@babylonjs/core 9.2.2 → 9.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Engines/abstractEngine.js +2 -2
- package/Engines/abstractEngine.js.map +1 -1
- package/Engines/engine.d.ts +49 -1118
- package/FlowGraph/flowGraph.d.ts +11 -0
- package/FlowGraph/flowGraph.js +20 -0
- package/FlowGraph/flowGraph.js.map +1 -1
- package/FlowGraph/flowGraphContext.d.ts +30 -0
- package/FlowGraph/flowGraphContext.js +42 -0
- package/FlowGraph/flowGraphContext.js.map +1 -1
- package/FlowGraph/flowGraphParser.js +13 -0
- package/FlowGraph/flowGraphParser.js.map +1 -1
- package/FlowGraph/typeDefinitions.d.ts +16 -0
- package/FlowGraph/typeDefinitions.js.map +1 -1
- package/Layers/thinSelectionOutlineLayer.js +25 -1
- package/Layers/thinSelectionOutlineLayer.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.d.ts +18 -0
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.js +110 -1
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.js.map +1 -1
- package/Materials/Textures/baseTexture.d.ts +1 -0
- package/Materials/Textures/baseTexture.js +1 -0
- package/Materials/Textures/baseTexture.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.d.ts +5 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.js +14 -4
- package/Meshes/GaussianSplatting/gaussianSplattingMesh.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.d.ts +24 -0
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.js +128 -0
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.js.map +1 -1
- package/Misc/tools.js +1 -1
- package/Misc/tools.js.map +1 -1
- package/Particles/IParticleSystem.d.ts +7 -1
- package/Particles/IParticleSystem.js.map +1 -1
- package/Particles/baseParticleSystem.d.ts +18 -2
- package/Particles/baseParticleSystem.js +53 -11
- package/Particles/baseParticleSystem.js.map +1 -1
- package/Particles/computeShaderParticleSystem.js +16 -0
- package/Particles/computeShaderParticleSystem.js.map +1 -1
- package/Particles/gpuParticleSystem.d.ts +14 -72
- package/Particles/gpuParticleSystem.js +130 -106
- package/Particles/gpuParticleSystem.js.map +1 -1
- package/Particles/particleSystem.d.ts +0 -80
- package/Particles/particleSystem.functions.d.ts +16 -0
- package/Particles/particleSystem.functions.js +18 -0
- package/Particles/particleSystem.functions.js.map +1 -1
- package/Particles/particleSystem.js +0 -114
- package/Particles/particleSystem.js.map +1 -1
- package/Particles/webgl2ParticleSystem.js +12 -0
- package/Particles/webgl2ParticleSystem.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.js +17 -0
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.d.ts +10 -0
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js +146 -24
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js.map +1 -1
- package/Rendering/objectRenderer.d.ts +2 -0
- package/Rendering/objectRenderer.js +10 -0
- package/Rendering/objectRenderer.js.map +1 -1
- package/Shaders/ShadersInclude/gaussianSplatting.js +21 -1
- package/Shaders/ShadersInclude/gaussianSplatting.js.map +1 -1
- package/Shaders/gaussianSplattingVoxel.fragment.d.ts +5 -0
- package/Shaders/gaussianSplattingVoxel.fragment.js +27 -0
- package/Shaders/gaussianSplattingVoxel.fragment.js.map +1 -0
- package/Shaders/gaussianSplattingVoxel.vertex.d.ts +8 -0
- package/Shaders/gaussianSplattingVoxel.vertex.js +31 -0
- package/Shaders/gaussianSplattingVoxel.vertex.js.map +1 -0
- package/Shaders/gpuUpdateParticles.vertex.js +13 -0
- package/Shaders/gpuUpdateParticles.vertex.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/gaussianSplatting.js +21 -1
- package/ShadersWGSL/ShadersInclude/gaussianSplatting.js.map +1 -1
- package/ShadersWGSL/gaussianSplattingVoxel.fragment.d.ts +5 -0
- package/ShadersWGSL/gaussianSplattingVoxel.fragment.js +22 -0
- package/ShadersWGSL/gaussianSplattingVoxel.fragment.js.map +1 -0
- package/ShadersWGSL/gaussianSplattingVoxel.vertex.d.ts +8 -0
- package/ShadersWGSL/gaussianSplattingVoxel.vertex.js +42 -0
- package/ShadersWGSL/gaussianSplattingVoxel.vertex.js.map +1 -0
- package/ShadersWGSL/gpuUpdateParticles.compute.js +19 -0
- package/ShadersWGSL/gpuUpdateParticles.compute.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gpuUpdateParticles.vertex.js","sourceRoot":"","sources":["../../../../dev/core/src/Shaders/gpuUpdateParticles.vertex.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,MAAM,IAAI,GAAG,gCAAgC,CAAC;AAC9C,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsSZ,CAAC;AACJ,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;IAClC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAC5C,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gpuUpdateParticlesVertexShader\";\nconst shader = `#version 300 es\n#define PI 3.14159\nuniform float currentCount;uniform float timeDelta;uniform float stopFactor;uniform float emitIndex;uniform float emitCount;\n#ifndef LOCAL\nuniform mat4 emitterWM;\n#endif\nuniform vec2 lifeTime;uniform vec2 emitPower;uniform vec2 sizeRange;uniform vec4 scaleRange;\n#ifdef FLOWMAP\nuniform mat4 flowMapProjection;uniform float flowMapStrength;uniform sampler2D flowMapSampler;\n#endif\n#ifndef COLORGRADIENTS\nuniform vec4 color1;uniform vec4 color2;\n#endif\nuniform vec3 gravity;uniform sampler2D randomSampler;uniform sampler2D randomSampler2;uniform vec4 angleRange;\n#ifdef BOXEMITTER\nuniform vec3 direction1;uniform vec3 direction2;uniform vec3 minEmitBox;uniform vec3 maxEmitBox;\n#endif\n#ifdef POINTEMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#endif\n#ifdef HEMISPHERICEMITTER\nuniform float radius;uniform float radiusRange;uniform float directionRandomizer;\n#endif\n#ifdef SPHEREEMITTER\nuniform float radius;uniform float radiusRange;\n#ifdef DIRECTEDSPHEREEMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\n#ifdef CYLINDEREMITTER\nuniform float radius;uniform float height;uniform float radiusRange;\n#ifdef DIRECTEDCYLINDEREMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\n#ifdef CONEEMITTER\nuniform vec2 radius;uniform float coneAngle;uniform vec2 height;\n#ifdef DIRECTEDCONEEMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\nin vec3 position;\n#ifdef CUSTOMEMITTER\nin vec3 initialPosition;\n#endif\nin float age;in float life;in vec4 seed;in vec3 size;\n#ifndef COLORGRADIENTS\nin vec4 color;\n#endif\nin vec3 direction;\n#ifndef BILLBOARD\nin vec3 initialDirection;\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nin float angle;\n#else\nin vec2 angle;\n#endif\n#ifdef ANIMATESHEET\nin float cellIndex;\n#ifdef ANIMATESHEETRANDOMSTART\nin float cellStartOffset;\n#endif\n#endif\n#ifdef NOISE\nin vec3 noiseCoordinates1;in vec3 noiseCoordinates2;\n#endif\nout vec3 outPosition;\n#ifdef CUSTOMEMITTER\nout vec3 outInitialPosition;\n#endif\nout float outAge;out float outLife;out vec4 outSeed;out vec3 outSize;\n#ifndef COLORGRADIENTS\nout vec4 outColor;\n#endif\nout vec3 outDirection;\n#ifndef BILLBOARD\nout vec3 outInitialDirection;\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nout float outAngle;\n#else\nout vec2 outAngle;\n#endif\n#ifdef ANIMATESHEET\nout float outCellIndex;\n#ifdef ANIMATESHEETRANDOMSTART\nout float outCellStartOffset;\n#endif\n#endif\n#ifdef NOISE\nout vec3 outNoiseCoordinates1;out vec3 outNoiseCoordinates2;\n#endif\n#ifdef SIZEGRADIENTS\nuniform sampler2D sizeGradientSampler;\n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nuniform sampler2D angularSpeedGradientSampler;\n#endif \n#ifdef VELOCITYGRADIENTS\nuniform sampler2D velocityGradientSampler;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\nuniform sampler2D limitVelocityGradientSampler;uniform float limitVelocityDamping;\n#endif\n#ifdef DRAGGRADIENTS\nuniform sampler2D dragGradientSampler;\n#endif\n#ifdef NOISE\nuniform vec3 noiseStrength;uniform sampler2D noiseSampler;\n#endif\n#ifdef ANIMATESHEET\nuniform vec4 cellInfos;\n#endif\n#ifdef ATTRACTORS\nuniform int attractorCount;uniform vec4 attractorPositionAndStrength[MAX_ATTRACTORS];\n#endif\n#ifdef STARTSIZEGRADIENTS\nuniform float startSizeGradientFactor;\n#endif\n#ifdef LIFETIMEGRADIENTS\nuniform vec2 lifeTimeGradientRange;\n#endif\nvec3 getRandomVec3(float offset) {return texture(randomSampler2,vec2(float(gl_VertexID)*offset/currentCount,0)).rgb;}\nvec4 getRandomVec4(float offset) {return texture(randomSampler,vec2(float(gl_VertexID)*offset/currentCount,0));}\nvoid main() {float newAge=age+timeDelta;\n#ifdef EMITRATECTRL\nfloat particleIndex=float(gl_VertexID);float offsetFromEmitIndex=particleIndex-emitIndex;if (offsetFromEmitIndex<0.0) {offsetFromEmitIndex+=currentCount; }\nbool shouldEmit=offsetFromEmitIndex<emitCount && stopFactor != 0.;\n#else\nbool shouldEmit=newAge>=life && stopFactor != 0.;\n#endif\nif (shouldEmit) {vec3 newPosition;vec3 newDirection;vec4 randoms=getRandomVec4(seed.x);outLife=lifeTime.x+(lifeTime.y-lifeTime.x)*randoms.r;\n#ifdef LIFETIMEGRADIENTS\noutLife=lifeTimeGradientRange.x+(lifeTimeGradientRange.y-lifeTimeGradientRange.x)*randoms.r;\n#endif\n#ifdef EMITRATECTRL\noutAge=0.0;\n#else\noutAge=newAge-life;\n#endif\noutSeed=seed;\n#ifdef SIZEGRADIENTS \nvec2 sizeGradientRange=texture(sizeGradientSampler,vec2(0,0)).rg;outSize.x=sizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y;\n#else\noutSize.x=sizeRange.x+(sizeRange.y-sizeRange.x)*randoms.g;\n#endif\noutSize.y=scaleRange.x+(scaleRange.y-scaleRange.x)*randoms.b;outSize.z=scaleRange.z+(scaleRange.w-scaleRange.z)*randoms.a; \n#ifdef STARTSIZEGRADIENTS\noutSize.x*=startSizeGradientFactor;\n#endif\n#ifndef COLORGRADIENTS\noutColor=color1+(color2-color1)*randoms.b;\n#endif\n#ifndef ANGULARSPEEDGRADIENTS \noutAngle.y=angleRange.x+(angleRange.y-angleRange.x)*randoms.a;outAngle.x=angleRange.z+(angleRange.w-angleRange.z)*randoms.r;\n#else\noutAngle=angleRange.z+(angleRange.w-angleRange.z)*randoms.r;\n#endif \n#ifdef POINTEMITTER\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);newPosition=vec3(0,0,0);newDirection=direction1+(direction2-direction1)*randoms3;\n#elif defined(BOXEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);newPosition=minEmitBox+(maxEmitBox-minEmitBox)*randoms2;newDirection=direction1+(direction2-direction1)*randoms3; \n#elif defined(HEMISPHERICEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);float phi=2.0*PI*randoms2.x;float theta=acos(2.0*randoms2.y-1.0);float randX=cos(phi)*sin(theta);float randY=cos(theta);float randZ=sin(phi)*sin(theta);newPosition=(radius-(radius*radiusRange*randoms2.z))*vec3(randX,abs(randY),randZ);newDirection=newPosition+directionRandomizer*randoms3; \n#elif defined(SPHEREEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);float phi=2.0*PI*randoms2.x;float theta=acos(2.0*randoms2.y-1.0);float randX=cos(phi)*sin(theta);float randY=cos(theta);float randZ=sin(phi)*sin(theta);newPosition=(radius-(radius*radiusRange*randoms2.z))*vec3(randX,randY,randZ);\n#ifdef DIRECTEDSPHEREEMITTER\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#else\nnewDirection=normalize(newPosition+directionRandomizer*randoms3);\n#endif\n#elif defined(CYLINDEREMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);float yPos=(randoms2.x-0.5)*height;float angle=randoms2.y*PI*2.;float inverseRadiusRangeSquared=((1.-radiusRange)*(1.-radiusRange));float positionRadius=radius*sqrt(inverseRadiusRangeSquared+(randoms2.z*(1.-inverseRadiusRangeSquared)));float xPos=positionRadius*cos(angle);float zPos=positionRadius*sin(angle);newPosition=vec3(xPos,yPos,zPos);\n#ifdef DIRECTEDCYLINDEREMITTER\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#else\nangle=angle+((randoms3.x-0.5)*PI)*directionRandomizer;newDirection=vec3(cos(angle),(randoms3.y-0.5)*directionRandomizer,sin(angle));newDirection=normalize(newDirection);\n#endif\n#elif defined(CONEEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);float s=2.0*PI*randoms2.x;\n#ifdef CONEEMITTERSPAWNPOINT\nfloat h=0.0001;\n#else\nfloat h=randoms2.y*height.y;h=1.-h*h; \n#endif\nfloat lRadius=radius.x-radius.x*randoms2.z*radius.y;lRadius=lRadius*h;float randX=lRadius*sin(s);float randZ=lRadius*cos(s);float randY=h *height.x;newPosition=vec3(randX,randY,randZ); \nvec3 randoms3=getRandomVec3(seed.z);\n#ifdef DIRECTEDCONEEMITTER\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#else\nif (abs(cos(coneAngle))==1.0) {newDirection=vec3(0.,1.0,0.);} else {newDirection=normalize(newPosition+directionRandomizer*randoms3); }\n#endif\n#elif defined(CUSTOMEMITTER)\nnewPosition=initialPosition;outInitialPosition=initialPosition;\n#else \nnewPosition=vec3(0.,0.,0.);newDirection=2.0*(getRandomVec3(seed.w)-vec3(0.5,0.5,0.5));\n#endif\nfloat power=emitPower.x+(emitPower.y-emitPower.x)*randoms.a;\n#ifdef LOCAL\noutPosition=newPosition;\n#else\noutPosition=(emitterWM*vec4(newPosition,1.)).xyz;\n#endif\n#ifdef CUSTOMEMITTER\noutDirection=direction;\n#ifndef BILLBOARD \noutInitialDirection=direction;\n#endif\n#else\n#ifdef LOCAL\nvec3 initial=newDirection;\n#else \nvec3 initial=(emitterWM*vec4(newDirection,0.)).xyz;\n#endif\noutDirection=initial*power;\n#ifndef BILLBOARD \noutInitialDirection=initial;\n#endif\n#endif\n#ifdef ANIMATESHEET \noutCellIndex=cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\noutCellStartOffset=randoms.a*outLife;\n#endif \n#endif\n#ifdef NOISE\noutNoiseCoordinates1=noiseCoordinates1;outNoiseCoordinates2=noiseCoordinates2;\n#endif\n} else {float directionScale=timeDelta;outAge=newAge;float ageGradient=newAge/life;\n#ifdef VELOCITYGRADIENTS\nvec2 velocityGradientRange=texture(velocityGradientSampler,vec2(ageGradient,0)).rg;directionScale*=velocityGradientRange.x+(velocityGradientRange.y-velocityGradientRange.x)*seed.w;\n#endif\n#ifdef DRAGGRADIENTS\nvec2 dragGradientRange=texture(dragGradientSampler,vec2(ageGradient,0)).rg;directionScale*=1.0-(dragGradientRange.x+(dragGradientRange.y-dragGradientRange.x)*seed.x);\n#endif\n#if defined(CUSTOMEMITTER)\noutPosition=position+(direction-position)*ageGradient; \noutInitialPosition=initialPosition;\n#else\noutPosition=position+direction*directionScale;\n#endif\noutLife=life;outSeed=seed;\n#ifndef COLORGRADIENTS \noutColor=color;\n#endif\n#ifdef SIZEGRADIENTS\nvec2 sizeGradientRange=texture(sizeGradientSampler,vec2(ageGradient,0)).rg;outSize.x=sizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y;outSize.yz=size.yz;\n#else\noutSize=size;\n#endif \n#ifndef BILLBOARD \noutInitialDirection=initialDirection;\n#endif\n#ifdef CUSTOMEMITTER\noutDirection=direction;\n#else\nvec3 updatedDirection=direction+gravity*timeDelta;\n#ifdef FLOWMAP\nvec4 clipSpace=(flowMapProjection*vec4(position,1.));vec3 ndcSpace=clipSpace.xyz/clipSpace.w;vec2 flowMapUV=ndcSpace.xy*0.5+0.5;vec4 flowMapValue=texture(flowMapSampler,flowMapUV);vec3 flowMapDirection=(flowMapValue.xyz*2.0-1.0)*flowMapValue.w;updatedDirection+=flowMapDirection*timeDelta*flowMapStrength;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\nvec2 limitVelocityRange=texture(limitVelocityGradientSampler,vec2(ageGradient,0)).rg;float limitVelocity=limitVelocityRange.x+(limitVelocityRange.y-limitVelocityRange.x)*seed.y;float currentVelocity=length(updatedDirection);if (currentVelocity>limitVelocity) {updatedDirection=updatedDirection*limitVelocityDamping;}\n#endif\n#ifdef ATTRACTORS\n{for (int i=0; i<attractorCount; i++) {vec3 toAttractor=attractorPositionAndStrength[i].xyz-outPosition;float distSq=dot(toAttractor,toAttractor)+1.0;updatedDirection+=(attractorPositionAndStrength[i].w/distSq)*normalize(toAttractor)*timeDelta;}}\n#endif\noutDirection=updatedDirection;\n#ifdef NOISE\nfloat fetchedR=texture(noiseSampler,vec2(noiseCoordinates1.x,noiseCoordinates1.y)*vec2(0.5)+vec2(0.5)).r;float fetchedG=texture(noiseSampler,vec2(noiseCoordinates1.z,noiseCoordinates2.x)*vec2(0.5)+vec2(0.5)).r;float fetchedB=texture(noiseSampler,vec2(noiseCoordinates2.y,noiseCoordinates2.z)*vec2(0.5)+vec2(0.5)).r;vec3 force=vec3(2.*fetchedR-1.,2.*fetchedG-1.,2.*fetchedB-1.)*noiseStrength;outDirection=outDirection+force*timeDelta;outNoiseCoordinates1=noiseCoordinates1;outNoiseCoordinates2=noiseCoordinates2;\n#endif \n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nvec2 angularSpeedRange=texture(angularSpeedGradientSampler,vec2(ageGradient,0)).rg;float angularSpeed=angularSpeedRange.x+(angularSpeedRange.y-angularSpeedRange.x)*seed.z;outAngle=angle+angularSpeed*timeDelta;\n#else\noutAngle=vec2(angle.x+angle.y*timeDelta,angle.y);\n#endif\n#ifdef ANIMATESHEET \nfloat offsetAge=outAge;float dist=cellInfos.y-cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\noutCellStartOffset=cellStartOffset;offsetAge+=cellStartOffset;\n#else\nfloat cellStartOffset=0.;\n#endif \nfloat ratio=0.;if (cellInfos.w==1.0) {ratio=clamp(mod(cellStartOffset+cellInfos.z*offsetAge,life)/life,0.,1.0);}\nelse {ratio=clamp(cellStartOffset+cellInfos.z*offsetAge/life,0.,1.0);}\noutCellIndex=float(int(cellInfos.x+ratio*dist));\n#endif\n}}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const gpuUpdateParticlesVertexShader = { name, shader };\n"]}
|
|
1
|
+
{"version":3,"file":"gpuUpdateParticles.vertex.js","sourceRoot":"","sources":["../../../../dev/core/src/Shaders/gpuUpdateParticles.vertex.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,MAAM,IAAI,GAAG,gCAAgC,CAAC;AAC9C,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmTZ,CAAC;AACJ,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;IAClC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAC5C,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gpuUpdateParticlesVertexShader\";\nconst shader = `#version 300 es\n#define PI 3.14159\nuniform float currentCount;uniform float timeDelta;uniform float stopFactor;uniform float emitIndex;uniform float emitCount;\n#ifndef LOCAL\nuniform mat4 emitterWM;\n#endif\nuniform vec2 lifeTime;uniform vec2 emitPower;uniform vec2 sizeRange;uniform vec4 scaleRange;\n#ifdef FLOWMAP\nuniform mat4 flowMapProjection;uniform float flowMapStrength;uniform sampler2D flowMapSampler;\n#endif\n#ifndef COLORGRADIENTS\nuniform vec4 color1;uniform vec4 color2;\n#endif\nuniform vec3 gravity;uniform sampler2D randomSampler;uniform sampler2D randomSampler2;uniform vec4 angleRange;\n#ifdef BOXEMITTER\nuniform vec3 direction1;uniform vec3 direction2;uniform vec3 minEmitBox;uniform vec3 maxEmitBox;\n#endif\n#ifdef POINTEMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#endif\n#ifdef HEMISPHERICEMITTER\nuniform float radius;uniform float radiusRange;uniform float directionRandomizer;\n#endif\n#ifdef SPHEREEMITTER\nuniform float radius;uniform float radiusRange;\n#ifdef DIRECTEDSPHEREEMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\n#ifdef CYLINDEREMITTER\nuniform float radius;uniform float height;uniform float radiusRange;\n#ifdef DIRECTEDCYLINDEREMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\n#ifdef CONEEMITTER\nuniform vec2 radius;uniform float coneAngle;uniform vec2 height;\n#ifdef DIRECTEDCONEEMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\nin vec3 position;\n#ifdef CUSTOMEMITTER\nin vec3 initialPosition;\n#endif\nin float age;in float life;in vec4 seed;in vec3 size;\n#ifndef COLORGRADIENTS\nin vec4 color;\n#endif\nin vec3 direction;\n#ifndef BILLBOARD\nin vec3 initialDirection;\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nin float angle;\n#else\nin vec2 angle;\n#endif\n#ifdef ANIMATESHEET\nin float cellIndex;\n#ifdef ANIMATESHEETRANDOMSTART\nin float cellStartOffset;\n#endif\n#endif\n#ifdef NOISE\nin vec3 noiseCoordinates1;in vec3 noiseCoordinates2;\n#endif\nout vec3 outPosition;\n#ifdef CUSTOMEMITTER\nout vec3 outInitialPosition;\n#endif\nout float outAge;out float outLife;out vec4 outSeed;out vec3 outSize;\n#ifndef COLORGRADIENTS\nout vec4 outColor;\n#endif\nout vec3 outDirection;\n#ifndef BILLBOARD\nout vec3 outInitialDirection;\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nout float outAngle;\n#else\nout vec2 outAngle;\n#endif\n#ifdef ANIMATESHEET\nout float outCellIndex;\n#ifdef ANIMATESHEETRANDOMSTART\nout float outCellStartOffset;\n#endif\n#endif\n#ifdef NOISE\nout vec3 outNoiseCoordinates1;out vec3 outNoiseCoordinates2;\n#endif\n#ifdef SIZEGRADIENTS\nuniform sampler2D sizeGradientSampler;\n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nuniform sampler2D angularSpeedGradientSampler;\n#endif \n#ifdef VELOCITYGRADIENTS\nuniform sampler2D velocityGradientSampler;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\nuniform sampler2D limitVelocityGradientSampler;uniform float limitVelocityDamping;\n#endif\n#ifdef DRAGGRADIENTS\nuniform sampler2D dragGradientSampler;\n#endif\n#ifdef NOISE\nuniform vec3 noiseStrength;uniform sampler2D noiseSampler;\n#endif\n#ifdef ANIMATESHEET\nuniform vec4 cellInfos;\n#endif\n#ifdef ATTRACTORS\nuniform int attractorCount;uniform vec4 attractorPositionAndStrength[MAX_ATTRACTORS];\n#endif\n#ifdef STARTSIZEGRADIENTS\nuniform float startSizeGradientFactor;\n#endif\n#ifdef LIFETIMEGRADIENTS\nuniform vec2 lifeTimeGradientRange;\n#endif\n#ifdef MESHEMITTER\nuniform sampler2D meshPositionSampler;uniform int meshTriangleCount;uniform int meshTextureWidth;uniform vec3 direction1;uniform vec3 direction2;\n#ifdef MESHNORMALS\nuniform sampler2D meshNormalSampler;\n#endif\n#endif\nvec3 getRandomVec3(float offset) {return texture(randomSampler2,vec2(float(gl_VertexID)*offset/currentCount,0)).rgb;}\nvec4 getRandomVec4(float offset) {return texture(randomSampler,vec2(float(gl_VertexID)*offset/currentCount,0));}\nvoid main() {float newAge=age+timeDelta;\n#ifdef EMITRATECTRL\nfloat particleIndex=float(gl_VertexID);float offsetFromEmitIndex=particleIndex-emitIndex;if (offsetFromEmitIndex<0.0) {offsetFromEmitIndex+=currentCount; }\nbool shouldEmit=offsetFromEmitIndex<emitCount && stopFactor != 0.;\n#else\nbool shouldEmit=newAge>=life && stopFactor != 0.;\n#endif\nif (shouldEmit) {vec3 newPosition;vec3 newDirection;vec4 randoms=getRandomVec4(seed.x);outLife=lifeTime.x+(lifeTime.y-lifeTime.x)*randoms.r;\n#ifdef LIFETIMEGRADIENTS\noutLife=lifeTimeGradientRange.x+(lifeTimeGradientRange.y-lifeTimeGradientRange.x)*randoms.r;\n#endif\n#ifdef EMITRATECTRL\noutAge=0.0;\n#else\noutAge=newAge-life;\n#endif\noutSeed=seed;\n#ifdef SIZEGRADIENTS \nvec2 sizeGradientRange=texture(sizeGradientSampler,vec2(0,0)).rg;outSize.x=sizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y;\n#else\noutSize.x=sizeRange.x+(sizeRange.y-sizeRange.x)*randoms.g;\n#endif\noutSize.y=scaleRange.x+(scaleRange.y-scaleRange.x)*randoms.b;outSize.z=scaleRange.z+(scaleRange.w-scaleRange.z)*randoms.a; \n#ifdef STARTSIZEGRADIENTS\noutSize.x*=startSizeGradientFactor;\n#endif\n#ifndef COLORGRADIENTS\noutColor=color1+(color2-color1)*randoms.b;\n#endif\n#ifndef ANGULARSPEEDGRADIENTS \noutAngle.y=angleRange.x+(angleRange.y-angleRange.x)*randoms.a;outAngle.x=angleRange.z+(angleRange.w-angleRange.z)*randoms.r;\n#else\noutAngle=angleRange.z+(angleRange.w-angleRange.z)*randoms.r;\n#endif \n#ifdef POINTEMITTER\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);newPosition=vec3(0,0,0);newDirection=direction1+(direction2-direction1)*randoms3;\n#elif defined(BOXEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);newPosition=minEmitBox+(maxEmitBox-minEmitBox)*randoms2;newDirection=direction1+(direction2-direction1)*randoms3; \n#elif defined(HEMISPHERICEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);float phi=2.0*PI*randoms2.x;float theta=acos(2.0*randoms2.y-1.0);float randX=cos(phi)*sin(theta);float randY=cos(theta);float randZ=sin(phi)*sin(theta);newPosition=(radius-(radius*radiusRange*randoms2.z))*vec3(randX,abs(randY),randZ);newDirection=newPosition+directionRandomizer*randoms3; \n#elif defined(SPHEREEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);float phi=2.0*PI*randoms2.x;float theta=acos(2.0*randoms2.y-1.0);float randX=cos(phi)*sin(theta);float randY=cos(theta);float randZ=sin(phi)*sin(theta);newPosition=(radius-(radius*radiusRange*randoms2.z))*vec3(randX,randY,randZ);\n#ifdef DIRECTEDSPHEREEMITTER\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#else\nnewDirection=normalize(newPosition+directionRandomizer*randoms3);\n#endif\n#elif defined(CYLINDEREMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);float yPos=(randoms2.x-0.5)*height;float angle=randoms2.y*PI*2.;float inverseRadiusRangeSquared=((1.-radiusRange)*(1.-radiusRange));float positionRadius=radius*sqrt(inverseRadiusRangeSquared+(randoms2.z*(1.-inverseRadiusRangeSquared)));float xPos=positionRadius*cos(angle);float zPos=positionRadius*sin(angle);newPosition=vec3(xPos,yPos,zPos);\n#ifdef DIRECTEDCYLINDEREMITTER\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#else\nangle=angle+((randoms3.x-0.5)*PI)*directionRandomizer;newDirection=vec3(cos(angle),(randoms3.y-0.5)*directionRandomizer,sin(angle));newDirection=normalize(newDirection);\n#endif\n#elif defined(CONEEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);float s=2.0*PI*randoms2.x;\n#ifdef CONEEMITTERSPAWNPOINT\nfloat h=0.0001;\n#else\nfloat h=randoms2.y*height.y;h=1.-h*h; \n#endif\nfloat lRadius=radius.x-radius.x*randoms2.z*radius.y;lRadius=lRadius*h;float randX=lRadius*sin(s);float randZ=lRadius*cos(s);float randY=h *height.x;newPosition=vec3(randX,randY,randZ); \nvec3 randoms3=getRandomVec3(seed.z);\n#ifdef DIRECTEDCONEEMITTER\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#else\nif (abs(cos(coneAngle))==1.0) {newDirection=vec3(0.,1.0,0.);} else {newDirection=normalize(newPosition+directionRandomizer*randoms3); }\n#endif\n#elif defined(MESHEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);int triIdx=int(floor(randoms2.x*float(meshTriangleCount)));triIdx=min(triIdx,meshTriangleCount-1);int baseTexel=triIdx*3;int t0=baseTexel;int t1=baseTexel+1;int t2=baseTexel+2;vec3 v0=texelFetch(meshPositionSampler,ivec2(t0 % meshTextureWidth,t0/meshTextureWidth),0).xyz;vec3 v1=texelFetch(meshPositionSampler,ivec2(t1 % meshTextureWidth,t1/meshTextureWidth),0).xyz;vec3 v2=texelFetch(meshPositionSampler,ivec2(t2 % meshTextureWidth,t2/meshTextureWidth),0).xyz;float bu=randoms2.y;float bv=randoms2.z*(1.0-bu);float bw=1.0-bu-bv;newPosition=bu*v0+bv*v1+bw*v2;\n#ifdef MESHNORMALS\nvec3 n0=texelFetch(meshNormalSampler,ivec2(t0 % meshTextureWidth,t0/meshTextureWidth),0).xyz;vec3 n1=texelFetch(meshNormalSampler,ivec2(t1 % meshTextureWidth,t1/meshTextureWidth),0).xyz;vec3 n2=texelFetch(meshNormalSampler,ivec2(t2 % meshTextureWidth,t2/meshTextureWidth),0).xyz;newDirection=normalize(bu*n0+bv*n1+bw*n2);\n#else\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#endif\n#elif defined(CUSTOMEMITTER)\nnewPosition=initialPosition;outInitialPosition=initialPosition;\n#else \nnewPosition=vec3(0.,0.,0.);newDirection=2.0*(getRandomVec3(seed.w)-vec3(0.5,0.5,0.5));\n#endif\nfloat power=emitPower.x+(emitPower.y-emitPower.x)*randoms.a;\n#ifdef LOCAL\noutPosition=newPosition;\n#else\noutPosition=(emitterWM*vec4(newPosition,1.)).xyz;\n#endif\n#ifdef CUSTOMEMITTER\noutDirection=direction;\n#ifndef BILLBOARD \noutInitialDirection=direction;\n#endif\n#else\n#ifdef LOCAL\nvec3 initial=newDirection;\n#else \nvec3 initial=(emitterWM*vec4(newDirection,0.)).xyz;\n#endif\noutDirection=initial*power;\n#ifndef BILLBOARD \noutInitialDirection=initial;\n#endif\n#endif\n#ifdef ANIMATESHEET \noutCellIndex=cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\noutCellStartOffset=randoms.a*outLife;\n#endif \n#endif\n#ifdef NOISE\noutNoiseCoordinates1=noiseCoordinates1;outNoiseCoordinates2=noiseCoordinates2;\n#endif\n} else {float directionScale=timeDelta;outAge=newAge;float ageGradient=newAge/life;\n#ifdef VELOCITYGRADIENTS\nvec2 velocityGradientRange=texture(velocityGradientSampler,vec2(ageGradient,0)).rg;directionScale*=velocityGradientRange.x+(velocityGradientRange.y-velocityGradientRange.x)*seed.w;\n#endif\n#ifdef DRAGGRADIENTS\nvec2 dragGradientRange=texture(dragGradientSampler,vec2(ageGradient,0)).rg;directionScale*=1.0-(dragGradientRange.x+(dragGradientRange.y-dragGradientRange.x)*seed.x);\n#endif\n#if defined(CUSTOMEMITTER)\noutPosition=position+(direction-position)*ageGradient; \noutInitialPosition=initialPosition;\n#else\noutPosition=position+direction*directionScale;\n#endif\noutLife=life;outSeed=seed;\n#ifndef COLORGRADIENTS \noutColor=color;\n#endif\n#ifdef SIZEGRADIENTS\nvec2 sizeGradientRange=texture(sizeGradientSampler,vec2(ageGradient,0)).rg;outSize.x=sizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y;outSize.yz=size.yz;\n#else\noutSize=size;\n#endif \n#ifndef BILLBOARD \noutInitialDirection=initialDirection;\n#endif\n#ifdef CUSTOMEMITTER\noutDirection=direction;\n#else\nvec3 updatedDirection=direction+gravity*timeDelta;\n#ifdef FLOWMAP\nvec4 clipSpace=(flowMapProjection*vec4(position,1.));vec3 ndcSpace=clipSpace.xyz/clipSpace.w;vec2 flowMapUV=ndcSpace.xy*0.5+0.5;vec4 flowMapValue=texture(flowMapSampler,flowMapUV);vec3 flowMapDirection=(flowMapValue.xyz*2.0-1.0)*flowMapValue.w;updatedDirection+=flowMapDirection*timeDelta*flowMapStrength;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\nvec2 limitVelocityRange=texture(limitVelocityGradientSampler,vec2(ageGradient,0)).rg;float limitVelocity=limitVelocityRange.x+(limitVelocityRange.y-limitVelocityRange.x)*seed.y;float currentVelocity=length(updatedDirection);if (currentVelocity>limitVelocity) {updatedDirection=updatedDirection*limitVelocityDamping;}\n#endif\n#ifdef ATTRACTORS\n{for (int i=0; i<attractorCount; i++) {vec3 toAttractor=attractorPositionAndStrength[i].xyz-outPosition;float distSq=dot(toAttractor,toAttractor)+1.0;updatedDirection+=(attractorPositionAndStrength[i].w/distSq)*normalize(toAttractor)*timeDelta;}}\n#endif\noutDirection=updatedDirection;\n#ifdef NOISE\nfloat fetchedR=texture(noiseSampler,vec2(noiseCoordinates1.x,noiseCoordinates1.y)*vec2(0.5)+vec2(0.5)).r;float fetchedG=texture(noiseSampler,vec2(noiseCoordinates1.z,noiseCoordinates2.x)*vec2(0.5)+vec2(0.5)).r;float fetchedB=texture(noiseSampler,vec2(noiseCoordinates2.y,noiseCoordinates2.z)*vec2(0.5)+vec2(0.5)).r;vec3 force=vec3(2.*fetchedR-1.,2.*fetchedG-1.,2.*fetchedB-1.)*noiseStrength;outDirection=outDirection+force*timeDelta;outNoiseCoordinates1=noiseCoordinates1;outNoiseCoordinates2=noiseCoordinates2;\n#endif \n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nvec2 angularSpeedRange=texture(angularSpeedGradientSampler,vec2(ageGradient,0)).rg;float angularSpeed=angularSpeedRange.x+(angularSpeedRange.y-angularSpeedRange.x)*seed.z;outAngle=angle+angularSpeed*timeDelta;\n#else\noutAngle=vec2(angle.x+angle.y*timeDelta,angle.y);\n#endif\n#ifdef ANIMATESHEET \nfloat offsetAge=outAge;float dist=cellInfos.y-cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\noutCellStartOffset=cellStartOffset;offsetAge+=cellStartOffset;\n#else\nfloat cellStartOffset=0.;\n#endif \nfloat ratio=0.;if (cellInfos.w==1.0) {ratio=clamp(mod(cellStartOffset+cellInfos.z*offsetAge,life)/life,0.,1.0);}\nelse {ratio=clamp(cellStartOffset+cellInfos.z*offsetAge/life,0.,1.0);}\noutCellIndex=float(int(cellInfos.x+ratio*dist));\n#endif\n}}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const gpuUpdateParticlesVertexShader = { name, shader };\n"]}
|
|
@@ -22,6 +22,11 @@ sh4: vec4<u32>,
|
|
|
22
22
|
#if IS_COMPOUND
|
|
23
23
|
partIndex: u32,
|
|
24
24
|
#endif
|
|
25
|
+
#if defined(IS_FOR_VOXELIZATION)
|
|
26
|
+
rotationA: vec4f,
|
|
27
|
+
rotationB: vec4f,
|
|
28
|
+
rotationScale: vec4f,
|
|
29
|
+
#endif
|
|
25
30
|
};fn getSplatIndex(localIndex: i32,splatIndex0: vec4f,splatIndex1: vec4f,splatIndex2: vec4f,splatIndex3: vec4f)->f32 {var splatIndex: f32;switch (localIndex)
|
|
26
31
|
{case 0:
|
|
27
32
|
{splatIndex=splatIndex0.x;break;}
|
|
@@ -56,7 +61,10 @@ case 14:
|
|
|
56
61
|
default:
|
|
57
62
|
{splatIndex=splatIndex3.w;break;}}
|
|
58
63
|
return splatIndex;}
|
|
59
|
-
fn readSplat(splatIndex: f32,dataTextureSize: vec2f)->Splat {var splat: Splat;let splatUV=getDataUV(splatIndex,dataTextureSize);let splatUVi32=vec2<i32>(i32(splatUV.x),i32(splatUV.y));splat.center=textureLoad(centersTexture,splatUVi32,0);splat.color=textureLoad(colorsTexture,splatUVi32,0);
|
|
64
|
+
fn readSplat(splatIndex: f32,dataTextureSize: vec2f)->Splat {var splat: Splat;let splatUV=getDataUV(splatIndex,dataTextureSize);let splatUVi32=vec2<i32>(i32(splatUV.x),i32(splatUV.y));splat.center=textureLoad(centersTexture,splatUVi32,0);splat.color=textureLoad(colorsTexture,splatUVi32,0);
|
|
65
|
+
#if !defined(IS_FOR_VOXELIZATION)
|
|
66
|
+
splat.covA=textureLoad(covariancesATexture,splatUVi32,0)*splat.center.w;splat.covB=textureLoad(covariancesBTexture,splatUVi32,0)*splat.center.w;
|
|
67
|
+
#endif
|
|
60
68
|
#if SH_DEGREE>0
|
|
61
69
|
splat.sh0=textureLoad(shTexture0,splatUVi32,0);
|
|
62
70
|
#endif
|
|
@@ -72,6 +80,9 @@ splat.sh3=textureLoad(shTexture3,splatUVi32,0);splat.sh4=textureLoad(shTexture4,
|
|
|
72
80
|
#if IS_COMPOUND
|
|
73
81
|
splat.partIndex=u32(textureLoad(partIndicesTexture,splatUVi32,0).r*255.0+0.5);
|
|
74
82
|
#endif
|
|
83
|
+
#if defined(IS_FOR_VOXELIZATION)
|
|
84
|
+
splat.rotationA=textureLoad(rotationsATexture,splatUVi32,0);splat.rotationB=textureLoad(rotationsBTexture,splatUVi32,0);splat.rotationScale=textureLoad(rotationScaleTexture,splatUVi32,0);
|
|
85
|
+
#endif
|
|
75
86
|
return splat;}
|
|
76
87
|
fn computeColorFromSHDegree(dir: vec3f,sh: array<vec3<f32>,25>)->vec3f
|
|
77
88
|
{let SH_C0: f32=0.28209479;let SH_C1: f32=0.48860251;var SH_C2: array<f32,5>=array<f32,5>(
|
|
@@ -200,6 +211,15 @@ pos2d.w
|
|
|
200
211
|
#if IS_COMPOUND
|
|
201
212
|
fn getPartWorld(partIndex: u32)->mat4x4<f32> {return uniforms.partWorld[partIndex];}
|
|
202
213
|
#endif
|
|
214
|
+
#if defined(IS_FOR_VOXELIZATION)
|
|
215
|
+
fn computeVoxelSplatWorldPos(rotationA: vec4f,rotationB: vec4f,rotationScale: vec4f,center: vec3f,splatWorld: mat4x4f,viewMatrix: mat4x4f,invWorldScale: mat4x4f,quadPos: vec2f)->vec4f {let splatRotation=mat3x3f(
|
|
216
|
+
rotationA.xyz,
|
|
217
|
+
vec3f(rotationA.w,rotationB.x,rotationB.y),
|
|
218
|
+
vec3f(rotationB.z,rotationB.w,rotationScale.x)
|
|
219
|
+
);let splatScale=rotationScale.yzw;let view3x3=mat3x3f(viewMatrix[0].xyz,viewMatrix[1].xyz,viewMatrix[2].xyz);let invWorldScale3x3=mat3x3f(invWorldScale[0].xyz,invWorldScale[1].xyz,invWorldScale[2].xyz);let splatWorld3x3=mat3x3f(splatWorld[0].xyz,splatWorld[1].xyz,splatWorld[2].xyz);let rotToView=view3x3*invWorldScale3x3*splatWorld3x3*splatRotation;let axisLengthInViewZ=abs(vec3f(rotToView[0][2],rotToView[1][2],rotToView[2][2]));let gaussianSplatCutoffStddev: f32=0.7071067812;
|
|
220
|
+
var offsetSplatSpace: vec3f;if (axisLengthInViewZ.x>axisLengthInViewZ.y && axisLengthInViewZ.x>axisLengthInViewZ.z) {offsetSplatSpace=vec3f(0.0,quadPos.x,quadPos.y)*splatScale*gaussianSplatCutoffStddev;} else if (axisLengthInViewZ.y>axisLengthInViewZ.z) {offsetSplatSpace=vec3f(quadPos.x,0.0,quadPos.y)*splatScale*gaussianSplatCutoffStddev;} else {offsetSplatSpace=vec3f(quadPos.x,quadPos.y,0.0)*splatScale*gaussianSplatCutoffStddev;}
|
|
221
|
+
let vertexObjectSpace=center+splatRotation*offsetSplatSpace;return splatWorld*vec4f(vertexObjectSpace,1.0);}
|
|
222
|
+
#endif
|
|
203
223
|
`;
|
|
204
224
|
// Sideeffect
|
|
205
225
|
if (!ShaderStore.IncludesShadersStoreWGSL[name]) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gaussianSplatting.js","sourceRoot":"","sources":["../../../../../dev/core/src/ShadersWGSL/ShadersInclude/gaussianSplatting.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,IAAI,GAAG,mBAAmB,CAAC;AACjC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuMd,CAAC;AACF,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC;IAC9C,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AACxD,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\n\nconst name = \"gaussianSplatting\";\nconst shader = `fn getDataUV(index: f32,dataTextureSize: vec2f)->vec2<f32> {let y: f32=floor(index/dataTextureSize.x);let x: f32=index-y*dataTextureSize.x;return vec2f((x+0.5),(y+0.5));}\nstruct Splat {center: vec4f,\ncolor: vec4f,\ncovA: vec4f,\ncovB: vec4f,\n#if SH_DEGREE>0\nsh0: vec4<u32>,\n#endif\n#if SH_DEGREE>1\nsh1: vec4<u32>,\n#endif\n#if SH_DEGREE>2\nsh2: vec4<u32>,\n#endif\n#if SH_DEGREE>3\nsh3: vec4<u32>,\nsh4: vec4<u32>,\n#endif\n#if IS_COMPOUND\npartIndex: u32,\n#endif\n};fn getSplatIndex(localIndex: i32,splatIndex0: vec4f,splatIndex1: vec4f,splatIndex2: vec4f,splatIndex3: vec4f)->f32 {var splatIndex: f32;switch (localIndex)\n{case 0:\n{splatIndex=splatIndex0.x;break;}\ncase 1:\n{splatIndex=splatIndex0.y;break;}\ncase 2:\n{splatIndex=splatIndex0.z;break;}\ncase 3:\n{splatIndex=splatIndex0.w;break;}\ncase 4:\n{splatIndex=splatIndex1.x;break;}\ncase 5:\n{splatIndex=splatIndex1.y;break;}\ncase 6:\n{splatIndex=splatIndex1.z;break;}\ncase 7:\n{splatIndex=splatIndex1.w;break;}\ncase 8:\n{splatIndex=splatIndex2.x;break;}\ncase 9:\n{splatIndex=splatIndex2.y;break;}\ncase 10:\n{splatIndex=splatIndex2.z;break;}\ncase 11:\n{splatIndex=splatIndex2.w;break;}\ncase 12:\n{splatIndex=splatIndex3.x;break;}\ncase 13:\n{splatIndex=splatIndex3.y;break;}\ncase 14:\n{splatIndex=splatIndex3.z;break;}\ndefault:\n{splatIndex=splatIndex3.w;break;}}\nreturn splatIndex;}\nfn readSplat(splatIndex: f32,dataTextureSize: vec2f)->Splat {var splat: Splat;let splatUV=getDataUV(splatIndex,dataTextureSize);let splatUVi32=vec2<i32>(i32(splatUV.x),i32(splatUV.y));splat.center=textureLoad(centersTexture,splatUVi32,0);splat.color=textureLoad(colorsTexture,splatUVi32,0);splat.covA=textureLoad(covariancesATexture,splatUVi32,0)*splat.center.w;splat.covB=textureLoad(covariancesBTexture,splatUVi32,0)*splat.center.w;\n#if SH_DEGREE>0\nsplat.sh0=textureLoad(shTexture0,splatUVi32,0);\n#endif\n#if SH_DEGREE>1\nsplat.sh1=textureLoad(shTexture1,splatUVi32,0);\n#endif\n#if SH_DEGREE>2\nsplat.sh2=textureLoad(shTexture2,splatUVi32,0);\n#endif\n#if SH_DEGREE>3\nsplat.sh3=textureLoad(shTexture3,splatUVi32,0);splat.sh4=textureLoad(shTexture4,splatUVi32,0);\n#endif\n#if IS_COMPOUND\nsplat.partIndex=u32(textureLoad(partIndicesTexture,splatUVi32,0).r*255.0+0.5);\n#endif\nreturn splat;}\nfn computeColorFromSHDegree(dir: vec3f,sh: array<vec3<f32>,25>)->vec3f\n{let SH_C0: f32=0.28209479;let SH_C1: f32=0.48860251;var SH_C2: array<f32,5>=array<f32,5>(\n1.092548430,\n-1.09254843,\n0.315391565,\n-1.09254843,\n0.546274215\n);var SH_C3: array<f32,7>=array<f32,7>(\n-0.59004358,\n2.890611442,\n-0.45704579,\n0.373176332,\n-0.45704579,\n1.445305721,\n-0.59004358\n);var SH_C4: array<f32,9>=array<f32,9>(\n2.5033429418,\n-1.7701307698,\n0.9461746958,\n-0.6690465436,\n0.1057855469,\n-0.6690465436,\n0.4730873479,\n-1.7701307698,\n0.6258357354\n);var result: vec3f=/*SH_C0**/sh[0];\n#if SH_DEGREE>0\nlet x: f32=dir.x;let y: f32=dir.y;let z: f32=dir.z;result+=-SH_C1*y*sh[1]+SH_C1*z*sh[2]-SH_C1*x*sh[3];\n#if SH_DEGREE>1\nlet xx: f32=x*x;let yy: f32=y*y;let zz: f32=z*z;let xy: f32=x*y;let yz: f32=y*z;let xz: f32=x*z;result +=\nSH_C2[0]*xy*sh[4] +\nSH_C2[1]*yz*sh[5] +\nSH_C2[2]*(2.0f*zz-xx-yy)*sh[6] +\nSH_C2[3]*xz*sh[7] +\nSH_C2[4]*(xx-yy)*sh[8];\n#if SH_DEGREE>2\nresult +=\nSH_C3[0]*y*(3.0f*xx-yy)*sh[9] +\nSH_C3[1]*xy*z*sh[10] +\nSH_C3[2]*y*(4.0f*zz-xx-yy)*sh[11] +\nSH_C3[3]*z*(2.0f*zz-3.0f*xx-3.0f*yy)*sh[12] +\nSH_C3[4]*x*(4.0f*zz-xx-yy)*sh[13] +\nSH_C3[5]*z*(xx-yy)*sh[14] +\nSH_C3[6]*x*(xx-3.0f*yy)*sh[15];\n#if SH_DEGREE>3\nresult +=\nSH_C4[0]*x*y*(xx-yy)*sh[16] +\nSH_C4[1]*y*z*(3.0f*xx-yy)*sh[17] +\nSH_C4[2]*x*y*(7.0f*zz-1.0f)*sh[18] +\nSH_C4[3]*y*z*(7.0f*zz-3.0f)*sh[19] +\nSH_C4[4]*(zz*(35.0f*zz-30.0f)+3.0f)*sh[20] +\nSH_C4[5]*x*z*(7.0f*zz-3.0f)*sh[21] +\nSH_C4[6]*(xx-yy)*(7.0f*zz-1.0f)*sh[22] +\nSH_C4[7]*x*z*(xx-3.0f*yy)*sh[23] +\nSH_C4[8]*(xx*(xx-3.0f*yy)-yy*(3.0f*xx-yy))*sh[24];\n#endif\n#endif\n#endif\n#endif\nreturn result;}\nfn decompose(value: u32)->vec4f\n{let components : vec4f=vec4f(\nf32((value ) & 255u),\nf32((value>>u32( 8)) & 255u),\nf32((value>>u32(16)) & 255u),\nf32((value>>u32(24)) & 255u));return components*vec4f(2./255.)-vec4f(1.);}\nfn computeSH(splat: Splat,dir: vec3f)->vec3f\n{var sh: array<vec3<f32>,25>;sh[0]=vec3f(0.,0.,0.);\n#if SH_DEGREE>0\nlet sh00: vec4f=decompose(splat.sh0.x);let sh01: vec4f=decompose(splat.sh0.y);let sh02: vec4f=decompose(splat.sh0.z);sh[1]=vec3f(sh00.x,sh00.y,sh00.z);sh[2]=vec3f(sh00.w,sh01.x,sh01.y);sh[3]=vec3f(sh01.z,sh01.w,sh02.x);\n#endif\n#if SH_DEGREE>1\nlet sh03: vec4f=decompose(splat.sh0.w);let sh04: vec4f=decompose(splat.sh1.x);let sh05: vec4f=decompose(splat.sh1.y);sh[4]=vec3f(sh02.y,sh02.z,sh02.w);sh[5]=vec3f(sh03.x,sh03.y,sh03.z);sh[6]=vec3f(sh03.w,sh04.x,sh04.y);sh[7]=vec3f(sh04.z,sh04.w,sh05.x);sh[8]=vec3f(sh05.y,sh05.z,sh05.w);\n#endif\n#if SH_DEGREE>2\nlet sh06: vec4f=decompose(splat.sh1.z);let sh07: vec4f=decompose(splat.sh1.w);let sh08: vec4f=decompose(splat.sh2.x);let sh09: vec4f=decompose(splat.sh2.y);let sh10: vec4f=decompose(splat.sh2.z);let sh11: vec4f=decompose(splat.sh2.w);sh[9]=vec3f(sh06.x,sh06.y,sh06.z);sh[10]=vec3f(sh06.w,sh07.x,sh07.y);sh[11]=vec3f(sh07.z,sh07.w,sh08.x);sh[12]=vec3f(sh08.y,sh08.z,sh08.w);sh[13]=vec3f(sh09.x,sh09.y,sh09.z);sh[14]=vec3f(sh09.w,sh10.x,sh10.y);sh[15]=vec3f(sh10.z,sh10.w,sh11.x);\n#endif\n#if SH_DEGREE>3\nlet sh12: vec4f=decompose(splat.sh3.x);let sh13: vec4f=decompose(splat.sh3.y);let sh14: vec4f=decompose(splat.sh3.z);let sh15: vec4f=decompose(splat.sh3.w);let sh16: vec4f=decompose(splat.sh4.x);let sh17: vec4f=decompose(splat.sh4.y);sh[16]=vec3f(sh11.y,sh11.z,sh11.w);sh[17]=vec3f(sh12.x,sh12.y,sh12.z);sh[18]=vec3f(sh12.w,sh13.x,sh13.y);sh[19]=vec3f(sh13.z,sh13.w,sh14.x);sh[20]=vec3f(sh14.y,sh14.z,sh14.w);sh[21]=vec3f(sh15.x,sh15.y,sh15.z);sh[22]=vec3f(sh15.w,sh16.x,sh16.y);sh[23]=vec3f(sh16.z,sh16.w,sh17.x);sh[24]=vec3f(sh17.y,sh17.z,sh17.w);\n#endif\nreturn computeColorFromSHDegree(dir,sh);}\nfn gaussianSplatting(\nmeshPos: vec2<f32>,\nworldPos: vec3<f32>,\nscale: vec2<f32>,\ncovA: vec3<f32>,\ncovB: vec3<f32>,\nworldMatrix: mat4x4<f32>,\nviewMatrix: mat4x4<f32>,\nprojectionMatrix: mat4x4<f32>,\nfocal: vec2f,\ninvViewport: vec2f,\nkernelSize: f32\n)->vec4f {let modelView=viewMatrix*worldMatrix;let camspace=viewMatrix*vec4f(worldPos,1.0);let pos2d=projectionMatrix*camspace;let bounds=1.2*pos2d.w;if (pos2d.z<0. || pos2d.x<-bounds || pos2d.x>bounds || pos2d.y<-bounds || pos2d.y>bounds) {return vec4f(0.0,0.0,2.0,1.0);}\nlet Vrk=mat3x3<f32>(\ncovA.x,covA.y,covA.z,\ncovA.y,covB.x,covB.y,\ncovA.z,covB.y,covB.z\n);let isOrtho=abs(projectionMatrix[3][3]-1.0)<0.001;var J: mat3x3<f32>;if (isOrtho) {J=mat3x3<f32>(\nfocal.x,0.0,0.0,\n0.0,focal.y,0.0,\n0.0,0.0,0.0\n);} else {J=mat3x3<f32>(\nfocal.x/camspace.z,0.0,-(focal.x*camspace.x)/(camspace.z*camspace.z),\n0.0,focal.y/camspace.z,-(focal.y*camspace.y)/(camspace.z*camspace.z),\n0.0,0.0,0.0\n);}\nlet T=transpose(mat3x3<f32>(\nmodelView[0].xyz,\nmodelView[1].xyz,\nmodelView[2].xyz))*J;var cov2d=transpose(T)*Vrk*T;\n#if COMPENSATION\nlet c00: f32=cov2d[0][0];let c11: f32=cov2d[1][1];let c01: f32=cov2d[0][1];let detOrig: f32=c00*c11-c01*c01;\n#endif\ncov2d[0][0]+=kernelSize;cov2d[1][1]+=kernelSize;\n#if COMPENSATION\nlet c2d: vec3f=vec3f(cov2d[0][0],c01,cov2d[1][1]);let detBlur: f32=c2d.x*c2d.z-c2d.y*c2d.y;let compensation: f32=sqrt(max(0.,detOrig/detBlur));vertexOutputs.vColor.w*=compensation;\n#endif\nlet mid=(cov2d[0][0]+cov2d[1][1])/2.0;let radius=length(vec2<f32>((cov2d[0][0]-cov2d[1][1])/2.0,cov2d[0][1]));let lambda1=mid+radius;let lambda2=mid-radius;if (lambda2<0.0) {return vec4f(0.0,0.0,2.0,1.0);}\nlet diagonalVector=normalize(vec2<f32>(cov2d[0][1],lambda1-cov2d[0][0]));let majorAxis=min(sqrt(2.0*lambda1),1024.0)*diagonalVector;let minorAxis=min(sqrt(2.0*lambda2),1024.0)*vec2<f32>(diagonalVector.y,-diagonalVector.x);let vCenter=vec2<f32>(pos2d.x,pos2d.y);let scaleFactor=select(pos2d.w,1.0,isOrtho);return vec4f(\nvCenter+((meshPos.x*majorAxis+meshPos.y*minorAxis)*invViewport*scaleFactor)*scale,\npos2d.z,\npos2d.w\n);}\n#if IS_COMPOUND\nfn getPartWorld(partIndex: u32)->mat4x4<f32> {return uniforms.partWorld[partIndex];}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const gaussianSplattingWGSL = { name, shader };\n"]}
|
|
1
|
+
{"version":3,"file":"gaussianSplatting.js","sourceRoot":"","sources":["../../../../../dev/core/src/ShadersWGSL/ShadersInclude/gaussianSplatting.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,IAAI,GAAG,mBAAmB,CAAC;AACjC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Nd,CAAC;AACF,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC;IAC9C,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AACxD,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\n\nconst name = \"gaussianSplatting\";\nconst shader = `fn getDataUV(index: f32,dataTextureSize: vec2f)->vec2<f32> {let y: f32=floor(index/dataTextureSize.x);let x: f32=index-y*dataTextureSize.x;return vec2f((x+0.5),(y+0.5));}\nstruct Splat {center: vec4f,\ncolor: vec4f,\ncovA: vec4f,\ncovB: vec4f,\n#if SH_DEGREE>0\nsh0: vec4<u32>,\n#endif\n#if SH_DEGREE>1\nsh1: vec4<u32>,\n#endif\n#if SH_DEGREE>2\nsh2: vec4<u32>,\n#endif\n#if SH_DEGREE>3\nsh3: vec4<u32>,\nsh4: vec4<u32>,\n#endif\n#if IS_COMPOUND\npartIndex: u32,\n#endif\n#if defined(IS_FOR_VOXELIZATION)\nrotationA: vec4f,\nrotationB: vec4f,\nrotationScale: vec4f,\n#endif\n};fn getSplatIndex(localIndex: i32,splatIndex0: vec4f,splatIndex1: vec4f,splatIndex2: vec4f,splatIndex3: vec4f)->f32 {var splatIndex: f32;switch (localIndex)\n{case 0:\n{splatIndex=splatIndex0.x;break;}\ncase 1:\n{splatIndex=splatIndex0.y;break;}\ncase 2:\n{splatIndex=splatIndex0.z;break;}\ncase 3:\n{splatIndex=splatIndex0.w;break;}\ncase 4:\n{splatIndex=splatIndex1.x;break;}\ncase 5:\n{splatIndex=splatIndex1.y;break;}\ncase 6:\n{splatIndex=splatIndex1.z;break;}\ncase 7:\n{splatIndex=splatIndex1.w;break;}\ncase 8:\n{splatIndex=splatIndex2.x;break;}\ncase 9:\n{splatIndex=splatIndex2.y;break;}\ncase 10:\n{splatIndex=splatIndex2.z;break;}\ncase 11:\n{splatIndex=splatIndex2.w;break;}\ncase 12:\n{splatIndex=splatIndex3.x;break;}\ncase 13:\n{splatIndex=splatIndex3.y;break;}\ncase 14:\n{splatIndex=splatIndex3.z;break;}\ndefault:\n{splatIndex=splatIndex3.w;break;}}\nreturn splatIndex;}\nfn readSplat(splatIndex: f32,dataTextureSize: vec2f)->Splat {var splat: Splat;let splatUV=getDataUV(splatIndex,dataTextureSize);let splatUVi32=vec2<i32>(i32(splatUV.x),i32(splatUV.y));splat.center=textureLoad(centersTexture,splatUVi32,0);splat.color=textureLoad(colorsTexture,splatUVi32,0);\n#if !defined(IS_FOR_VOXELIZATION)\nsplat.covA=textureLoad(covariancesATexture,splatUVi32,0)*splat.center.w;splat.covB=textureLoad(covariancesBTexture,splatUVi32,0)*splat.center.w;\n#endif\n#if SH_DEGREE>0\nsplat.sh0=textureLoad(shTexture0,splatUVi32,0);\n#endif\n#if SH_DEGREE>1\nsplat.sh1=textureLoad(shTexture1,splatUVi32,0);\n#endif\n#if SH_DEGREE>2\nsplat.sh2=textureLoad(shTexture2,splatUVi32,0);\n#endif\n#if SH_DEGREE>3\nsplat.sh3=textureLoad(shTexture3,splatUVi32,0);splat.sh4=textureLoad(shTexture4,splatUVi32,0);\n#endif\n#if IS_COMPOUND\nsplat.partIndex=u32(textureLoad(partIndicesTexture,splatUVi32,0).r*255.0+0.5);\n#endif\n#if defined(IS_FOR_VOXELIZATION)\nsplat.rotationA=textureLoad(rotationsATexture,splatUVi32,0);splat.rotationB=textureLoad(rotationsBTexture,splatUVi32,0);splat.rotationScale=textureLoad(rotationScaleTexture,splatUVi32,0);\n#endif\nreturn splat;}\nfn computeColorFromSHDegree(dir: vec3f,sh: array<vec3<f32>,25>)->vec3f\n{let SH_C0: f32=0.28209479;let SH_C1: f32=0.48860251;var SH_C2: array<f32,5>=array<f32,5>(\n1.092548430,\n-1.09254843,\n0.315391565,\n-1.09254843,\n0.546274215\n);var SH_C3: array<f32,7>=array<f32,7>(\n-0.59004358,\n2.890611442,\n-0.45704579,\n0.373176332,\n-0.45704579,\n1.445305721,\n-0.59004358\n);var SH_C4: array<f32,9>=array<f32,9>(\n2.5033429418,\n-1.7701307698,\n0.9461746958,\n-0.6690465436,\n0.1057855469,\n-0.6690465436,\n0.4730873479,\n-1.7701307698,\n0.6258357354\n);var result: vec3f=/*SH_C0**/sh[0];\n#if SH_DEGREE>0\nlet x: f32=dir.x;let y: f32=dir.y;let z: f32=dir.z;result+=-SH_C1*y*sh[1]+SH_C1*z*sh[2]-SH_C1*x*sh[3];\n#if SH_DEGREE>1\nlet xx: f32=x*x;let yy: f32=y*y;let zz: f32=z*z;let xy: f32=x*y;let yz: f32=y*z;let xz: f32=x*z;result +=\nSH_C2[0]*xy*sh[4] +\nSH_C2[1]*yz*sh[5] +\nSH_C2[2]*(2.0f*zz-xx-yy)*sh[6] +\nSH_C2[3]*xz*sh[7] +\nSH_C2[4]*(xx-yy)*sh[8];\n#if SH_DEGREE>2\nresult +=\nSH_C3[0]*y*(3.0f*xx-yy)*sh[9] +\nSH_C3[1]*xy*z*sh[10] +\nSH_C3[2]*y*(4.0f*zz-xx-yy)*sh[11] +\nSH_C3[3]*z*(2.0f*zz-3.0f*xx-3.0f*yy)*sh[12] +\nSH_C3[4]*x*(4.0f*zz-xx-yy)*sh[13] +\nSH_C3[5]*z*(xx-yy)*sh[14] +\nSH_C3[6]*x*(xx-3.0f*yy)*sh[15];\n#if SH_DEGREE>3\nresult +=\nSH_C4[0]*x*y*(xx-yy)*sh[16] +\nSH_C4[1]*y*z*(3.0f*xx-yy)*sh[17] +\nSH_C4[2]*x*y*(7.0f*zz-1.0f)*sh[18] +\nSH_C4[3]*y*z*(7.0f*zz-3.0f)*sh[19] +\nSH_C4[4]*(zz*(35.0f*zz-30.0f)+3.0f)*sh[20] +\nSH_C4[5]*x*z*(7.0f*zz-3.0f)*sh[21] +\nSH_C4[6]*(xx-yy)*(7.0f*zz-1.0f)*sh[22] +\nSH_C4[7]*x*z*(xx-3.0f*yy)*sh[23] +\nSH_C4[8]*(xx*(xx-3.0f*yy)-yy*(3.0f*xx-yy))*sh[24];\n#endif\n#endif\n#endif\n#endif\nreturn result;}\nfn decompose(value: u32)->vec4f\n{let components : vec4f=vec4f(\nf32((value ) & 255u),\nf32((value>>u32( 8)) & 255u),\nf32((value>>u32(16)) & 255u),\nf32((value>>u32(24)) & 255u));return components*vec4f(2./255.)-vec4f(1.);}\nfn computeSH(splat: Splat,dir: vec3f)->vec3f\n{var sh: array<vec3<f32>,25>;sh[0]=vec3f(0.,0.,0.);\n#if SH_DEGREE>0\nlet sh00: vec4f=decompose(splat.sh0.x);let sh01: vec4f=decompose(splat.sh0.y);let sh02: vec4f=decompose(splat.sh0.z);sh[1]=vec3f(sh00.x,sh00.y,sh00.z);sh[2]=vec3f(sh00.w,sh01.x,sh01.y);sh[3]=vec3f(sh01.z,sh01.w,sh02.x);\n#endif\n#if SH_DEGREE>1\nlet sh03: vec4f=decompose(splat.sh0.w);let sh04: vec4f=decompose(splat.sh1.x);let sh05: vec4f=decompose(splat.sh1.y);sh[4]=vec3f(sh02.y,sh02.z,sh02.w);sh[5]=vec3f(sh03.x,sh03.y,sh03.z);sh[6]=vec3f(sh03.w,sh04.x,sh04.y);sh[7]=vec3f(sh04.z,sh04.w,sh05.x);sh[8]=vec3f(sh05.y,sh05.z,sh05.w);\n#endif\n#if SH_DEGREE>2\nlet sh06: vec4f=decompose(splat.sh1.z);let sh07: vec4f=decompose(splat.sh1.w);let sh08: vec4f=decompose(splat.sh2.x);let sh09: vec4f=decompose(splat.sh2.y);let sh10: vec4f=decompose(splat.sh2.z);let sh11: vec4f=decompose(splat.sh2.w);sh[9]=vec3f(sh06.x,sh06.y,sh06.z);sh[10]=vec3f(sh06.w,sh07.x,sh07.y);sh[11]=vec3f(sh07.z,sh07.w,sh08.x);sh[12]=vec3f(sh08.y,sh08.z,sh08.w);sh[13]=vec3f(sh09.x,sh09.y,sh09.z);sh[14]=vec3f(sh09.w,sh10.x,sh10.y);sh[15]=vec3f(sh10.z,sh10.w,sh11.x);\n#endif\n#if SH_DEGREE>3\nlet sh12: vec4f=decompose(splat.sh3.x);let sh13: vec4f=decompose(splat.sh3.y);let sh14: vec4f=decompose(splat.sh3.z);let sh15: vec4f=decompose(splat.sh3.w);let sh16: vec4f=decompose(splat.sh4.x);let sh17: vec4f=decompose(splat.sh4.y);sh[16]=vec3f(sh11.y,sh11.z,sh11.w);sh[17]=vec3f(sh12.x,sh12.y,sh12.z);sh[18]=vec3f(sh12.w,sh13.x,sh13.y);sh[19]=vec3f(sh13.z,sh13.w,sh14.x);sh[20]=vec3f(sh14.y,sh14.z,sh14.w);sh[21]=vec3f(sh15.x,sh15.y,sh15.z);sh[22]=vec3f(sh15.w,sh16.x,sh16.y);sh[23]=vec3f(sh16.z,sh16.w,sh17.x);sh[24]=vec3f(sh17.y,sh17.z,sh17.w);\n#endif\nreturn computeColorFromSHDegree(dir,sh);}\nfn gaussianSplatting(\nmeshPos: vec2<f32>,\nworldPos: vec3<f32>,\nscale: vec2<f32>,\ncovA: vec3<f32>,\ncovB: vec3<f32>,\nworldMatrix: mat4x4<f32>,\nviewMatrix: mat4x4<f32>,\nprojectionMatrix: mat4x4<f32>,\nfocal: vec2f,\ninvViewport: vec2f,\nkernelSize: f32\n)->vec4f {let modelView=viewMatrix*worldMatrix;let camspace=viewMatrix*vec4f(worldPos,1.0);let pos2d=projectionMatrix*camspace;let bounds=1.2*pos2d.w;if (pos2d.z<0. || pos2d.x<-bounds || pos2d.x>bounds || pos2d.y<-bounds || pos2d.y>bounds) {return vec4f(0.0,0.0,2.0,1.0);}\nlet Vrk=mat3x3<f32>(\ncovA.x,covA.y,covA.z,\ncovA.y,covB.x,covB.y,\ncovA.z,covB.y,covB.z\n);let isOrtho=abs(projectionMatrix[3][3]-1.0)<0.001;var J: mat3x3<f32>;if (isOrtho) {J=mat3x3<f32>(\nfocal.x,0.0,0.0,\n0.0,focal.y,0.0,\n0.0,0.0,0.0\n);} else {J=mat3x3<f32>(\nfocal.x/camspace.z,0.0,-(focal.x*camspace.x)/(camspace.z*camspace.z),\n0.0,focal.y/camspace.z,-(focal.y*camspace.y)/(camspace.z*camspace.z),\n0.0,0.0,0.0\n);}\nlet T=transpose(mat3x3<f32>(\nmodelView[0].xyz,\nmodelView[1].xyz,\nmodelView[2].xyz))*J;var cov2d=transpose(T)*Vrk*T;\n#if COMPENSATION\nlet c00: f32=cov2d[0][0];let c11: f32=cov2d[1][1];let c01: f32=cov2d[0][1];let detOrig: f32=c00*c11-c01*c01;\n#endif\ncov2d[0][0]+=kernelSize;cov2d[1][1]+=kernelSize;\n#if COMPENSATION\nlet c2d: vec3f=vec3f(cov2d[0][0],c01,cov2d[1][1]);let detBlur: f32=c2d.x*c2d.z-c2d.y*c2d.y;let compensation: f32=sqrt(max(0.,detOrig/detBlur));vertexOutputs.vColor.w*=compensation;\n#endif\nlet mid=(cov2d[0][0]+cov2d[1][1])/2.0;let radius=length(vec2<f32>((cov2d[0][0]-cov2d[1][1])/2.0,cov2d[0][1]));let lambda1=mid+radius;let lambda2=mid-radius;if (lambda2<0.0) {return vec4f(0.0,0.0,2.0,1.0);}\nlet diagonalVector=normalize(vec2<f32>(cov2d[0][1],lambda1-cov2d[0][0]));let majorAxis=min(sqrt(2.0*lambda1),1024.0)*diagonalVector;let minorAxis=min(sqrt(2.0*lambda2),1024.0)*vec2<f32>(diagonalVector.y,-diagonalVector.x);let vCenter=vec2<f32>(pos2d.x,pos2d.y);let scaleFactor=select(pos2d.w,1.0,isOrtho);return vec4f(\nvCenter+((meshPos.x*majorAxis+meshPos.y*minorAxis)*invViewport*scaleFactor)*scale,\npos2d.z,\npos2d.w\n);}\n#if IS_COMPOUND\nfn getPartWorld(partIndex: u32)->mat4x4<f32> {return uniforms.partWorld[partIndex];}\n#endif\n#if defined(IS_FOR_VOXELIZATION)\nfn computeVoxelSplatWorldPos(rotationA: vec4f,rotationB: vec4f,rotationScale: vec4f,center: vec3f,splatWorld: mat4x4f,viewMatrix: mat4x4f,invWorldScale: mat4x4f,quadPos: vec2f)->vec4f {let splatRotation=mat3x3f(\nrotationA.xyz,\nvec3f(rotationA.w,rotationB.x,rotationB.y),\nvec3f(rotationB.z,rotationB.w,rotationScale.x)\n);let splatScale=rotationScale.yzw;let view3x3=mat3x3f(viewMatrix[0].xyz,viewMatrix[1].xyz,viewMatrix[2].xyz);let invWorldScale3x3=mat3x3f(invWorldScale[0].xyz,invWorldScale[1].xyz,invWorldScale[2].xyz);let splatWorld3x3=mat3x3f(splatWorld[0].xyz,splatWorld[1].xyz,splatWorld[2].xyz);let rotToView=view3x3*invWorldScale3x3*splatWorld3x3*splatRotation;let axisLengthInViewZ=abs(vec3f(rotToView[0][2],rotToView[1][2],rotToView[2][2]));let gaussianSplatCutoffStddev: f32=0.7071067812; \nvar offsetSplatSpace: vec3f;if (axisLengthInViewZ.x>axisLengthInViewZ.y && axisLengthInViewZ.x>axisLengthInViewZ.z) {offsetSplatSpace=vec3f(0.0,quadPos.x,quadPos.y)*splatScale*gaussianSplatCutoffStddev;} else if (axisLengthInViewZ.y>axisLengthInViewZ.z) {offsetSplatSpace=vec3f(quadPos.x,0.0,quadPos.y)*splatScale*gaussianSplatCutoffStddev;} else {offsetSplatSpace=vec3f(quadPos.x,quadPos.y,0.0)*splatScale*gaussianSplatCutoffStddev;}\nlet vertexObjectSpace=center+splatRotation*offsetSplatSpace;return splatWorld*vec4f(vertexObjectSpace,1.0);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const gaussianSplattingWGSL = { name, shader };\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Do not edit.
|
|
2
|
+
import { ShaderStore } from "../Engines/shaderStore.js";
|
|
3
|
+
const name = "gaussianSplattingVoxelPixelShader";
|
|
4
|
+
const shader = `var voxel_storage: texture_storage_3d<r8unorm,write>;varying vNormalizedPosition: vec3f;varying vNormalizedCenterPosition: vec3f;varying vAlpha: f32;varying vPatchPosition: vec2f;fn gsVoxelPrngCanonical1d(co: f32)->f32 {return fract(sin(co*91.3458)*47453.5453);}
|
|
5
|
+
fn gsVoxelPrngCanonical2d(co: vec2f)->f32 {return fract(sin(dot(co,vec2f(12.9898,78.233)))*43758.5453);}
|
|
6
|
+
fn gsVoxelPrngCanonical3d(co: vec3f)->f32 {return gsVoxelPrngCanonical2d(vec2f(co.x,co.y)+gsVoxelPrngCanonical1d(co.z));}
|
|
7
|
+
@fragment
|
|
8
|
+
fn main(input: FragmentInputs)->FragmentOutputs {let normPos: vec3f=input.vNormalizedPosition;let stepSize: f32=1.0/f32(textureDimensions(voxel_storage).x);let diff: vec3f=abs(input.vNormalizedCenterPosition-normPos);let distToCenter: f32=max(max(diff.x,diff.y),diff.z);let gaussian: f32=exp(-dot(input.vPatchPosition,input.vPatchPosition));let shadowingOpacity: f32=clamp(
|
|
9
|
+
select(gaussian,1.0,distToCenter<stepSize)*input.vAlpha,
|
|
10
|
+
0.0,1.0
|
|
11
|
+
);if (shadowingOpacity<1.0 && shadowingOpacity<gsVoxelPrngCanonical3d(normPos/stepSize)) {discard;}
|
|
12
|
+
let size: vec3f=vec3f(textureDimensions(voxel_storage));textureStore(voxel_storage,
|
|
13
|
+
vec3<i32>(i32(normPos.x*size.x),i32(normPos.y*size.y),i32(normPos.z*size.z)),
|
|
14
|
+
vec4f(1.0,1.0,1.0,1.0));fragmentOutputs.color=vec4f(0.0,0.0,0.0,0.0);}
|
|
15
|
+
`;
|
|
16
|
+
// Sideeffect
|
|
17
|
+
if (!ShaderStore.ShadersStoreWGSL[name]) {
|
|
18
|
+
ShaderStore.ShadersStoreWGSL[name] = shader;
|
|
19
|
+
}
|
|
20
|
+
/** @internal */
|
|
21
|
+
export const gaussianSplattingVoxelPixelShaderWGSL = { name, shader };
|
|
22
|
+
//# sourceMappingURL=gaussianSplattingVoxel.fragment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gaussianSplattingVoxel.fragment.js","sourceRoot":"","sources":["../../../../dev/core/src/ShadersWGSL/gaussianSplattingVoxel.fragment.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,MAAM,IAAI,GAAG,mCAAmC,CAAC;AACjD,MAAM,MAAM,GAAG;;;;;;;;;;;CAWd,CAAC;AACF,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;IACtC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAChD,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,qCAAqC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gaussianSplattingVoxelPixelShader\";\nconst shader = `var voxel_storage: texture_storage_3d<r8unorm,write>;varying vNormalizedPosition: vec3f;varying vNormalizedCenterPosition: vec3f;varying vAlpha: f32;varying vPatchPosition: vec2f;fn gsVoxelPrngCanonical1d(co: f32)->f32 {return fract(sin(co*91.3458)*47453.5453);}\nfn gsVoxelPrngCanonical2d(co: vec2f)->f32 {return fract(sin(dot(co,vec2f(12.9898,78.233)))*43758.5453);}\nfn gsVoxelPrngCanonical3d(co: vec3f)->f32 {return gsVoxelPrngCanonical2d(vec2f(co.x,co.y)+gsVoxelPrngCanonical1d(co.z));}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let normPos: vec3f=input.vNormalizedPosition;let stepSize: f32=1.0/f32(textureDimensions(voxel_storage).x);let diff: vec3f=abs(input.vNormalizedCenterPosition-normPos);let distToCenter: f32=max(max(diff.x,diff.y),diff.z);let gaussian: f32=exp(-dot(input.vPatchPosition,input.vPatchPosition));let shadowingOpacity: f32=clamp(\nselect(gaussian,1.0,distToCenter<stepSize)*input.vAlpha,\n0.0,1.0\n);if (shadowingOpacity<1.0 && shadowingOpacity<gsVoxelPrngCanonical3d(normPos/stepSize)) {discard;}\nlet size: vec3f=vec3f(textureDimensions(voxel_storage));textureStore(voxel_storage,\nvec3<i32>(i32(normPos.x*size.x),i32(normPos.y*size.y),i32(normPos.z*size.z)),\nvec4f(1.0,1.0,1.0,1.0));fragmentOutputs.color=vec4f(0.0,0.0,0.0,0.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const gaussianSplattingVoxelPixelShaderWGSL = { name, shader };\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./ShadersInclude/sceneUboDeclaration.js";
|
|
2
|
+
import "./ShadersInclude/meshUboDeclaration.js";
|
|
3
|
+
import "./ShadersInclude/gaussianSplatting.js";
|
|
4
|
+
/** @internal */
|
|
5
|
+
export declare const gaussianSplattingVoxelVertexShaderWGSL: {
|
|
6
|
+
name: string;
|
|
7
|
+
shader: string;
|
|
8
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Do not edit.
|
|
2
|
+
import { ShaderStore } from "../Engines/shaderStore.js";
|
|
3
|
+
import "./ShadersInclude/sceneUboDeclaration.js";
|
|
4
|
+
import "./ShadersInclude/meshUboDeclaration.js";
|
|
5
|
+
import "./ShadersInclude/gaussianSplatting.js";
|
|
6
|
+
const name = "gaussianSplattingVoxelVertexShader";
|
|
7
|
+
const shader = `#include<sceneUboDeclaration>
|
|
8
|
+
#include<meshUboDeclaration>
|
|
9
|
+
attribute splatIndex0: vec4f;attribute splatIndex1: vec4f;attribute splatIndex2: vec4f;attribute splatIndex3: vec4f;attribute position: vec3f;uniform dataTextureSize: vec2f;uniform alpha: f32;uniform invWorldScale: mat4x4f;uniform viewMatrix: mat4x4f;
|
|
10
|
+
#if IS_COMPOUND
|
|
11
|
+
uniform partWorld: array<mat4x4<f32>,MAX_PART_COUNT>;uniform partVisibility: array<f32,MAX_PART_COUNT>;
|
|
12
|
+
#endif
|
|
13
|
+
var rotationsATexture: texture_2d<f32>;var rotationsBTexture: texture_2d<f32>;var rotationScaleTexture: texture_2d<f32>;var centersTexture: texture_2d<f32>;var colorsTexture: texture_2d<f32>;
|
|
14
|
+
#if IS_COMPOUND
|
|
15
|
+
var partIndicesTexture: texture_2d<f32>;
|
|
16
|
+
#endif
|
|
17
|
+
varying vNormalizedPosition: vec3f;varying vNormalizedCenterPosition: vec3f;varying vAlpha: f32;varying vPatchPosition: vec2f;
|
|
18
|
+
#include<gaussianSplatting>
|
|
19
|
+
@vertex
|
|
20
|
+
fn main(input: VertexInputs)->FragmentInputs {let splatIndex: f32=getSplatIndex(
|
|
21
|
+
i32(vertexInputs.position.z+0.5),
|
|
22
|
+
vertexInputs.splatIndex0,vertexInputs.splatIndex1,
|
|
23
|
+
vertexInputs.splatIndex2,vertexInputs.splatIndex3
|
|
24
|
+
);var splat: Splat=readSplat(splatIndex,uniforms.dataTextureSize);
|
|
25
|
+
#if IS_COMPOUND
|
|
26
|
+
let splatWorld: mat4x4f=getPartWorld(splat.partIndex);
|
|
27
|
+
#else
|
|
28
|
+
let splatWorld: mat4x4f=mesh.world;
|
|
29
|
+
#endif
|
|
30
|
+
let quadPos: vec2f=vertexInputs.position.xy;let worldPos: vec4f=computeVoxelSplatWorldPos(splat.rotationA,splat.rotationB,splat.rotationScale,splat.center.xyz,splatWorld,uniforms.viewMatrix,uniforms.invWorldScale,quadPos);vertexOutputs.vNormalizedPosition=(uniforms.invWorldScale*worldPos).xyz*0.5+0.5;let clipPos: vec4f=uniforms.viewMatrix*uniforms.invWorldScale*worldPos;vertexOutputs.position=vec4f(clipPos.x,clipPos.y,clipPos.z*0.5+0.5,1.0);vertexOutputs.vNormalizedCenterPosition=(uniforms.invWorldScale*splatWorld*vec4f(splat.center.xyz,1.0)).xyz*0.5+0.5;vertexOutputs.vAlpha=splat.color.w*uniforms.alpha;
|
|
31
|
+
#if IS_COMPOUND
|
|
32
|
+
vertexOutputs.vAlpha*=uniforms.partVisibility[splat.partIndex];
|
|
33
|
+
#endif
|
|
34
|
+
vertexOutputs.vPatchPosition=quadPos;}
|
|
35
|
+
`;
|
|
36
|
+
// Sideeffect
|
|
37
|
+
if (!ShaderStore.ShadersStoreWGSL[name]) {
|
|
38
|
+
ShaderStore.ShadersStoreWGSL[name] = shader;
|
|
39
|
+
}
|
|
40
|
+
/** @internal */
|
|
41
|
+
export const gaussianSplattingVoxelVertexShaderWGSL = { name, shader };
|
|
42
|
+
//# sourceMappingURL=gaussianSplattingVoxel.vertex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gaussianSplattingVoxel.vertex.js","sourceRoot":"","sources":["../../../../dev/core/src/ShadersWGSL/gaussianSplattingVoxel.vertex.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,sCAAsC,CAAC;AAC9C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,oCAAoC,CAAC;AAE5C,MAAM,IAAI,GAAG,oCAAoC,CAAC;AAClD,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4Bd,CAAC;AACF,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;IACtC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAChD,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,sCAAsC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport \"./ShadersInclude/sceneUboDeclaration\";\nimport \"./ShadersInclude/meshUboDeclaration\";\nimport \"./ShadersInclude/gaussianSplatting\";\n\nconst name = \"gaussianSplattingVoxelVertexShader\";\nconst shader = `#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\nattribute splatIndex0: vec4f;attribute splatIndex1: vec4f;attribute splatIndex2: vec4f;attribute splatIndex3: vec4f;attribute position: vec3f;uniform dataTextureSize: vec2f;uniform alpha: f32;uniform invWorldScale: mat4x4f;uniform viewMatrix: mat4x4f;\n#if IS_COMPOUND\nuniform partWorld: array<mat4x4<f32>,MAX_PART_COUNT>;uniform partVisibility: array<f32,MAX_PART_COUNT>;\n#endif\nvar rotationsATexture: texture_2d<f32>;var rotationsBTexture: texture_2d<f32>;var rotationScaleTexture: texture_2d<f32>;var centersTexture: texture_2d<f32>;var colorsTexture: texture_2d<f32>;\n#if IS_COMPOUND\nvar partIndicesTexture: texture_2d<f32>;\n#endif\nvarying vNormalizedPosition: vec3f;varying vNormalizedCenterPosition: vec3f;varying vAlpha: f32;varying vPatchPosition: vec2f;\n#include<gaussianSplatting>\n@vertex\nfn main(input: VertexInputs)->FragmentInputs {let splatIndex: f32=getSplatIndex(\ni32(vertexInputs.position.z+0.5),\nvertexInputs.splatIndex0,vertexInputs.splatIndex1,\nvertexInputs.splatIndex2,vertexInputs.splatIndex3\n);var splat: Splat=readSplat(splatIndex,uniforms.dataTextureSize);\n#if IS_COMPOUND\nlet splatWorld: mat4x4f=getPartWorld(splat.partIndex);\n#else\nlet splatWorld: mat4x4f=mesh.world;\n#endif\nlet quadPos: vec2f=vertexInputs.position.xy;let worldPos: vec4f=computeVoxelSplatWorldPos(splat.rotationA,splat.rotationB,splat.rotationScale,splat.center.xyz,splatWorld,uniforms.viewMatrix,uniforms.invWorldScale,quadPos);vertexOutputs.vNormalizedPosition=(uniforms.invWorldScale*worldPos).xyz*0.5+0.5;let clipPos: vec4f=uniforms.viewMatrix*uniforms.invWorldScale*worldPos;vertexOutputs.position=vec4f(clipPos.x,clipPos.y,clipPos.z*0.5+0.5,1.0);vertexOutputs.vNormalizedCenterPosition=(uniforms.invWorldScale*splatWorld*vec4f(splat.center.xyz,1.0)).xyz*0.5+0.5;vertexOutputs.vAlpha=splat.color.w*uniforms.alpha;\n#if IS_COMPOUND\nvertexOutputs.vAlpha*=uniforms.partVisibility[splat.partIndex];\n#endif\nvertexOutputs.vPatchPosition=quadPos;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const gaussianSplattingVoxelVertexShaderWGSL = { name, shader };\n"]}
|
|
@@ -78,6 +78,12 @@ startSizeGradientFactor : f32,
|
|
|
78
78
|
#ifdef LIFETIMEGRADIENTS
|
|
79
79
|
lifeTimeGradientRange : vec2<f32>,
|
|
80
80
|
#endif
|
|
81
|
+
#ifdef MESHEMITTER
|
|
82
|
+
meshTriangleCount : i32,
|
|
83
|
+
meshTextureWidth : i32,
|
|
84
|
+
direction1 : vec3<f32>,
|
|
85
|
+
direction2 : vec3<f32>,
|
|
86
|
+
#endif
|
|
81
87
|
#ifdef BOXEMITTER
|
|
82
88
|
direction1 : vec3<f32>,
|
|
83
89
|
direction2 : vec3<f32>,
|
|
@@ -147,6 +153,12 @@ directionRandomizer : f32,
|
|
|
147
153
|
#ifdef FLOWMAP
|
|
148
154
|
@binding(12) @group(1) var flowMapSampler : sampler;@binding(13) @group(1) var flowMapTexture : texture_2d<f32>;
|
|
149
155
|
#endif
|
|
156
|
+
#ifdef MESHEMITTER
|
|
157
|
+
@binding(14) @group(1) var meshPositionTexture : texture_2d<f32>;
|
|
158
|
+
#ifdef MESHNORMALS
|
|
159
|
+
@binding(15) @group(1) var meshNormalTexture : texture_2d<f32>;
|
|
160
|
+
#endif
|
|
161
|
+
#endif
|
|
150
162
|
fn getRandomVec3(offset : f32,vertexID : f32)->vec3<f32> {return textureLoad(randomTexture2,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0).rgb;}
|
|
151
163
|
fn getRandomVec4(offset : f32,vertexID : f32)->vec4<f32> {return textureLoad(randomTexture,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0);}
|
|
152
164
|
@compute @workgroup_size(64)
|
|
@@ -226,6 +238,13 @@ newDirection=params.direction1+(params.direction2-params.direction1)*randoms3;
|
|
|
226
238
|
#else
|
|
227
239
|
if (abs(cos(params.coneAngle))==1.0) {newDirection=vec3<f32>(0.,1.0,0.);} else {newDirection=normalize(newPosition+params.directionRandomizer*randoms3); }
|
|
228
240
|
#endif
|
|
241
|
+
#elif defined(MESHEMITTER)
|
|
242
|
+
let randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);var triIdx : i32=i32(floor(randoms2.x*f32(params.meshTriangleCount)));triIdx=min(triIdx,params.meshTriangleCount-1);let baseTexel : i32=triIdx*3;let t0 : i32=baseTexel;let t1 : i32=baseTexel+1;let t2 : i32=baseTexel+2;let v0 : vec3<f32>=textureLoad(meshPositionTexture,vec2<i32>(t0 % params.meshTextureWidth,t0/params.meshTextureWidth),0).xyz;let v1 : vec3<f32>=textureLoad(meshPositionTexture,vec2<i32>(t1 % params.meshTextureWidth,t1/params.meshTextureWidth),0).xyz;let v2 : vec3<f32>=textureLoad(meshPositionTexture,vec2<i32>(t2 % params.meshTextureWidth,t2/params.meshTextureWidth),0).xyz;let bu : f32=randoms2.y;let bv : f32=randoms2.z*(1.0-bu);let bw : f32=1.0-bu-bv;newPosition=bu*v0+bv*v1+bw*v2;
|
|
243
|
+
#ifdef MESHNORMALS
|
|
244
|
+
let n0 : vec3<f32>=textureLoad(meshNormalTexture,vec2<i32>(t0 % params.meshTextureWidth,t0/params.meshTextureWidth),0).xyz;let n1 : vec3<f32>=textureLoad(meshNormalTexture,vec2<i32>(t1 % params.meshTextureWidth,t1/params.meshTextureWidth),0).xyz;let n2 : vec3<f32>=textureLoad(meshNormalTexture,vec2<i32>(t2 % params.meshTextureWidth,t2/params.meshTextureWidth),0).xyz;newDirection=normalize(bu*n0+bv*n1+bw*n2);
|
|
245
|
+
#else
|
|
246
|
+
newDirection=params.direction1+(params.direction2-params.direction1)*randoms3;
|
|
247
|
+
#endif
|
|
229
248
|
#elif defined(CUSTOMEMITTER)
|
|
230
249
|
newPosition=particlesIn.particles[index].initialPosition;particlesOut.particles[index].initialPosition=newPosition;
|
|
231
250
|
#else
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gpuUpdateParticles.compute.js","sourceRoot":"","sources":["../../../../dev/core/src/ShadersWGSL/gpuUpdateParticles.compute.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,MAAM,IAAI,GAAG,iCAAiC,CAAC;AAC/C,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoUd,CAAC;AACF,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;IACtC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAChD,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,mCAAmC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gpuUpdateParticlesComputeShader\";\nconst shader = `struct Particle {position : vec3<f32>,\nage : f32,\nsize : vec3<f32>,\nlife : f32,\nseed : vec4<f32>,\ndirection : vec3<f32>,\ndummy0: f32,\n#ifdef CUSTOMEMITTER\ninitialPosition : vec3<f32>,\ndummy1: f32,\n#endif\n#ifndef COLORGRADIENTS\ncolor : vec4<f32>,\n#endif\n#ifndef BILLBOARD\ninitialDirection : vec3<f32>,\ndummy2: f32,\n#endif\n#ifdef NOISE\nnoiseCoordinates1 : vec3<f32>,\ndummy3: f32,\nnoiseCoordinates2 : vec3<f32>,\ndummy4: f32,\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nangle : f32,\n#else\nangle : vec2<f32>,\n#endif\n#ifdef ANIMATESHEET\ncellIndex : f32,\n#ifdef ANIMATESHEETRANDOMSTART\ncellStartOffset : f32,\n#endif\n#endif\n};struct Particles {particles : array<Particle>,};struct SimParams {currentCount : f32,\ntimeDelta : f32,\nstopFactor : f32,\nrandomTextureSize: i32,\nlifeTime : vec2<f32>,\nemitPower : vec2<f32>,\nemitIndex : f32,\nemitCount : f32,\n#ifndef COLORGRADIENTS\ncolor1 : vec4<f32>,\ncolor2 : vec4<f32>,\n#endif\nsizeRange : vec2<f32>,\nscaleRange : vec4<f32>,\nangleRange : vec4<f32>,\ngravity : vec3<f32>,\n#ifdef LIMITVELOCITYGRADIENTS\nlimitVelocityDamping : f32,\n#endif\n#ifdef ANIMATESHEET\ncellInfos : vec4<f32>,\n#endif\n#ifdef NOISE\nnoiseStrength : vec3<f32>,\n#endif\n#ifdef FLOWMAP\nflowMapProjection : mat4x4<f32>,\nflowMapStrength : f32,\n#endif\n#ifndef LOCAL\nemitterWM : mat4x4<f32>,\n#endif\n#ifdef ATTRACTORS\nattractorCount : i32,\nattractorPositionAndStrength : array<vec4<f32>,MAX_ATTRACTORS>,\n#endif\n#ifdef STARTSIZEGRADIENTS\nstartSizeGradientFactor : f32,\n#endif\n#ifdef LIFETIMEGRADIENTS\nlifeTimeGradientRange : vec2<f32>,\n#endif\n#ifdef BOXEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\nminEmitBox : vec3<f32>,\nmaxEmitBox : vec3<f32>,\n#endif\n#ifdef CONEEMITTER\nradius : vec2<f32>,\nconeAngle : f32,\nheight : vec2<f32>,\n#ifdef DIRECTEDCONEEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#else\ndirectionRandomizer : f32,\n#endif\n#endif\n#ifdef CYLINDEREMITTER\nradius : f32,\nheight : f32,\nradiusRange : f32,\n#ifdef DIRECTEDCYLINDEREMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#else\ndirectionRandomizer : f32,\n#endif\n#endif\n#ifdef HEMISPHERICEMITTER\nradius : f32,\nradiusRange : f32,\ndirectionRandomizer : f32,\n#endif\n#ifdef POINTEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#endif\n#ifdef SPHEREEMITTER\nradius : f32,\nradiusRange : f32,\n#ifdef DIRECTEDSPHEREEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#else\ndirectionRandomizer : f32,\n#endif\n#endif\n};@binding(0) @group(0) var<uniform> params : SimParams;@binding(1) @group(0) var<storage,read> particlesIn : Particles;@binding(2) @group(0) var<storage,read_write> particlesOut : Particles;@binding(3) @group(0) var randomTexture : texture_2d<f32>;@binding(4) @group(0) var randomTexture2 : texture_2d<f32>;\n#ifdef SIZEGRADIENTS\n@binding(0) @group(1) var sizeGradientSampler : sampler;@binding(1) @group(1) var sizeGradientTexture : texture_2d<f32>;\n#endif \n#ifdef ANGULARSPEEDGRADIENTS\n@binding(2) @group(1) var angularSpeedGradientSampler : sampler;@binding(3) @group(1) var angularSpeedGradientTexture : texture_2d<f32>;\n#endif \n#ifdef VELOCITYGRADIENTS\n@binding(4) @group(1) var velocityGradientSampler : sampler;@binding(5) @group(1) var velocityGradientTexture : texture_2d<f32>;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\n@binding(6) @group(1) var limitVelocityGradientSampler : sampler;@binding(7) @group(1) var limitVelocityGradientTexture : texture_2d<f32>;\n#endif\n#ifdef DRAGGRADIENTS\n@binding(8) @group(1) var dragGradientSampler : sampler;@binding(9) @group(1) var dragGradientTexture : texture_2d<f32>;\n#endif\n#ifdef NOISE\n@binding(10) @group(1) var noiseSampler : sampler;@binding(11) @group(1) var noiseTexture : texture_2d<f32>;\n#endif\n#ifdef FLOWMAP\n@binding(12) @group(1) var flowMapSampler : sampler;@binding(13) @group(1) var flowMapTexture : texture_2d<f32>;\n#endif\nfn getRandomVec3(offset : f32,vertexID : f32)->vec3<f32> {return textureLoad(randomTexture2,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0).rgb;}\nfn getRandomVec4(offset : f32,vertexID : f32)->vec4<f32> {return textureLoad(randomTexture,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0);}\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {let index : u32=GlobalInvocationID.x;let vertexID : f32=f32(index);if (index>=u32(params.currentCount)) {return;}\nlet PI : f32=3.14159;let timeDelta : f32=params.timeDelta;let newAge : f32=particlesIn.particles[index].age+timeDelta;let life : f32=particlesIn.particles[index].life;let seed : vec4<f32>=particlesIn.particles[index].seed;let direction : vec3<f32>=particlesIn.particles[index].direction;\n#ifdef EMITRATECTRL\nvar offsetFromEmitIndex : f32=vertexID-params.emitIndex;if (offsetFromEmitIndex<0.0) {offsetFromEmitIndex+=params.currentCount; }\nlet shouldEmit : bool=offsetFromEmitIndex<params.emitCount && params.stopFactor != 0.;\n#else\nlet shouldEmit : bool=newAge>=life && params.stopFactor != 0.;\n#endif\nif (shouldEmit) {var newPosition : vec3<f32>;var newDirection : vec3<f32>;let randoms : vec4<f32>=getRandomVec4(seed.x,vertexID);let outLife : f32=params.lifeTime.x+(params.lifeTime.y-params.lifeTime.x)*randoms.r;\n#ifdef LIFETIMEGRADIENTS\nparticlesOut.particles[index].life=params.lifeTimeGradientRange.x+(params.lifeTimeGradientRange.y-params.lifeTimeGradientRange.x)*randoms.r;\n#else\nparticlesOut.particles[index].life=outLife;\n#endif\n#ifdef EMITRATECTRL\nparticlesOut.particles[index].age=0.0;\n#else\nparticlesOut.particles[index].age=newAge-life;\n#endif\nparticlesOut.particles[index].seed=seed;var sizex : f32;\n#ifdef SIZEGRADIENTS \nlet sizeGradientRange=textureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(0.,0.),0.).rg;sizex=sizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y;\n#else\nsizex=params.sizeRange.x+(params.sizeRange.y-params.sizeRange.x)*randoms.g;\n#endif\n#ifdef STARTSIZEGRADIENTS\nsizex*=params.startSizeGradientFactor;\n#endif\nparticlesOut.particles[index].size=vec3<f32>(\nsizex,\nparams.scaleRange.x+(params.scaleRange.y-params.scaleRange.x)*randoms.b,\nparams.scaleRange.z+(params.scaleRange.w-params.scaleRange.z)*randoms.a);\n#ifndef COLORGRADIENTS\nparticlesOut.particles[index].color=params.color1+(params.color2-params.color1)*randoms.b;\n#endif\n#ifndef ANGULARSPEEDGRADIENTS \nparticlesOut.particles[index].angle=vec2<f32>(\nparams.angleRange.z+(params.angleRange.w-params.angleRange.z)*randoms.r,\nparams.angleRange.x+(params.angleRange.y-params.angleRange.x)*randoms.a);\n#else\nparticlesOut.particles[index].angle=params.angleRange.z+(params.angleRange.w-params.angleRange.z)*randoms.r;\n#endif \n#if defined(POINTEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);newPosition=vec3<f32>(0.,0.,0.);newDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#elif defined(BOXEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);newPosition=params.minEmitBox+(params.maxEmitBox-params.minEmitBox)*randoms2;newDirection=params.direction1+(params.direction2-params.direction1)*randoms3; \n#elif defined(HEMISPHERICEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);let phi : f32=2.0*PI*randoms2.x;let theta : f32=acos(-1.0+2.0*randoms2.y);let randX : f32=cos(phi)*sin(theta);let randY : f32=cos(theta);let randZ : f32=sin(phi)*sin(theta);newPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,abs(randY),randZ);newDirection=normalize(newPosition+params.directionRandomizer*randoms3);\n#elif defined(SPHEREEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);let phi : f32=2.0*PI*randoms2.x;let theta : f32=acos(-1.0+2.0*randoms2.y);let randX : f32=cos(phi)*sin(theta);let randY : f32=cos(theta);let randZ : f32=sin(phi)*sin(theta);newPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,randY,randZ);\n#ifdef DIRECTEDSPHEREEMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#else\nnewDirection=normalize(newPosition+params.directionRandomizer*randoms3);\n#endif\n#elif defined(CYLINDEREMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);let yPos : f32=(-0.5+randoms2.x)*params.height;var angle : f32=randoms2.y*PI*2.;let inverseRadiusRangeSquared : f32=(1.-params.radiusRange)*(1.-params.radiusRange);let positionRadius : f32=params.radius*sqrt(inverseRadiusRangeSquared+randoms2.z*(1.-inverseRadiusRangeSquared));let xPos : f32=positionRadius*cos(angle);let zPos : f32=positionRadius*sin(angle);newPosition=vec3<f32>(xPos,yPos,zPos);\n#ifdef DIRECTEDCYLINDEREMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#else\nangle=angle+(-0.5+randoms3.x)*PI*params.directionRandomizer;newDirection=vec3<f32>(cos(angle),(-0.5+randoms3.y)*params.directionRandomizer,sin(angle));newDirection=normalize(newDirection);\n#endif\n#elif defined(CONEEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let s : f32=2.0*PI*randoms2.x;\n#ifdef CONEEMITTERSPAWNPOINT\nlet h : f32=0.0001;\n#else\nvar h : f32=randoms2.y*params.height.y;h=1.-h*h; \n#endif\nvar lRadius : f32=params.radius.x-params.radius.x*randoms2.z*params.radius.y;lRadius=lRadius*h;let randX : f32=lRadius*sin(s);let randZ : f32=lRadius*cos(s);let randY : f32=h *params.height.x;newPosition=vec3<f32>(randX,randY,randZ); \nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\n#ifdef DIRECTEDCONEEMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#else\nif (abs(cos(params.coneAngle))==1.0) {newDirection=vec3<f32>(0.,1.0,0.);} else {newDirection=normalize(newPosition+params.directionRandomizer*randoms3); }\n#endif\n#elif defined(CUSTOMEMITTER)\nnewPosition=particlesIn.particles[index].initialPosition;particlesOut.particles[index].initialPosition=newPosition;\n#else \nnewPosition=vec3<f32>(0.,0.,0.);newDirection=2.0*(getRandomVec3(seed.w,vertexID)-vec3<f32>(0.5,0.5,0.5));\n#endif\nlet power : f32=params.emitPower.x+(params.emitPower.y-params.emitPower.x)*randoms.a;\n#ifdef LOCAL\nparticlesOut.particles[index].position=newPosition;\n#else\nparticlesOut.particles[index].position=(params.emitterWM*vec4<f32>(newPosition,1.)).xyz;\n#endif\n#ifdef CUSTOMEMITTER\nparticlesOut.particles[index].direction=direction;\n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=direction;\n#endif\n#else\n#ifdef LOCAL\nlet initial : vec3<f32>=newDirection;\n#else \nlet initial : vec3<f32>=(params.emitterWM*vec4<f32>(newDirection,0.)).xyz;\n#endif\nparticlesOut.particles[index].direction=initial*power;\n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=initial;\n#endif\n#endif\n#ifdef ANIMATESHEET \nparticlesOut.particles[index].cellIndex=params.cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\nparticlesOut.particles[index].cellStartOffset=randoms.a*outLife;\n#endif \n#endif\n#ifdef NOISE\nparticlesOut.particles[index].noiseCoordinates1=particlesIn.particles[index].noiseCoordinates1;particlesOut.particles[index].noiseCoordinates2=particlesIn.particles[index].noiseCoordinates2;\n#endif\n} else {var directionScale : f32=timeDelta;particlesOut.particles[index].age=newAge;let ageGradient : f32=newAge/life;\n#ifdef VELOCITYGRADIENTS\nlet velocityGradientRange=textureSampleLevel(velocityGradientTexture,velocityGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;directionScale=directionScale*(velocityGradientRange.x+(velocityGradientRange.y-velocityGradientRange.x)*seed.w);\n#endif\n#ifdef DRAGGRADIENTS\nlet dragGradientRange=textureSampleLevel(dragGradientTexture,dragGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;directionScale=directionScale*(1.0-(dragGradientRange.x+(dragGradientRange.y-dragGradientRange.x)*seed.x));\n#endif\nlet position : vec3<f32>=particlesIn.particles[index].position;\n#if defined(CUSTOMEMITTER)\nparticlesOut.particles[index].position=position+(direction-position)*ageGradient; \nparticlesOut.particles[index].initialPosition=particlesIn.particles[index].initialPosition;\n#else\nparticlesOut.particles[index].position=position+direction*directionScale;\n#endif\nparticlesOut.particles[index].life=life;particlesOut.particles[index].seed=seed;\n#ifndef COLORGRADIENTS \nparticlesOut.particles[index].color=particlesIn.particles[index].color;\n#endif\n#ifdef SIZEGRADIENTS\nlet sizeGradientRange=textureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;particlesOut.particles[index].size=vec3<f32>(\nsizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y,\nparticlesIn.particles[index].size.yz);\n#else\nparticlesOut.particles[index].size=particlesIn.particles[index].size;\n#endif \n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=particlesIn.particles[index].initialDirection;\n#endif\n#ifdef CUSTOMEMITTER\nparticlesOut.particles[index].direction=direction;\n#else\nvar updatedDirection : vec3<f32>=direction+params.gravity*timeDelta;\n#ifdef FLOWMAP\nvar clipSpace=(params.flowMapProjection*vec4f(position,1.));var ndcSpace=clipSpace.xyz/clipSpace.w;var flowMapUV=ndcSpace.xy*0.5+0.5;var flowMapValue=textureSampleLevel(flowMapTexture,flowMapSampler,flowMapUV,0.);var flowMapDirection=(flowMapValue.xyz*2.0-1.0)*flowMapValue.w;updatedDirection+=flowMapDirection*timeDelta*params.flowMapStrength;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\nlet limitVelocityRange=textureSampleLevel(limitVelocityGradientTexture,limitVelocityGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;let limitVelocity : f32=limitVelocityRange.x+(limitVelocityRange.y-limitVelocityRange.x)*seed.y;let currentVelocity : f32=length(updatedDirection);if (currentVelocity>limitVelocity) {updatedDirection=updatedDirection*params.limitVelocityDamping;}\n#endif\n#ifdef ATTRACTORS\n{for (var i : i32=0; i<params.attractorCount; i=i+1) {let toAttractor : vec3<f32>=params.attractorPositionAndStrength[i].xyz-position;let distSq : f32=dot(toAttractor,toAttractor)+1.0;updatedDirection=updatedDirection+(params.attractorPositionAndStrength[i].w/distSq)*normalize(toAttractor)*timeDelta;}}\n#endif\nparticlesOut.particles[index].direction=updatedDirection;\n#ifdef NOISE\nlet noiseCoordinates1 : vec3<f32>=particlesIn.particles[index].noiseCoordinates1;let noiseCoordinates2 : vec3<f32>=particlesIn.particles[index].noiseCoordinates2;let fetchedR : f32=textureSampleLevel(noiseTexture,noiseSampler,vec2<f32>(noiseCoordinates1.x,noiseCoordinates1.y)*vec2<f32>(0.5,0.5)+vec2<f32>(0.5,0.5),0.).r;let fetchedG : f32=textureSampleLevel(noiseTexture,noiseSampler,vec2<f32>(noiseCoordinates1.z,noiseCoordinates2.x)*vec2<f32>(0.5,0.5)+vec2<f32>(0.5,0.5),0.).r;let fetchedB : f32=textureSampleLevel(noiseTexture,noiseSampler,vec2<f32>(noiseCoordinates2.y,noiseCoordinates2.z)*vec2<f32>(0.5,0.5)+vec2<f32>(0.5,0.5),0.).r;let force : vec3<f32>=vec3<f32>(-1.+2.*fetchedR,-1.+2.*fetchedG,-1.+2.*fetchedB)*params.noiseStrength;particlesOut.particles[index].direction=particlesOut.particles[index].direction+force*timeDelta;particlesOut.particles[index].noiseCoordinates1=noiseCoordinates1;particlesOut.particles[index].noiseCoordinates2=noiseCoordinates2;\n#endif \n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nlet angularSpeedRange=textureSampleLevel(angularSpeedGradientTexture,angularSpeedGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;let angularSpeed : f32=angularSpeedRange.x+(angularSpeedRange.y-angularSpeedRange.x)*seed.z;particlesOut.particles[index].angle=particlesIn.particles[index].angle+angularSpeed*timeDelta;\n#else\nlet angle : vec2<f32>=particlesIn.particles[index].angle;particlesOut.particles[index].angle=vec2<f32>(angle.x+angle.y*timeDelta,angle.y);\n#endif\n#ifdef ANIMATESHEET \nvar offsetAge : f32=particlesOut.particles[index].age;let dist : f32=params.cellInfos.y-params.cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\nlet cellStartOffset : f32=particlesIn.particles[index].cellStartOffset;particlesOut.particles[index].cellStartOffset=cellStartOffset;offsetAge=offsetAge+cellStartOffset;\n#else\nlet cellStartOffset : f32=0.;\n#endif \nvar ratio : f32;if (params.cellInfos.w==1.0) {ratio=clamp(((cellStartOffset+params.cellInfos.z*offsetAge) % life)/life,0.,1.0);}\nelse {ratio=clamp((cellStartOffset+params.cellInfos.z*offsetAge)/life,0.,1.0);}\nparticlesOut.particles[index].cellIndex=f32(i32(params.cellInfos.x+ratio*dist));\n#endif\n}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const gpuUpdateParticlesComputeShaderWGSL = { name, shader };\n"]}
|
|
1
|
+
{"version":3,"file":"gpuUpdateParticles.compute.js","sourceRoot":"","sources":["../../../../dev/core/src/ShadersWGSL/gpuUpdateParticles.compute.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,MAAM,IAAI,GAAG,iCAAiC,CAAC;AAC/C,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuVd,CAAC;AACF,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;IACtC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAChD,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,mCAAmC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gpuUpdateParticlesComputeShader\";\nconst shader = `struct Particle {position : vec3<f32>,\nage : f32,\nsize : vec3<f32>,\nlife : f32,\nseed : vec4<f32>,\ndirection : vec3<f32>,\ndummy0: f32,\n#ifdef CUSTOMEMITTER\ninitialPosition : vec3<f32>,\ndummy1: f32,\n#endif\n#ifndef COLORGRADIENTS\ncolor : vec4<f32>,\n#endif\n#ifndef BILLBOARD\ninitialDirection : vec3<f32>,\ndummy2: f32,\n#endif\n#ifdef NOISE\nnoiseCoordinates1 : vec3<f32>,\ndummy3: f32,\nnoiseCoordinates2 : vec3<f32>,\ndummy4: f32,\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nangle : f32,\n#else\nangle : vec2<f32>,\n#endif\n#ifdef ANIMATESHEET\ncellIndex : f32,\n#ifdef ANIMATESHEETRANDOMSTART\ncellStartOffset : f32,\n#endif\n#endif\n};struct Particles {particles : array<Particle>,};struct SimParams {currentCount : f32,\ntimeDelta : f32,\nstopFactor : f32,\nrandomTextureSize: i32,\nlifeTime : vec2<f32>,\nemitPower : vec2<f32>,\nemitIndex : f32,\nemitCount : f32,\n#ifndef COLORGRADIENTS\ncolor1 : vec4<f32>,\ncolor2 : vec4<f32>,\n#endif\nsizeRange : vec2<f32>,\nscaleRange : vec4<f32>,\nangleRange : vec4<f32>,\ngravity : vec3<f32>,\n#ifdef LIMITVELOCITYGRADIENTS\nlimitVelocityDamping : f32,\n#endif\n#ifdef ANIMATESHEET\ncellInfos : vec4<f32>,\n#endif\n#ifdef NOISE\nnoiseStrength : vec3<f32>,\n#endif\n#ifdef FLOWMAP\nflowMapProjection : mat4x4<f32>,\nflowMapStrength : f32,\n#endif\n#ifndef LOCAL\nemitterWM : mat4x4<f32>,\n#endif\n#ifdef ATTRACTORS\nattractorCount : i32,\nattractorPositionAndStrength : array<vec4<f32>,MAX_ATTRACTORS>,\n#endif\n#ifdef STARTSIZEGRADIENTS\nstartSizeGradientFactor : f32,\n#endif\n#ifdef LIFETIMEGRADIENTS\nlifeTimeGradientRange : vec2<f32>,\n#endif\n#ifdef MESHEMITTER\nmeshTriangleCount : i32,\nmeshTextureWidth : i32,\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#endif\n#ifdef BOXEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\nminEmitBox : vec3<f32>,\nmaxEmitBox : vec3<f32>,\n#endif\n#ifdef CONEEMITTER\nradius : vec2<f32>,\nconeAngle : f32,\nheight : vec2<f32>,\n#ifdef DIRECTEDCONEEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#else\ndirectionRandomizer : f32,\n#endif\n#endif\n#ifdef CYLINDEREMITTER\nradius : f32,\nheight : f32,\nradiusRange : f32,\n#ifdef DIRECTEDCYLINDEREMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#else\ndirectionRandomizer : f32,\n#endif\n#endif\n#ifdef HEMISPHERICEMITTER\nradius : f32,\nradiusRange : f32,\ndirectionRandomizer : f32,\n#endif\n#ifdef POINTEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#endif\n#ifdef SPHEREEMITTER\nradius : f32,\nradiusRange : f32,\n#ifdef DIRECTEDSPHEREEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#else\ndirectionRandomizer : f32,\n#endif\n#endif\n};@binding(0) @group(0) var<uniform> params : SimParams;@binding(1) @group(0) var<storage,read> particlesIn : Particles;@binding(2) @group(0) var<storage,read_write> particlesOut : Particles;@binding(3) @group(0) var randomTexture : texture_2d<f32>;@binding(4) @group(0) var randomTexture2 : texture_2d<f32>;\n#ifdef SIZEGRADIENTS\n@binding(0) @group(1) var sizeGradientSampler : sampler;@binding(1) @group(1) var sizeGradientTexture : texture_2d<f32>;\n#endif \n#ifdef ANGULARSPEEDGRADIENTS\n@binding(2) @group(1) var angularSpeedGradientSampler : sampler;@binding(3) @group(1) var angularSpeedGradientTexture : texture_2d<f32>;\n#endif \n#ifdef VELOCITYGRADIENTS\n@binding(4) @group(1) var velocityGradientSampler : sampler;@binding(5) @group(1) var velocityGradientTexture : texture_2d<f32>;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\n@binding(6) @group(1) var limitVelocityGradientSampler : sampler;@binding(7) @group(1) var limitVelocityGradientTexture : texture_2d<f32>;\n#endif\n#ifdef DRAGGRADIENTS\n@binding(8) @group(1) var dragGradientSampler : sampler;@binding(9) @group(1) var dragGradientTexture : texture_2d<f32>;\n#endif\n#ifdef NOISE\n@binding(10) @group(1) var noiseSampler : sampler;@binding(11) @group(1) var noiseTexture : texture_2d<f32>;\n#endif\n#ifdef FLOWMAP\n@binding(12) @group(1) var flowMapSampler : sampler;@binding(13) @group(1) var flowMapTexture : texture_2d<f32>;\n#endif\n#ifdef MESHEMITTER\n@binding(14) @group(1) var meshPositionTexture : texture_2d<f32>;\n#ifdef MESHNORMALS\n@binding(15) @group(1) var meshNormalTexture : texture_2d<f32>;\n#endif\n#endif\nfn getRandomVec3(offset : f32,vertexID : f32)->vec3<f32> {return textureLoad(randomTexture2,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0).rgb;}\nfn getRandomVec4(offset : f32,vertexID : f32)->vec4<f32> {return textureLoad(randomTexture,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0);}\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {let index : u32=GlobalInvocationID.x;let vertexID : f32=f32(index);if (index>=u32(params.currentCount)) {return;}\nlet PI : f32=3.14159;let timeDelta : f32=params.timeDelta;let newAge : f32=particlesIn.particles[index].age+timeDelta;let life : f32=particlesIn.particles[index].life;let seed : vec4<f32>=particlesIn.particles[index].seed;let direction : vec3<f32>=particlesIn.particles[index].direction;\n#ifdef EMITRATECTRL\nvar offsetFromEmitIndex : f32=vertexID-params.emitIndex;if (offsetFromEmitIndex<0.0) {offsetFromEmitIndex+=params.currentCount; }\nlet shouldEmit : bool=offsetFromEmitIndex<params.emitCount && params.stopFactor != 0.;\n#else\nlet shouldEmit : bool=newAge>=life && params.stopFactor != 0.;\n#endif\nif (shouldEmit) {var newPosition : vec3<f32>;var newDirection : vec3<f32>;let randoms : vec4<f32>=getRandomVec4(seed.x,vertexID);let outLife : f32=params.lifeTime.x+(params.lifeTime.y-params.lifeTime.x)*randoms.r;\n#ifdef LIFETIMEGRADIENTS\nparticlesOut.particles[index].life=params.lifeTimeGradientRange.x+(params.lifeTimeGradientRange.y-params.lifeTimeGradientRange.x)*randoms.r;\n#else\nparticlesOut.particles[index].life=outLife;\n#endif\n#ifdef EMITRATECTRL\nparticlesOut.particles[index].age=0.0;\n#else\nparticlesOut.particles[index].age=newAge-life;\n#endif\nparticlesOut.particles[index].seed=seed;var sizex : f32;\n#ifdef SIZEGRADIENTS \nlet sizeGradientRange=textureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(0.,0.),0.).rg;sizex=sizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y;\n#else\nsizex=params.sizeRange.x+(params.sizeRange.y-params.sizeRange.x)*randoms.g;\n#endif\n#ifdef STARTSIZEGRADIENTS\nsizex*=params.startSizeGradientFactor;\n#endif\nparticlesOut.particles[index].size=vec3<f32>(\nsizex,\nparams.scaleRange.x+(params.scaleRange.y-params.scaleRange.x)*randoms.b,\nparams.scaleRange.z+(params.scaleRange.w-params.scaleRange.z)*randoms.a);\n#ifndef COLORGRADIENTS\nparticlesOut.particles[index].color=params.color1+(params.color2-params.color1)*randoms.b;\n#endif\n#ifndef ANGULARSPEEDGRADIENTS \nparticlesOut.particles[index].angle=vec2<f32>(\nparams.angleRange.z+(params.angleRange.w-params.angleRange.z)*randoms.r,\nparams.angleRange.x+(params.angleRange.y-params.angleRange.x)*randoms.a);\n#else\nparticlesOut.particles[index].angle=params.angleRange.z+(params.angleRange.w-params.angleRange.z)*randoms.r;\n#endif \n#if defined(POINTEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);newPosition=vec3<f32>(0.,0.,0.);newDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#elif defined(BOXEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);newPosition=params.minEmitBox+(params.maxEmitBox-params.minEmitBox)*randoms2;newDirection=params.direction1+(params.direction2-params.direction1)*randoms3; \n#elif defined(HEMISPHERICEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);let phi : f32=2.0*PI*randoms2.x;let theta : f32=acos(-1.0+2.0*randoms2.y);let randX : f32=cos(phi)*sin(theta);let randY : f32=cos(theta);let randZ : f32=sin(phi)*sin(theta);newPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,abs(randY),randZ);newDirection=normalize(newPosition+params.directionRandomizer*randoms3);\n#elif defined(SPHEREEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);let phi : f32=2.0*PI*randoms2.x;let theta : f32=acos(-1.0+2.0*randoms2.y);let randX : f32=cos(phi)*sin(theta);let randY : f32=cos(theta);let randZ : f32=sin(phi)*sin(theta);newPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,randY,randZ);\n#ifdef DIRECTEDSPHEREEMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#else\nnewDirection=normalize(newPosition+params.directionRandomizer*randoms3);\n#endif\n#elif defined(CYLINDEREMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);let yPos : f32=(-0.5+randoms2.x)*params.height;var angle : f32=randoms2.y*PI*2.;let inverseRadiusRangeSquared : f32=(1.-params.radiusRange)*(1.-params.radiusRange);let positionRadius : f32=params.radius*sqrt(inverseRadiusRangeSquared+randoms2.z*(1.-inverseRadiusRangeSquared));let xPos : f32=positionRadius*cos(angle);let zPos : f32=positionRadius*sin(angle);newPosition=vec3<f32>(xPos,yPos,zPos);\n#ifdef DIRECTEDCYLINDEREMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#else\nangle=angle+(-0.5+randoms3.x)*PI*params.directionRandomizer;newDirection=vec3<f32>(cos(angle),(-0.5+randoms3.y)*params.directionRandomizer,sin(angle));newDirection=normalize(newDirection);\n#endif\n#elif defined(CONEEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let s : f32=2.0*PI*randoms2.x;\n#ifdef CONEEMITTERSPAWNPOINT\nlet h : f32=0.0001;\n#else\nvar h : f32=randoms2.y*params.height.y;h=1.-h*h; \n#endif\nvar lRadius : f32=params.radius.x-params.radius.x*randoms2.z*params.radius.y;lRadius=lRadius*h;let randX : f32=lRadius*sin(s);let randZ : f32=lRadius*cos(s);let randY : f32=h *params.height.x;newPosition=vec3<f32>(randX,randY,randZ); \nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\n#ifdef DIRECTEDCONEEMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#else\nif (abs(cos(params.coneAngle))==1.0) {newDirection=vec3<f32>(0.,1.0,0.);} else {newDirection=normalize(newPosition+params.directionRandomizer*randoms3); }\n#endif\n#elif defined(MESHEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);var triIdx : i32=i32(floor(randoms2.x*f32(params.meshTriangleCount)));triIdx=min(triIdx,params.meshTriangleCount-1);let baseTexel : i32=triIdx*3;let t0 : i32=baseTexel;let t1 : i32=baseTexel+1;let t2 : i32=baseTexel+2;let v0 : vec3<f32>=textureLoad(meshPositionTexture,vec2<i32>(t0 % params.meshTextureWidth,t0/params.meshTextureWidth),0).xyz;let v1 : vec3<f32>=textureLoad(meshPositionTexture,vec2<i32>(t1 % params.meshTextureWidth,t1/params.meshTextureWidth),0).xyz;let v2 : vec3<f32>=textureLoad(meshPositionTexture,vec2<i32>(t2 % params.meshTextureWidth,t2/params.meshTextureWidth),0).xyz;let bu : f32=randoms2.y;let bv : f32=randoms2.z*(1.0-bu);let bw : f32=1.0-bu-bv;newPosition=bu*v0+bv*v1+bw*v2;\n#ifdef MESHNORMALS\nlet n0 : vec3<f32>=textureLoad(meshNormalTexture,vec2<i32>(t0 % params.meshTextureWidth,t0/params.meshTextureWidth),0).xyz;let n1 : vec3<f32>=textureLoad(meshNormalTexture,vec2<i32>(t1 % params.meshTextureWidth,t1/params.meshTextureWidth),0).xyz;let n2 : vec3<f32>=textureLoad(meshNormalTexture,vec2<i32>(t2 % params.meshTextureWidth,t2/params.meshTextureWidth),0).xyz;newDirection=normalize(bu*n0+bv*n1+bw*n2);\n#else\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#endif\n#elif defined(CUSTOMEMITTER)\nnewPosition=particlesIn.particles[index].initialPosition;particlesOut.particles[index].initialPosition=newPosition;\n#else \nnewPosition=vec3<f32>(0.,0.,0.);newDirection=2.0*(getRandomVec3(seed.w,vertexID)-vec3<f32>(0.5,0.5,0.5));\n#endif\nlet power : f32=params.emitPower.x+(params.emitPower.y-params.emitPower.x)*randoms.a;\n#ifdef LOCAL\nparticlesOut.particles[index].position=newPosition;\n#else\nparticlesOut.particles[index].position=(params.emitterWM*vec4<f32>(newPosition,1.)).xyz;\n#endif\n#ifdef CUSTOMEMITTER\nparticlesOut.particles[index].direction=direction;\n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=direction;\n#endif\n#else\n#ifdef LOCAL\nlet initial : vec3<f32>=newDirection;\n#else \nlet initial : vec3<f32>=(params.emitterWM*vec4<f32>(newDirection,0.)).xyz;\n#endif\nparticlesOut.particles[index].direction=initial*power;\n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=initial;\n#endif\n#endif\n#ifdef ANIMATESHEET \nparticlesOut.particles[index].cellIndex=params.cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\nparticlesOut.particles[index].cellStartOffset=randoms.a*outLife;\n#endif \n#endif\n#ifdef NOISE\nparticlesOut.particles[index].noiseCoordinates1=particlesIn.particles[index].noiseCoordinates1;particlesOut.particles[index].noiseCoordinates2=particlesIn.particles[index].noiseCoordinates2;\n#endif\n} else {var directionScale : f32=timeDelta;particlesOut.particles[index].age=newAge;let ageGradient : f32=newAge/life;\n#ifdef VELOCITYGRADIENTS\nlet velocityGradientRange=textureSampleLevel(velocityGradientTexture,velocityGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;directionScale=directionScale*(velocityGradientRange.x+(velocityGradientRange.y-velocityGradientRange.x)*seed.w);\n#endif\n#ifdef DRAGGRADIENTS\nlet dragGradientRange=textureSampleLevel(dragGradientTexture,dragGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;directionScale=directionScale*(1.0-(dragGradientRange.x+(dragGradientRange.y-dragGradientRange.x)*seed.x));\n#endif\nlet position : vec3<f32>=particlesIn.particles[index].position;\n#if defined(CUSTOMEMITTER)\nparticlesOut.particles[index].position=position+(direction-position)*ageGradient; \nparticlesOut.particles[index].initialPosition=particlesIn.particles[index].initialPosition;\n#else\nparticlesOut.particles[index].position=position+direction*directionScale;\n#endif\nparticlesOut.particles[index].life=life;particlesOut.particles[index].seed=seed;\n#ifndef COLORGRADIENTS \nparticlesOut.particles[index].color=particlesIn.particles[index].color;\n#endif\n#ifdef SIZEGRADIENTS\nlet sizeGradientRange=textureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;particlesOut.particles[index].size=vec3<f32>(\nsizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y,\nparticlesIn.particles[index].size.yz);\n#else\nparticlesOut.particles[index].size=particlesIn.particles[index].size;\n#endif \n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=particlesIn.particles[index].initialDirection;\n#endif\n#ifdef CUSTOMEMITTER\nparticlesOut.particles[index].direction=direction;\n#else\nvar updatedDirection : vec3<f32>=direction+params.gravity*timeDelta;\n#ifdef FLOWMAP\nvar clipSpace=(params.flowMapProjection*vec4f(position,1.));var ndcSpace=clipSpace.xyz/clipSpace.w;var flowMapUV=ndcSpace.xy*0.5+0.5;var flowMapValue=textureSampleLevel(flowMapTexture,flowMapSampler,flowMapUV,0.);var flowMapDirection=(flowMapValue.xyz*2.0-1.0)*flowMapValue.w;updatedDirection+=flowMapDirection*timeDelta*params.flowMapStrength;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\nlet limitVelocityRange=textureSampleLevel(limitVelocityGradientTexture,limitVelocityGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;let limitVelocity : f32=limitVelocityRange.x+(limitVelocityRange.y-limitVelocityRange.x)*seed.y;let currentVelocity : f32=length(updatedDirection);if (currentVelocity>limitVelocity) {updatedDirection=updatedDirection*params.limitVelocityDamping;}\n#endif\n#ifdef ATTRACTORS\n{for (var i : i32=0; i<params.attractorCount; i=i+1) {let toAttractor : vec3<f32>=params.attractorPositionAndStrength[i].xyz-position;let distSq : f32=dot(toAttractor,toAttractor)+1.0;updatedDirection=updatedDirection+(params.attractorPositionAndStrength[i].w/distSq)*normalize(toAttractor)*timeDelta;}}\n#endif\nparticlesOut.particles[index].direction=updatedDirection;\n#ifdef NOISE\nlet noiseCoordinates1 : vec3<f32>=particlesIn.particles[index].noiseCoordinates1;let noiseCoordinates2 : vec3<f32>=particlesIn.particles[index].noiseCoordinates2;let fetchedR : f32=textureSampleLevel(noiseTexture,noiseSampler,vec2<f32>(noiseCoordinates1.x,noiseCoordinates1.y)*vec2<f32>(0.5,0.5)+vec2<f32>(0.5,0.5),0.).r;let fetchedG : f32=textureSampleLevel(noiseTexture,noiseSampler,vec2<f32>(noiseCoordinates1.z,noiseCoordinates2.x)*vec2<f32>(0.5,0.5)+vec2<f32>(0.5,0.5),0.).r;let fetchedB : f32=textureSampleLevel(noiseTexture,noiseSampler,vec2<f32>(noiseCoordinates2.y,noiseCoordinates2.z)*vec2<f32>(0.5,0.5)+vec2<f32>(0.5,0.5),0.).r;let force : vec3<f32>=vec3<f32>(-1.+2.*fetchedR,-1.+2.*fetchedG,-1.+2.*fetchedB)*params.noiseStrength;particlesOut.particles[index].direction=particlesOut.particles[index].direction+force*timeDelta;particlesOut.particles[index].noiseCoordinates1=noiseCoordinates1;particlesOut.particles[index].noiseCoordinates2=noiseCoordinates2;\n#endif \n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nlet angularSpeedRange=textureSampleLevel(angularSpeedGradientTexture,angularSpeedGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;let angularSpeed : f32=angularSpeedRange.x+(angularSpeedRange.y-angularSpeedRange.x)*seed.z;particlesOut.particles[index].angle=particlesIn.particles[index].angle+angularSpeed*timeDelta;\n#else\nlet angle : vec2<f32>=particlesIn.particles[index].angle;particlesOut.particles[index].angle=vec2<f32>(angle.x+angle.y*timeDelta,angle.y);\n#endif\n#ifdef ANIMATESHEET \nvar offsetAge : f32=particlesOut.particles[index].age;let dist : f32=params.cellInfos.y-params.cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\nlet cellStartOffset : f32=particlesIn.particles[index].cellStartOffset;particlesOut.particles[index].cellStartOffset=cellStartOffset;offsetAge=offsetAge+cellStartOffset;\n#else\nlet cellStartOffset : f32=0.;\n#endif \nvar ratio : f32;if (params.cellInfos.w==1.0) {ratio=clamp(((cellStartOffset+params.cellInfos.z*offsetAge) % life)/life,0.,1.0);}\nelse {ratio=clamp((cellStartOffset+params.cellInfos.z*offsetAge)/life,0.,1.0);}\nparticlesOut.particles[index].cellIndex=f32(i32(params.cellInfos.x+ratio*dist));\n#endif\n}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const gpuUpdateParticlesComputeShaderWGSL = { name, shader };\n"]}
|