@babylonjs/core 5.0.0 → 5.0.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/Collisions/collider.d.ts +4 -0
- package/Collisions/collider.js +9 -0
- package/Collisions/collider.js.map +1 -1
- package/Engines/WebGPU/webgpuShaderProcessorsWGSL.d.ts +2 -0
- package/Engines/WebGPU/webgpuShaderProcessorsWGSL.js +25 -10
- package/Engines/WebGPU/webgpuShaderProcessorsWGSL.js.map +1 -1
- package/Engines/nullEngine.d.ts +1 -0
- package/Engines/nullEngine.js +5 -0
- package/Engines/nullEngine.js.map +1 -1
- package/Engines/thinEngine.js +2 -2
- package/Engines/thinEngine.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/meshUboDeclaration.js +1 -1
- package/ShadersWGSL/ShadersInclude/meshUboDeclaration.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/sceneUboDeclaration.js +1 -1
- package/ShadersWGSL/ShadersInclude/sceneUboDeclaration.js.map +1 -1
- package/ShadersWGSL/gpuUpdateParticles.compute.js +1 -1
- package/ShadersWGSL/gpuUpdateParticles.compute.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Do not edit.
|
|
2
2
|
import { ShaderStore } from "../../Engines/shaderStore.js";
|
|
3
3
|
var name = "meshUboDeclaration";
|
|
4
|
-
var shader = "struct Mesh {\nworld : mat4x4<f32
|
|
4
|
+
var shader = "struct Mesh {\nworld : mat4x4<f32>,\nvisibility : f32,\n};\nvar<uniform> mesh : Mesh;\n#define WORLD_UBO\n";
|
|
5
5
|
// Sideeffect
|
|
6
6
|
ShaderStore.IncludesShadersStoreWGSL[name] = shader;
|
|
7
7
|
/** @hidden */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meshUboDeclaration.js","sourceRoot":"","sources":["../../../../../../lts/core/generated/ShadersWGSL/ShadersInclude/meshUboDeclaration.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,IAAM,IAAI,GAAG,oBAAoB,CAAC;AAClC,IAAM,MAAM,GAAG,4GAMd,CAAC;AACF,aAAa;AACb,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AACpD,cAAc;AACd,MAAM,CAAC,IAAM,kBAAkB,GAAG,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\n\nconst name = \"meshUboDeclaration\";\nconst shader = `struct Mesh {\rworld : mat4x4<f32
|
|
1
|
+
{"version":3,"file":"meshUboDeclaration.js","sourceRoot":"","sources":["../../../../../../lts/core/generated/ShadersWGSL/ShadersInclude/meshUboDeclaration.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,IAAM,IAAI,GAAG,oBAAoB,CAAC;AAClC,IAAM,MAAM,GAAG,4GAMd,CAAC;AACF,aAAa;AACb,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AACpD,cAAc;AACd,MAAM,CAAC,IAAM,kBAAkB,GAAG,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\n\nconst name = \"meshUboDeclaration\";\nconst shader = `struct Mesh {\rworld : mat4x4<f32>,\rvisibility : f32,\r};\rvar<uniform> mesh : Mesh;\r#define WORLD_UBO\n`;\n// Sideeffect\nShaderStore.IncludesShadersStoreWGSL[name] = shader;\n/** @hidden */\nexport const meshUboDeclaration = { name, shader };\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Do not edit.
|
|
2
2
|
import { ShaderStore } from "../../Engines/shaderStore.js";
|
|
3
3
|
var name = "sceneUboDeclaration";
|
|
4
|
-
var shader = "struct Scene {\nviewProjection : mat4x4<f32
|
|
4
|
+
var shader = "struct Scene {\nviewProjection : mat4x4<f32>,\n#ifdef MULTIVIEW\nviewProjectionR : mat4x4<f32>,\n#endif \nview : mat4x4<f32>,\nprojection : mat4x4<f32>,\nvEyePosition : vec4<f32>,\n};\nvar<uniform> scene : Scene;\n";
|
|
5
5
|
// Sideeffect
|
|
6
6
|
ShaderStore.IncludesShadersStoreWGSL[name] = shader;
|
|
7
7
|
/** @hidden */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sceneUboDeclaration.js","sourceRoot":"","sources":["../../../../../../lts/core/generated/ShadersWGSL/ShadersInclude/sceneUboDeclaration.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,IAAM,IAAI,GAAG,qBAAqB,CAAC;AACnC,IAAM,MAAM,GAAG,wNAUd,CAAC;AACF,aAAa;AACb,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AACpD,cAAc;AACd,MAAM,CAAC,IAAM,mBAAmB,GAAG,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\n\nconst name = \"sceneUboDeclaration\";\nconst shader = `struct Scene {\rviewProjection : mat4x4<f32
|
|
1
|
+
{"version":3,"file":"sceneUboDeclaration.js","sourceRoot":"","sources":["../../../../../../lts/core/generated/ShadersWGSL/ShadersInclude/sceneUboDeclaration.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,IAAM,IAAI,GAAG,qBAAqB,CAAC;AACnC,IAAM,MAAM,GAAG,wNAUd,CAAC;AACF,aAAa;AACb,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AACpD,cAAc;AACd,MAAM,CAAC,IAAM,mBAAmB,GAAG,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\n\nconst name = \"sceneUboDeclaration\";\nconst shader = `struct Scene {\rviewProjection : mat4x4<f32>,\r#ifdef MULTIVIEW\nviewProjectionR : mat4x4<f32>,\r#endif \nview : mat4x4<f32>,\rprojection : mat4x4<f32>,\rvEyePosition : vec4<f32>,\r};\rvar<uniform> scene : Scene;\r`;\n// Sideeffect\nShaderStore.IncludesShadersStoreWGSL[name] = shader;\n/** @hidden */\nexport const sceneUboDeclaration = { name, shader };\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Do not edit.
|
|
2
2
|
import { ShaderStore } from "../Engines/shaderStore.js";
|
|
3
3
|
var name = "gpuUpdateParticlesComputeShader";
|
|
4
|
-
var shader = "struct Particle {\nposition : 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};\nstruct Particles {\nparticles : array<Particle>;\n};\nstruct SimParams {\ncurrentCount : f32;\ntimeDelta : f32;\nstopFactor : f32;\nrandomTextureSize: i32;\nlifeTime : vec2<f32>;\nemitPower : vec2<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#ifndef LOCAL\nemitterWM : mat4x4<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>;\ndirectionRandomizer : f32;\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};\n@binding(0) @group(0) var<uniform> params : SimParams;\n@binding(1) @group(0) var<storage,read> particlesIn : Particles;\n@binding(2) @group(0) var<storage,read_write> particlesOut : Particles;\n@binding(3) @group(0) var randomTexture : texture_2d<f32>;\n@binding(4) @group(0) var randomTexture2 : texture_2d<f32>;\n#ifdef SIZEGRADIENTS\n@binding(0) @group(1) var sizeGradientSampler : sampler;\n@binding(1) @group(1) var sizeGradientTexture : texture_2d<f32>;\n#endif \n#ifdef ANGULARSPEEDGRADIENTS\n@binding(2) @group(1) var angularSpeedGradientSampler : sampler;\n@binding(3) @group(1) var angularSpeedGradientTexture : texture_2d<f32>;\n#endif \n#ifdef VELOCITYGRADIENTS\n@binding(4) @group(1) var velocityGradientSampler : sampler;\n@binding(5) @group(1) var velocityGradientTexture : texture_2d<f32>;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\n@binding(6) @group(1) var limitVelocityGradientSampler : sampler;\n@binding(7) @group(1) var limitVelocityGradientTexture : texture_2d<f32>;\n#endif\n#ifdef DRAGGRADIENTS\n@binding(8) @group(1) var dragGradientSampler : sampler;\n@binding(9) @group(1) var dragGradientTexture : texture_2d<f32>;\n#endif\n#ifdef NOISE\n@binding(10) @group(1) var noiseSampler : sampler;\n@binding(11) @group(1) var noiseTexture : texture_2d<f32>;\n#endif\nfn getRandomVec3(offset : f32,vertexID : f32)->vec3<f32> {\nreturn textureLoad(randomTexture2,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0).rgb;\n}\nfn getRandomVec4(offset : f32,vertexID : f32)->vec4<f32> {\nreturn textureLoad(randomTexture,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0);\n}\n@stage(compute) @workgroup_size(64)\nfn main(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {\nlet index : u32=GlobalInvocationID.x;\nlet vertexID : f32=f32(index);\nif (index>=u32(params.currentCount)) {\nreturn;\n}\nlet PI : f32=3.14159;\nlet timeDelta : f32=params.timeDelta;\nlet newAge : f32=particlesIn.particles[index].age+timeDelta;\nlet life : f32=particlesIn.particles[index].life;\nlet seed : vec4<f32>=particlesIn.particles[index].seed;\nlet direction : vec3<f32>=particlesIn.particles[index].direction;\nif (newAge>=life && params.stopFactor != 0.) {\nvar newPosition : vec3<f32>;\nvar newDirection : vec3<f32>;\nlet randoms : vec4<f32>=getRandomVec4(seed.x,vertexID);\nlet outLife : f32=params.lifeTime.x+(params.lifeTime.y-params.lifeTime.x)*randoms.r;\nparticlesOut.particles[index].life=outLife;\nparticlesOut.particles[index].age=newAge-life;\nparticlesOut.particles[index].seed=seed;\nvar sizex : f32;\n#ifdef SIZEGRADIENTS \nsizex=textureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(0.,0.),0.).r;\n#else\nsizex=params.sizeRange.x+(params.sizeRange.y-params.sizeRange.x)*randoms.g;\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);\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nnewPosition=vec3<f32>(0.,0.,0.);\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#elif defined(BOXEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nnewPosition=params.minEmitBox+(params.maxEmitBox-params.minEmitBox)*randoms2;\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3; \n#elif defined(HEMISPHERICEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nlet phi : f32=2.0*PI*randoms2.x;\nlet theta : f32=acos(-1.0+2.0*randoms2.y);\nlet randX : f32=cos(phi)*sin(theta);\nlet randY : f32=cos(theta);\nlet randZ : f32=sin(phi)*sin(theta);\nnewPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,abs(randY),randZ);\nnewDirection=normalize(newPosition+params.directionRandomizer*randoms3);\n#elif defined(SPHEREEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nlet phi : f32=2.0*PI*randoms2.x;\nlet theta : f32=acos(-1.0+2.0*randoms2.y);\nlet randX : f32=cos(phi)*sin(theta);\nlet randY : f32=cos(theta);\nlet randZ : f32=sin(phi)*sin(theta);\nnewPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,randY,randZ);\n#ifdef DIRECTEDSPHEREEMITTER\nnewDirection=normalize(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);\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nlet yPos : f32=(-0.5+randoms2.x)*params.height;\nvar angle : f32=randoms2.y*PI*2.;\nlet inverseRadiusRangeSquared : f32=(1.-params.radiusRange)*(1.-params.radiusRange);\nlet positionRadius : f32=params.radius*sqrt(inverseRadiusRangeSquared+randoms2.z*(1.-inverseRadiusRangeSquared));\nlet xPos : f32=positionRadius*cos(angle);\nlet zPos : f32=positionRadius*sin(angle);\nnewPosition=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;\nnewDirection=vec3<f32>(cos(angle),(-0.5+randoms3.y)*params.directionRandomizer,sin(angle));\nnewDirection=normalize(newDirection);\n#endif\n#elif defined(CONEEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\nlet 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;\nh=1.-h*h; \n#endif\nvar lRadius : f32=params.radius.x-params.radius.x*randoms2.z*params.radius.y;\nlRadius=lRadius*h;\nlet randX : f32=lRadius*sin(s);\nlet randZ : f32=lRadius*cos(s);\nlet randY : f32=h *params.height.x;\nnewPosition=vec3<f32>(randX,randY,randZ); \nif (abs(cos(params.coneAngle))==1.0) {\nnewDirection=vec3<f32>(0.,1.0,0.);\n} else {\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nnewDirection=normalize(newPosition+params.directionRandomizer*randoms3); \n}\n#elif defined(CUSTOMEMITTER)\nnewPosition=particlesIn.particles[index].initialPosition;\nparticlesOut.particles[index].initialPosition=newPosition;\n#else \nnewPosition=vec3<f32>(0.,0.,0.);\nnewDirection=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;\nparticlesOut.particles[index].noiseCoordinates2=particlesIn.particles[index].noiseCoordinates2;\n#endif\n} else {\nvar directionScale : f32=timeDelta;\nparticlesOut.particles[index].age=newAge;\nlet ageGradient : f32=newAge/life;\n#ifdef VELOCITYGRADIENTS\ndirectionScale=directionScale*textureSampleLevel(velocityGradientTexture,velocityGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\n#endif\n#ifdef DRAGGRADIENTS\ndirectionScale=directionScale*(1.0-textureSampleLevel(dragGradientTexture,dragGradientSampler,vec2<f32>(ageGradient,0.),0.).r);\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;\nparticlesOut.particles[index].seed=seed;\n#ifndef COLORGRADIENTS \nparticlesOut.particles[index].color=particlesIn.particles[index].color;\n#endif\n#ifdef SIZEGRADIENTS\nparticlesOut.particles[index].size=vec3<f32>(\ntextureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(ageGradient,0.),0.).r,\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 LIMITVELOCITYGRADIENTS\nlet limitVelocity : f32=textureSampleLevel(limitVelocityGradientTexture,limitVelocityGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\nlet currentVelocity : f32=length(updatedDirection);\nif (currentVelocity>limitVelocity) {\nupdatedDirection=updatedDirection*params.limitVelocityDamping;\n}\n#endif\nparticlesOut.particles[index].direction=updatedDirection;\n#ifdef NOISE\nlet noiseCoordinates1 : vec3<f32>=particlesIn.particles[index].noiseCoordinates1;\nlet noiseCoordinates2 : vec3<f32>=particlesIn.particles[index].noiseCoordinates2;\nlet 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;\nlet 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;\nlet 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;\nlet force : vec3<f32>=vec3<f32>(-1.+2.*fetchedR,-1.+2.*fetchedG,-1.+2.*fetchedB)*params.noiseStrength;\nparticlesOut.particles[index].direction=particlesOut.particles[index].direction+force*timeDelta;\nparticlesOut.particles[index].noiseCoordinates1=noiseCoordinates1;\nparticlesOut.particles[index].noiseCoordinates2=noiseCoordinates2;\n#endif \n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nlet angularSpeed : f32=textureSampleLevel(angularSpeedGradientTexture,angularSpeedGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\nparticlesOut.particles[index].angle=particlesIn.particles[index].angle+angularSpeed*timeDelta;\n#else\nlet angle : vec2<f32>=particlesIn.particles[index].angle;\nparticlesOut.particles[index].angle=vec2<f32>(angle.x+angle.y*timeDelta,angle.y);\n#endif\n#ifdef ANIMATESHEET \nvar offsetAge : f32=particlesOut.particles[index].age;\nlet dist : f32=params.cellInfos.y-params.cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\nlet cellStartOffset : f32=particlesIn.particles[index].cellStartOffset;\nparticlesOut.particles[index].cellStartOffset=cellStartOffset;\noffsetAge=offsetAge+cellStartOffset;\n#else\nlet cellStartOffset : f32=0.;\n#endif \nvar ratio : f32;\nif (params.cellInfos.w==1.0) {\nratio=clamp(((cellStartOffset+params.cellInfos.z*offsetAge) % life)/life,0.,1.0);\n}\nelse {\nratio=clamp((cellStartOffset+params.cellInfos.z*offsetAge)/life,0.,1.0);\n}\nparticlesOut.particles[index].cellIndex=f32(i32(params.cellInfos.x+ratio*dist));\n#endif\n}\n}\n";
|
|
4
|
+
var shader = "struct Particle {\nposition : 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};\nstruct Particles {\nparticles : array<Particle>,\n};\nstruct SimParams {\ncurrentCount : f32,\ntimeDelta : f32,\nstopFactor : f32,\nrandomTextureSize: i32,\nlifeTime : vec2<f32>,\nemitPower : vec2<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#ifndef LOCAL\nemitterWM : mat4x4<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>,\ndirectionRandomizer : f32,\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};\n@binding(0) @group(0) var<uniform> params : SimParams;\n@binding(1) @group(0) var<storage,read> particlesIn : Particles;\n@binding(2) @group(0) var<storage,read_write> particlesOut : Particles;\n@binding(3) @group(0) var randomTexture : texture_2d<f32>;\n@binding(4) @group(0) var randomTexture2 : texture_2d<f32>;\n#ifdef SIZEGRADIENTS\n@binding(0) @group(1) var sizeGradientSampler : sampler;\n@binding(1) @group(1) var sizeGradientTexture : texture_2d<f32>;\n#endif \n#ifdef ANGULARSPEEDGRADIENTS\n@binding(2) @group(1) var angularSpeedGradientSampler : sampler;\n@binding(3) @group(1) var angularSpeedGradientTexture : texture_2d<f32>;\n#endif \n#ifdef VELOCITYGRADIENTS\n@binding(4) @group(1) var velocityGradientSampler : sampler;\n@binding(5) @group(1) var velocityGradientTexture : texture_2d<f32>;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\n@binding(6) @group(1) var limitVelocityGradientSampler : sampler;\n@binding(7) @group(1) var limitVelocityGradientTexture : texture_2d<f32>;\n#endif\n#ifdef DRAGGRADIENTS\n@binding(8) @group(1) var dragGradientSampler : sampler;\n@binding(9) @group(1) var dragGradientTexture : texture_2d<f32>;\n#endif\n#ifdef NOISE\n@binding(10) @group(1) var noiseSampler : sampler;\n@binding(11) @group(1) var noiseTexture : texture_2d<f32>;\n#endif\nfn getRandomVec3(offset : f32,vertexID : f32)->vec3<f32> {\nreturn textureLoad(randomTexture2,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0).rgb;\n}\nfn getRandomVec4(offset : f32,vertexID : f32)->vec4<f32> {\nreturn textureLoad(randomTexture,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0);\n}\n@stage(compute) @workgroup_size(64)\nfn main(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {\nlet index : u32=GlobalInvocationID.x;\nlet vertexID : f32=f32(index);\nif (index>=u32(params.currentCount)) {\nreturn;\n}\nlet PI : f32=3.14159;\nlet timeDelta : f32=params.timeDelta;\nlet newAge : f32=particlesIn.particles[index].age+timeDelta;\nlet life : f32=particlesIn.particles[index].life;\nlet seed : vec4<f32>=particlesIn.particles[index].seed;\nlet direction : vec3<f32>=particlesIn.particles[index].direction;\nif (newAge>=life && params.stopFactor != 0.) {\nvar newPosition : vec3<f32>;\nvar newDirection : vec3<f32>;\nlet randoms : vec4<f32>=getRandomVec4(seed.x,vertexID);\nlet outLife : f32=params.lifeTime.x+(params.lifeTime.y-params.lifeTime.x)*randoms.r;\nparticlesOut.particles[index].life=outLife;\nparticlesOut.particles[index].age=newAge-life;\nparticlesOut.particles[index].seed=seed;\nvar sizex : f32;\n#ifdef SIZEGRADIENTS \nsizex=textureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(0.,0.),0.).r;\n#else\nsizex=params.sizeRange.x+(params.sizeRange.y-params.sizeRange.x)*randoms.g;\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);\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nnewPosition=vec3<f32>(0.,0.,0.);\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#elif defined(BOXEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nnewPosition=params.minEmitBox+(params.maxEmitBox-params.minEmitBox)*randoms2;\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3; \n#elif defined(HEMISPHERICEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nlet phi : f32=2.0*PI*randoms2.x;\nlet theta : f32=acos(-1.0+2.0*randoms2.y);\nlet randX : f32=cos(phi)*sin(theta);\nlet randY : f32=cos(theta);\nlet randZ : f32=sin(phi)*sin(theta);\nnewPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,abs(randY),randZ);\nnewDirection=normalize(newPosition+params.directionRandomizer*randoms3);\n#elif defined(SPHEREEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nlet phi : f32=2.0*PI*randoms2.x;\nlet theta : f32=acos(-1.0+2.0*randoms2.y);\nlet randX : f32=cos(phi)*sin(theta);\nlet randY : f32=cos(theta);\nlet randZ : f32=sin(phi)*sin(theta);\nnewPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,randY,randZ);\n#ifdef DIRECTEDSPHEREEMITTER\nnewDirection=normalize(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);\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nlet yPos : f32=(-0.5+randoms2.x)*params.height;\nvar angle : f32=randoms2.y*PI*2.;\nlet inverseRadiusRangeSquared : f32=(1.-params.radiusRange)*(1.-params.radiusRange);\nlet positionRadius : f32=params.radius*sqrt(inverseRadiusRangeSquared+randoms2.z*(1.-inverseRadiusRangeSquared));\nlet xPos : f32=positionRadius*cos(angle);\nlet zPos : f32=positionRadius*sin(angle);\nnewPosition=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;\nnewDirection=vec3<f32>(cos(angle),(-0.5+randoms3.y)*params.directionRandomizer,sin(angle));\nnewDirection=normalize(newDirection);\n#endif\n#elif defined(CONEEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\nlet 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;\nh=1.-h*h; \n#endif\nvar lRadius : f32=params.radius.x-params.radius.x*randoms2.z*params.radius.y;\nlRadius=lRadius*h;\nlet randX : f32=lRadius*sin(s);\nlet randZ : f32=lRadius*cos(s);\nlet randY : f32=h *params.height.x;\nnewPosition=vec3<f32>(randX,randY,randZ); \nif (abs(cos(params.coneAngle))==1.0) {\nnewDirection=vec3<f32>(0.,1.0,0.);\n} else {\nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\nnewDirection=normalize(newPosition+params.directionRandomizer*randoms3); \n}\n#elif defined(CUSTOMEMITTER)\nnewPosition=particlesIn.particles[index].initialPosition;\nparticlesOut.particles[index].initialPosition=newPosition;\n#else \nnewPosition=vec3<f32>(0.,0.,0.);\nnewDirection=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;\nparticlesOut.particles[index].noiseCoordinates2=particlesIn.particles[index].noiseCoordinates2;\n#endif\n} else {\nvar directionScale : f32=timeDelta;\nparticlesOut.particles[index].age=newAge;\nlet ageGradient : f32=newAge/life;\n#ifdef VELOCITYGRADIENTS\ndirectionScale=directionScale*textureSampleLevel(velocityGradientTexture,velocityGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\n#endif\n#ifdef DRAGGRADIENTS\ndirectionScale=directionScale*(1.0-textureSampleLevel(dragGradientTexture,dragGradientSampler,vec2<f32>(ageGradient,0.),0.).r);\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;\nparticlesOut.particles[index].seed=seed;\n#ifndef COLORGRADIENTS \nparticlesOut.particles[index].color=particlesIn.particles[index].color;\n#endif\n#ifdef SIZEGRADIENTS\nparticlesOut.particles[index].size=vec3<f32>(\ntextureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(ageGradient,0.),0.).r,\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 LIMITVELOCITYGRADIENTS\nlet limitVelocity : f32=textureSampleLevel(limitVelocityGradientTexture,limitVelocityGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\nlet currentVelocity : f32=length(updatedDirection);\nif (currentVelocity>limitVelocity) {\nupdatedDirection=updatedDirection*params.limitVelocityDamping;\n}\n#endif\nparticlesOut.particles[index].direction=updatedDirection;\n#ifdef NOISE\nlet noiseCoordinates1 : vec3<f32>=particlesIn.particles[index].noiseCoordinates1;\nlet noiseCoordinates2 : vec3<f32>=particlesIn.particles[index].noiseCoordinates2;\nlet 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;\nlet 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;\nlet 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;\nlet force : vec3<f32>=vec3<f32>(-1.+2.*fetchedR,-1.+2.*fetchedG,-1.+2.*fetchedB)*params.noiseStrength;\nparticlesOut.particles[index].direction=particlesOut.particles[index].direction+force*timeDelta;\nparticlesOut.particles[index].noiseCoordinates1=noiseCoordinates1;\nparticlesOut.particles[index].noiseCoordinates2=noiseCoordinates2;\n#endif \n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nlet angularSpeed : f32=textureSampleLevel(angularSpeedGradientTexture,angularSpeedGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\nparticlesOut.particles[index].angle=particlesIn.particles[index].angle+angularSpeed*timeDelta;\n#else\nlet angle : vec2<f32>=particlesIn.particles[index].angle;\nparticlesOut.particles[index].angle=vec2<f32>(angle.x+angle.y*timeDelta,angle.y);\n#endif\n#ifdef ANIMATESHEET \nvar offsetAge : f32=particlesOut.particles[index].age;\nlet dist : f32=params.cellInfos.y-params.cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\nlet cellStartOffset : f32=particlesIn.particles[index].cellStartOffset;\nparticlesOut.particles[index].cellStartOffset=cellStartOffset;\noffsetAge=offsetAge+cellStartOffset;\n#else\nlet cellStartOffset : f32=0.;\n#endif \nvar ratio : f32;\nif (params.cellInfos.w==1.0) {\nratio=clamp(((cellStartOffset+params.cellInfos.z*offsetAge) % life)/life,0.,1.0);\n}\nelse {\nratio=clamp((cellStartOffset+params.cellInfos.z*offsetAge)/life,0.,1.0);\n}\nparticlesOut.particles[index].cellIndex=f32(i32(params.cellInfos.x+ratio*dist));\n#endif\n}\n}\n";
|
|
5
5
|
// Sideeffect
|
|
6
6
|
ShaderStore.ShadersStoreWGSL[name] = shader;
|
|
7
7
|
/** @hidden */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gpuUpdateParticles.compute.js","sourceRoot":"","sources":["../../../../../lts/core/generated/ShadersWGSL/gpuUpdateParticles.compute.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,IAAM,IAAI,GAAG,iCAAiC,CAAC;AAC/C,IAAM,MAAM,GAAG,4kcA6Xd,CAAC;AACF,aAAa;AACb,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAC5C,cAAc;AACd,MAAM,CAAC,IAAM,+BAA+B,GAAG,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gpuUpdateParticlesComputeShader\";\nconst shader = `struct Particle {\rposition : vec3<f32>;\rage : f32;\rsize : vec3<f32>;\rlife : f32;\rseed : vec4<f32>;\rdirection : vec3<f32>;\rdummy0: f32;\r#ifdef CUSTOMEMITTER\ninitialPosition : vec3<f32>;\rdummy1: f32;\r#endif\n#ifndef COLORGRADIENTS\ncolor : vec4<f32>;\r#endif\n#ifndef BILLBOARD\ninitialDirection : vec3<f32>;\rdummy2: f32;\r#endif\n#ifdef NOISE\nnoiseCoordinates1 : vec3<f32>;\rdummy3: f32;\rnoiseCoordinates2 : vec3<f32>;\rdummy4: f32;\r#endif\n#ifdef ANGULARSPEEDGRADIENTS\nangle : f32;\r#else\nangle : vec2<f32>;\r#endif\n#ifdef ANIMATESHEET\ncellIndex : f32;\r#ifdef ANIMATESHEETRANDOMSTART\ncellStartOffset : f32;\r#endif\n#endif\n};\rstruct Particles {\rparticles : array<Particle>;\r};\rstruct SimParams {\rcurrentCount : f32;\rtimeDelta : f32;\rstopFactor : f32;\rrandomTextureSize: i32;\rlifeTime : vec2<f32>;\remitPower : vec2<f32>;\r#ifndef COLORGRADIENTS\ncolor1 : vec4<f32>;\rcolor2 : vec4<f32>;\r#endif\nsizeRange : vec2<f32>;\rscaleRange : vec4<f32>;\rangleRange : vec4<f32>;\rgravity : vec3<f32>;\r#ifdef LIMITVELOCITYGRADIENTS\nlimitVelocityDamping : f32;\r#endif\n#ifdef ANIMATESHEET\ncellInfos : vec4<f32>;\r#endif\n#ifdef NOISE\nnoiseStrength : vec3<f32>;\r#endif\n#ifndef LOCAL\nemitterWM : mat4x4<f32>;\r#endif\n#ifdef BOXEMITTER\ndirection1 : vec3<f32>;\rdirection2 : vec3<f32>;\rminEmitBox : vec3<f32>;\rmaxEmitBox : vec3<f32>;\r#endif\n#ifdef CONEEMITTER\nradius : vec2<f32>;\rconeAngle : f32;\rheight : vec2<f32>;\rdirectionRandomizer : f32;\r#endif\n#ifdef CYLINDEREMITTER\nradius : f32;\rheight : f32;\rradiusRange : f32;\r#ifdef DIRECTEDCYLINDEREMITTER\ndirection1 : vec3<f32>;\rdirection2 : vec3<f32>;\r#else\ndirectionRandomizer : f32;\r#endif\n#endif\n#ifdef HEMISPHERICEMITTER\nradius : f32;\rradiusRange : f32;\rdirectionRandomizer : f32;\r#endif\n#ifdef POINTEMITTER\ndirection1 : vec3<f32>;\rdirection2 : vec3<f32>;\r#endif\n#ifdef SPHEREEMITTER\nradius : f32;\rradiusRange : f32;\r#ifdef DIRECTEDSPHEREEMITTER\ndirection1 : vec3<f32>;\rdirection2 : vec3<f32>;\r#else\ndirectionRandomizer : f32;\r#endif\n#endif\n};\r@binding(0) @group(0) var<uniform> params : SimParams;\r@binding(1) @group(0) var<storage,read> particlesIn : Particles;\r@binding(2) @group(0) var<storage,read_write> particlesOut : Particles;\r@binding(3) @group(0) var randomTexture : texture_2d<f32>;\r@binding(4) @group(0) var randomTexture2 : texture_2d<f32>;\r#ifdef SIZEGRADIENTS\n@binding(0) @group(1) var sizeGradientSampler : sampler;\r@binding(1) @group(1) var sizeGradientTexture : texture_2d<f32>;\r#endif \n#ifdef ANGULARSPEEDGRADIENTS\n@binding(2) @group(1) var angularSpeedGradientSampler : sampler;\r@binding(3) @group(1) var angularSpeedGradientTexture : texture_2d<f32>;\r#endif \n#ifdef VELOCITYGRADIENTS\n@binding(4) @group(1) var velocityGradientSampler : sampler;\r@binding(5) @group(1) var velocityGradientTexture : texture_2d<f32>;\r#endif\n#ifdef LIMITVELOCITYGRADIENTS\n@binding(6) @group(1) var limitVelocityGradientSampler : sampler;\r@binding(7) @group(1) var limitVelocityGradientTexture : texture_2d<f32>;\r#endif\n#ifdef DRAGGRADIENTS\n@binding(8) @group(1) var dragGradientSampler : sampler;\r@binding(9) @group(1) var dragGradientTexture : texture_2d<f32>;\r#endif\n#ifdef NOISE\n@binding(10) @group(1) var noiseSampler : sampler;\r@binding(11) @group(1) var noiseTexture : texture_2d<f32>;\r#endif\nfn getRandomVec3(offset : f32,vertexID : f32)->vec3<f32> {\rreturn textureLoad(randomTexture2,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0).rgb;\r}\rfn getRandomVec4(offset : f32,vertexID : f32)->vec4<f32> {\rreturn textureLoad(randomTexture,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0);\r}\r@stage(compute) @workgroup_size(64)\rfn main(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {\rlet index : u32=GlobalInvocationID.x;\rlet vertexID : f32=f32(index);\rif (index>=u32(params.currentCount)) {\rreturn;\r}\rlet PI : f32=3.14159;\rlet timeDelta : f32=params.timeDelta;\rlet newAge : f32=particlesIn.particles[index].age+timeDelta;\rlet life : f32=particlesIn.particles[index].life;\rlet seed : vec4<f32>=particlesIn.particles[index].seed;\rlet direction : vec3<f32>=particlesIn.particles[index].direction;\rif (newAge>=life && params.stopFactor != 0.) {\rvar newPosition : vec3<f32>;\rvar newDirection : vec3<f32>;\rlet randoms : vec4<f32>=getRandomVec4(seed.x,vertexID);\rlet outLife : f32=params.lifeTime.x+(params.lifeTime.y-params.lifeTime.x)*randoms.r;\rparticlesOut.particles[index].life=outLife;\rparticlesOut.particles[index].age=newAge-life;\rparticlesOut.particles[index].seed=seed;\rvar sizex : f32;\r#ifdef SIZEGRADIENTS \nsizex=textureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(0.,0.),0.).r;\r#else\nsizex=params.sizeRange.x+(params.sizeRange.y-params.sizeRange.x)*randoms.g;\r#endif\nparticlesOut.particles[index].size=vec3<f32>(\rsizex,\rparams.scaleRange.x+(params.scaleRange.y-params.scaleRange.x)*randoms.b,\rparams.scaleRange.z+(params.scaleRange.w-params.scaleRange.z)*randoms.a);\r#ifndef COLORGRADIENTS\nparticlesOut.particles[index].color=params.color1+(params.color2-params.color1)*randoms.b;\r#endif\n#ifndef ANGULARSPEEDGRADIENTS \nparticlesOut.particles[index].angle=vec2<f32>(\rparams.angleRange.z+(params.angleRange.w-params.angleRange.z)*randoms.r,\rparams.angleRange.x+(params.angleRange.y-params.angleRange.x)*randoms.a);\r#else\nparticlesOut.particles[index].angle=params.angleRange.z+(params.angleRange.w-params.angleRange.z)*randoms.r;\r#endif \n#if defined(POINTEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rnewPosition=vec3<f32>(0.,0.,0.);\rnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\r#elif defined(BOXEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rnewPosition=params.minEmitBox+(params.maxEmitBox-params.minEmitBox)*randoms2;\rnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3; \r#elif defined(HEMISPHERICEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rlet phi : f32=2.0*PI*randoms2.x;\rlet theta : f32=acos(-1.0+2.0*randoms2.y);\rlet randX : f32=cos(phi)*sin(theta);\rlet randY : f32=cos(theta);\rlet randZ : f32=sin(phi)*sin(theta);\rnewPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,abs(randY),randZ);\rnewDirection=normalize(newPosition+params.directionRandomizer*randoms3);\r#elif defined(SPHEREEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rlet phi : f32=2.0*PI*randoms2.x;\rlet theta : f32=acos(-1.0+2.0*randoms2.y);\rlet randX : f32=cos(phi)*sin(theta);\rlet randY : f32=cos(theta);\rlet randZ : f32=sin(phi)*sin(theta);\rnewPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,randY,randZ);\r#ifdef DIRECTEDSPHEREEMITTER\nnewDirection=normalize(params.direction1+(params.direction2-params.direction1)*randoms3);\r#else\nnewDirection=normalize(newPosition+params.directionRandomizer*randoms3);\r#endif\n#elif defined(CYLINDEREMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rlet yPos : f32=(-0.5+randoms2.x)*params.height;\rvar angle : f32=randoms2.y*PI*2.;\rlet inverseRadiusRangeSquared : f32=(1.-params.radiusRange)*(1.-params.radiusRange);\rlet positionRadius : f32=params.radius*sqrt(inverseRadiusRangeSquared+randoms2.z*(1.-inverseRadiusRangeSquared));\rlet xPos : f32=positionRadius*cos(angle);\rlet zPos : f32=positionRadius*sin(angle);\rnewPosition=vec3<f32>(xPos,yPos,zPos);\r#ifdef DIRECTEDCYLINDEREMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\r#else\nangle=angle+(-0.5+randoms3.x)*PI*params.directionRandomizer;\rnewDirection=vec3<f32>(cos(angle),(-0.5+randoms3.y)*params.directionRandomizer,sin(angle));\rnewDirection=normalize(newDirection);\r#endif\n#elif defined(CONEEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet s : f32=2.0*PI*randoms2.x;\r#ifdef CONEEMITTERSPAWNPOINT\nlet h : f32=0.0001;\r#else\nvar h : f32=randoms2.y*params.height.y;\rh=1.-h*h; \r#endif\nvar lRadius : f32=params.radius.x-params.radius.x*randoms2.z*params.radius.y;\rlRadius=lRadius*h;\rlet randX : f32=lRadius*sin(s);\rlet randZ : f32=lRadius*cos(s);\rlet randY : f32=h *params.height.x;\rnewPosition=vec3<f32>(randX,randY,randZ); \rif (abs(cos(params.coneAngle))==1.0) {\rnewDirection=vec3<f32>(0.,1.0,0.);\r} else {\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rnewDirection=normalize(newPosition+params.directionRandomizer*randoms3); \r}\r#elif defined(CUSTOMEMITTER)\nnewPosition=particlesIn.particles[index].initialPosition;\rparticlesOut.particles[index].initialPosition=newPosition;\r#else \nnewPosition=vec3<f32>(0.,0.,0.);\rnewDirection=2.0*(getRandomVec3(seed.w,vertexID)-vec3<f32>(0.5,0.5,0.5));\r#endif\nlet power : f32=params.emitPower.x+(params.emitPower.y-params.emitPower.x)*randoms.a;\r#ifdef LOCAL\nparticlesOut.particles[index].position=newPosition;\r#else\nparticlesOut.particles[index].position=(params.emitterWM*vec4<f32>(newPosition,1.)).xyz;\r#endif\n#ifdef CUSTOMEMITTER\nparticlesOut.particles[index].direction=direction;\r#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=direction;\r#endif\n#else\n#ifdef LOCAL\nlet initial : vec3<f32>=newDirection;\r#else \nlet initial : vec3<f32>=(params.emitterWM*vec4<f32>(newDirection,0.)).xyz;\r#endif\nparticlesOut.particles[index].direction=initial*power;\r#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=initial;\r#endif\n#endif\n#ifdef ANIMATESHEET \nparticlesOut.particles[index].cellIndex=params.cellInfos.x;\r#ifdef ANIMATESHEETRANDOMSTART\nparticlesOut.particles[index].cellStartOffset=randoms.a*outLife;\r#endif \n#endif\n#ifdef NOISE\nparticlesOut.particles[index].noiseCoordinates1=particlesIn.particles[index].noiseCoordinates1;\rparticlesOut.particles[index].noiseCoordinates2=particlesIn.particles[index].noiseCoordinates2;\r#endif\n} else {\rvar directionScale : f32=timeDelta;\rparticlesOut.particles[index].age=newAge;\rlet ageGradient : f32=newAge/life;\r#ifdef VELOCITYGRADIENTS\ndirectionScale=directionScale*textureSampleLevel(velocityGradientTexture,velocityGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\r#endif\n#ifdef DRAGGRADIENTS\ndirectionScale=directionScale*(1.0-textureSampleLevel(dragGradientTexture,dragGradientSampler,vec2<f32>(ageGradient,0.),0.).r);\r#endif\nlet position : vec3<f32>=particlesIn.particles[index].position;\r#if defined(CUSTOMEMITTER)\nparticlesOut.particles[index].position=position+(direction-position)*ageGradient; \rparticlesOut.particles[index].initialPosition=particlesIn.particles[index].initialPosition;\r#else\nparticlesOut.particles[index].position=position+direction*directionScale;\r#endif\nparticlesOut.particles[index].life=life;\rparticlesOut.particles[index].seed=seed;\r#ifndef COLORGRADIENTS \nparticlesOut.particles[index].color=particlesIn.particles[index].color;\r#endif\n#ifdef SIZEGRADIENTS\nparticlesOut.particles[index].size=vec3<f32>(\rtextureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(ageGradient,0.),0.).r,\rparticlesIn.particles[index].size.yz);\r#else\nparticlesOut.particles[index].size=particlesIn.particles[index].size;\r#endif \n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=particlesIn.particles[index].initialDirection;\r#endif\n#ifdef CUSTOMEMITTER\nparticlesOut.particles[index].direction=direction;\r#else\nvar updatedDirection : vec3<f32>=direction+params.gravity*timeDelta;\r#ifdef LIMITVELOCITYGRADIENTS\nlet limitVelocity : f32=textureSampleLevel(limitVelocityGradientTexture,limitVelocityGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\rlet currentVelocity : f32=length(updatedDirection);\rif (currentVelocity>limitVelocity) {\rupdatedDirection=updatedDirection*params.limitVelocityDamping;\r}\r#endif\nparticlesOut.particles[index].direction=updatedDirection;\r#ifdef NOISE\nlet noiseCoordinates1 : vec3<f32>=particlesIn.particles[index].noiseCoordinates1;\rlet noiseCoordinates2 : vec3<f32>=particlesIn.particles[index].noiseCoordinates2;\rlet 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;\rlet 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;\rlet 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;\rlet force : vec3<f32>=vec3<f32>(-1.+2.*fetchedR,-1.+2.*fetchedG,-1.+2.*fetchedB)*params.noiseStrength;\rparticlesOut.particles[index].direction=particlesOut.particles[index].direction+force*timeDelta;\rparticlesOut.particles[index].noiseCoordinates1=noiseCoordinates1;\rparticlesOut.particles[index].noiseCoordinates2=noiseCoordinates2;\r#endif \n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nlet angularSpeed : f32=textureSampleLevel(angularSpeedGradientTexture,angularSpeedGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\rparticlesOut.particles[index].angle=particlesIn.particles[index].angle+angularSpeed*timeDelta;\r#else\nlet angle : vec2<f32>=particlesIn.particles[index].angle;\rparticlesOut.particles[index].angle=vec2<f32>(angle.x+angle.y*timeDelta,angle.y);\r#endif\n#ifdef ANIMATESHEET \nvar offsetAge : f32=particlesOut.particles[index].age;\rlet dist : f32=params.cellInfos.y-params.cellInfos.x;\r#ifdef ANIMATESHEETRANDOMSTART\nlet cellStartOffset : f32=particlesIn.particles[index].cellStartOffset;\rparticlesOut.particles[index].cellStartOffset=cellStartOffset;\roffsetAge=offsetAge+cellStartOffset;\r#else\nlet cellStartOffset : f32=0.;\r#endif \nvar ratio : f32;\rif (params.cellInfos.w==1.0) {\rratio=clamp(((cellStartOffset+params.cellInfos.z*offsetAge) % life)/life,0.,1.0);\r}\relse {\rratio=clamp((cellStartOffset+params.cellInfos.z*offsetAge)/life,0.,1.0);\r}\rparticlesOut.particles[index].cellIndex=f32(i32(params.cellInfos.x+ratio*dist));\r#endif\n}\r}\r`;\n// Sideeffect\nShaderStore.ShadersStoreWGSL[name] = shader;\n/** @hidden */\nexport const gpuUpdateParticlesComputeShader = { name, shader };\n"]}
|
|
1
|
+
{"version":3,"file":"gpuUpdateParticles.compute.js","sourceRoot":"","sources":["../../../../../lts/core/generated/ShadersWGSL/gpuUpdateParticles.compute.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,IAAM,IAAI,GAAG,iCAAiC,CAAC;AAC/C,IAAM,MAAM,GAAG,4kcA6Xd,CAAC;AACF,aAAa;AACb,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAC5C,cAAc;AACd,MAAM,CAAC,IAAM,+BAA+B,GAAG,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gpuUpdateParticlesComputeShader\";\nconst shader = `struct Particle {\rposition : vec3<f32>,\rage : f32,\rsize : vec3<f32>,\rlife : f32,\rseed : vec4<f32>,\rdirection : vec3<f32>,\rdummy0: f32,\r#ifdef CUSTOMEMITTER\ninitialPosition : vec3<f32>,\rdummy1: f32,\r#endif\n#ifndef COLORGRADIENTS\ncolor : vec4<f32>,\r#endif\n#ifndef BILLBOARD\ninitialDirection : vec3<f32>,\rdummy2: f32,\r#endif\n#ifdef NOISE\nnoiseCoordinates1 : vec3<f32>,\rdummy3: f32,\rnoiseCoordinates2 : vec3<f32>,\rdummy4: f32,\r#endif\n#ifdef ANGULARSPEEDGRADIENTS\nangle : f32,\r#else\nangle : vec2<f32>,\r#endif\n#ifdef ANIMATESHEET\ncellIndex : f32,\r#ifdef ANIMATESHEETRANDOMSTART\ncellStartOffset : f32,\r#endif\n#endif\n};\rstruct Particles {\rparticles : array<Particle>,\r};\rstruct SimParams {\rcurrentCount : f32,\rtimeDelta : f32,\rstopFactor : f32,\rrandomTextureSize: i32,\rlifeTime : vec2<f32>,\remitPower : vec2<f32>,\r#ifndef COLORGRADIENTS\ncolor1 : vec4<f32>,\rcolor2 : vec4<f32>,\r#endif\nsizeRange : vec2<f32>,\rscaleRange : vec4<f32>,\rangleRange : vec4<f32>,\rgravity : vec3<f32>,\r#ifdef LIMITVELOCITYGRADIENTS\nlimitVelocityDamping : f32,\r#endif\n#ifdef ANIMATESHEET\ncellInfos : vec4<f32>,\r#endif\n#ifdef NOISE\nnoiseStrength : vec3<f32>,\r#endif\n#ifndef LOCAL\nemitterWM : mat4x4<f32>,\r#endif\n#ifdef BOXEMITTER\ndirection1 : vec3<f32>,\rdirection2 : vec3<f32>,\rminEmitBox : vec3<f32>,\rmaxEmitBox : vec3<f32>,\r#endif\n#ifdef CONEEMITTER\nradius : vec2<f32>,\rconeAngle : f32,\rheight : vec2<f32>,\rdirectionRandomizer : f32,\r#endif\n#ifdef CYLINDEREMITTER\nradius : f32,\rheight : f32,\rradiusRange : f32,\r#ifdef DIRECTEDCYLINDEREMITTER\ndirection1 : vec3<f32>,\rdirection2 : vec3<f32>,\r#else\ndirectionRandomizer : f32,\r#endif\n#endif\n#ifdef HEMISPHERICEMITTER\nradius : f32,\rradiusRange : f32,\rdirectionRandomizer : f32,\r#endif\n#ifdef POINTEMITTER\ndirection1 : vec3<f32>,\rdirection2 : vec3<f32>,\r#endif\n#ifdef SPHEREEMITTER\nradius : f32,\rradiusRange : f32,\r#ifdef DIRECTEDSPHEREEMITTER\ndirection1 : vec3<f32>,\rdirection2 : vec3<f32>,\r#else\ndirectionRandomizer : f32,\r#endif\n#endif\n};\r@binding(0) @group(0) var<uniform> params : SimParams;\r@binding(1) @group(0) var<storage,read> particlesIn : Particles;\r@binding(2) @group(0) var<storage,read_write> particlesOut : Particles;\r@binding(3) @group(0) var randomTexture : texture_2d<f32>;\r@binding(4) @group(0) var randomTexture2 : texture_2d<f32>;\r#ifdef SIZEGRADIENTS\n@binding(0) @group(1) var sizeGradientSampler : sampler;\r@binding(1) @group(1) var sizeGradientTexture : texture_2d<f32>;\r#endif \n#ifdef ANGULARSPEEDGRADIENTS\n@binding(2) @group(1) var angularSpeedGradientSampler : sampler;\r@binding(3) @group(1) var angularSpeedGradientTexture : texture_2d<f32>;\r#endif \n#ifdef VELOCITYGRADIENTS\n@binding(4) @group(1) var velocityGradientSampler : sampler;\r@binding(5) @group(1) var velocityGradientTexture : texture_2d<f32>;\r#endif\n#ifdef LIMITVELOCITYGRADIENTS\n@binding(6) @group(1) var limitVelocityGradientSampler : sampler;\r@binding(7) @group(1) var limitVelocityGradientTexture : texture_2d<f32>;\r#endif\n#ifdef DRAGGRADIENTS\n@binding(8) @group(1) var dragGradientSampler : sampler;\r@binding(9) @group(1) var dragGradientTexture : texture_2d<f32>;\r#endif\n#ifdef NOISE\n@binding(10) @group(1) var noiseSampler : sampler;\r@binding(11) @group(1) var noiseTexture : texture_2d<f32>;\r#endif\nfn getRandomVec3(offset : f32,vertexID : f32)->vec3<f32> {\rreturn textureLoad(randomTexture2,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0).rgb;\r}\rfn getRandomVec4(offset : f32,vertexID : f32)->vec4<f32> {\rreturn textureLoad(randomTexture,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0);\r}\r@stage(compute) @workgroup_size(64)\rfn main(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {\rlet index : u32=GlobalInvocationID.x;\rlet vertexID : f32=f32(index);\rif (index>=u32(params.currentCount)) {\rreturn;\r}\rlet PI : f32=3.14159;\rlet timeDelta : f32=params.timeDelta;\rlet newAge : f32=particlesIn.particles[index].age+timeDelta;\rlet life : f32=particlesIn.particles[index].life;\rlet seed : vec4<f32>=particlesIn.particles[index].seed;\rlet direction : vec3<f32>=particlesIn.particles[index].direction;\rif (newAge>=life && params.stopFactor != 0.) {\rvar newPosition : vec3<f32>;\rvar newDirection : vec3<f32>;\rlet randoms : vec4<f32>=getRandomVec4(seed.x,vertexID);\rlet outLife : f32=params.lifeTime.x+(params.lifeTime.y-params.lifeTime.x)*randoms.r;\rparticlesOut.particles[index].life=outLife;\rparticlesOut.particles[index].age=newAge-life;\rparticlesOut.particles[index].seed=seed;\rvar sizex : f32;\r#ifdef SIZEGRADIENTS \nsizex=textureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(0.,0.),0.).r;\r#else\nsizex=params.sizeRange.x+(params.sizeRange.y-params.sizeRange.x)*randoms.g;\r#endif\nparticlesOut.particles[index].size=vec3<f32>(\rsizex,\rparams.scaleRange.x+(params.scaleRange.y-params.scaleRange.x)*randoms.b,\rparams.scaleRange.z+(params.scaleRange.w-params.scaleRange.z)*randoms.a);\r#ifndef COLORGRADIENTS\nparticlesOut.particles[index].color=params.color1+(params.color2-params.color1)*randoms.b;\r#endif\n#ifndef ANGULARSPEEDGRADIENTS \nparticlesOut.particles[index].angle=vec2<f32>(\rparams.angleRange.z+(params.angleRange.w-params.angleRange.z)*randoms.r,\rparams.angleRange.x+(params.angleRange.y-params.angleRange.x)*randoms.a);\r#else\nparticlesOut.particles[index].angle=params.angleRange.z+(params.angleRange.w-params.angleRange.z)*randoms.r;\r#endif \n#if defined(POINTEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rnewPosition=vec3<f32>(0.,0.,0.);\rnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\r#elif defined(BOXEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rnewPosition=params.minEmitBox+(params.maxEmitBox-params.minEmitBox)*randoms2;\rnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3; \r#elif defined(HEMISPHERICEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rlet phi : f32=2.0*PI*randoms2.x;\rlet theta : f32=acos(-1.0+2.0*randoms2.y);\rlet randX : f32=cos(phi)*sin(theta);\rlet randY : f32=cos(theta);\rlet randZ : f32=sin(phi)*sin(theta);\rnewPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,abs(randY),randZ);\rnewDirection=normalize(newPosition+params.directionRandomizer*randoms3);\r#elif defined(SPHEREEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rlet phi : f32=2.0*PI*randoms2.x;\rlet theta : f32=acos(-1.0+2.0*randoms2.y);\rlet randX : f32=cos(phi)*sin(theta);\rlet randY : f32=cos(theta);\rlet randZ : f32=sin(phi)*sin(theta);\rnewPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,randY,randZ);\r#ifdef DIRECTEDSPHEREEMITTER\nnewDirection=normalize(params.direction1+(params.direction2-params.direction1)*randoms3);\r#else\nnewDirection=normalize(newPosition+params.directionRandomizer*randoms3);\r#endif\n#elif defined(CYLINDEREMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rlet yPos : f32=(-0.5+randoms2.x)*params.height;\rvar angle : f32=randoms2.y*PI*2.;\rlet inverseRadiusRangeSquared : f32=(1.-params.radiusRange)*(1.-params.radiusRange);\rlet positionRadius : f32=params.radius*sqrt(inverseRadiusRangeSquared+randoms2.z*(1.-inverseRadiusRangeSquared));\rlet xPos : f32=positionRadius*cos(angle);\rlet zPos : f32=positionRadius*sin(angle);\rnewPosition=vec3<f32>(xPos,yPos,zPos);\r#ifdef DIRECTEDCYLINDEREMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\r#else\nangle=angle+(-0.5+randoms3.x)*PI*params.directionRandomizer;\rnewDirection=vec3<f32>(cos(angle),(-0.5+randoms3.y)*params.directionRandomizer,sin(angle));\rnewDirection=normalize(newDirection);\r#endif\n#elif defined(CONEEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);\rlet s : f32=2.0*PI*randoms2.x;\r#ifdef CONEEMITTERSPAWNPOINT\nlet h : f32=0.0001;\r#else\nvar h : f32=randoms2.y*params.height.y;\rh=1.-h*h; \r#endif\nvar lRadius : f32=params.radius.x-params.radius.x*randoms2.z*params.radius.y;\rlRadius=lRadius*h;\rlet randX : f32=lRadius*sin(s);\rlet randZ : f32=lRadius*cos(s);\rlet randY : f32=h *params.height.x;\rnewPosition=vec3<f32>(randX,randY,randZ); \rif (abs(cos(params.coneAngle))==1.0) {\rnewDirection=vec3<f32>(0.,1.0,0.);\r} else {\rlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\rnewDirection=normalize(newPosition+params.directionRandomizer*randoms3); \r}\r#elif defined(CUSTOMEMITTER)\nnewPosition=particlesIn.particles[index].initialPosition;\rparticlesOut.particles[index].initialPosition=newPosition;\r#else \nnewPosition=vec3<f32>(0.,0.,0.);\rnewDirection=2.0*(getRandomVec3(seed.w,vertexID)-vec3<f32>(0.5,0.5,0.5));\r#endif\nlet power : f32=params.emitPower.x+(params.emitPower.y-params.emitPower.x)*randoms.a;\r#ifdef LOCAL\nparticlesOut.particles[index].position=newPosition;\r#else\nparticlesOut.particles[index].position=(params.emitterWM*vec4<f32>(newPosition,1.)).xyz;\r#endif\n#ifdef CUSTOMEMITTER\nparticlesOut.particles[index].direction=direction;\r#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=direction;\r#endif\n#else\n#ifdef LOCAL\nlet initial : vec3<f32>=newDirection;\r#else \nlet initial : vec3<f32>=(params.emitterWM*vec4<f32>(newDirection,0.)).xyz;\r#endif\nparticlesOut.particles[index].direction=initial*power;\r#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=initial;\r#endif\n#endif\n#ifdef ANIMATESHEET \nparticlesOut.particles[index].cellIndex=params.cellInfos.x;\r#ifdef ANIMATESHEETRANDOMSTART\nparticlesOut.particles[index].cellStartOffset=randoms.a*outLife;\r#endif \n#endif\n#ifdef NOISE\nparticlesOut.particles[index].noiseCoordinates1=particlesIn.particles[index].noiseCoordinates1;\rparticlesOut.particles[index].noiseCoordinates2=particlesIn.particles[index].noiseCoordinates2;\r#endif\n} else {\rvar directionScale : f32=timeDelta;\rparticlesOut.particles[index].age=newAge;\rlet ageGradient : f32=newAge/life;\r#ifdef VELOCITYGRADIENTS\ndirectionScale=directionScale*textureSampleLevel(velocityGradientTexture,velocityGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\r#endif\n#ifdef DRAGGRADIENTS\ndirectionScale=directionScale*(1.0-textureSampleLevel(dragGradientTexture,dragGradientSampler,vec2<f32>(ageGradient,0.),0.).r);\r#endif\nlet position : vec3<f32>=particlesIn.particles[index].position;\r#if defined(CUSTOMEMITTER)\nparticlesOut.particles[index].position=position+(direction-position)*ageGradient; \rparticlesOut.particles[index].initialPosition=particlesIn.particles[index].initialPosition;\r#else\nparticlesOut.particles[index].position=position+direction*directionScale;\r#endif\nparticlesOut.particles[index].life=life;\rparticlesOut.particles[index].seed=seed;\r#ifndef COLORGRADIENTS \nparticlesOut.particles[index].color=particlesIn.particles[index].color;\r#endif\n#ifdef SIZEGRADIENTS\nparticlesOut.particles[index].size=vec3<f32>(\rtextureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(ageGradient,0.),0.).r,\rparticlesIn.particles[index].size.yz);\r#else\nparticlesOut.particles[index].size=particlesIn.particles[index].size;\r#endif \n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=particlesIn.particles[index].initialDirection;\r#endif\n#ifdef CUSTOMEMITTER\nparticlesOut.particles[index].direction=direction;\r#else\nvar updatedDirection : vec3<f32>=direction+params.gravity*timeDelta;\r#ifdef LIMITVELOCITYGRADIENTS\nlet limitVelocity : f32=textureSampleLevel(limitVelocityGradientTexture,limitVelocityGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\rlet currentVelocity : f32=length(updatedDirection);\rif (currentVelocity>limitVelocity) {\rupdatedDirection=updatedDirection*params.limitVelocityDamping;\r}\r#endif\nparticlesOut.particles[index].direction=updatedDirection;\r#ifdef NOISE\nlet noiseCoordinates1 : vec3<f32>=particlesIn.particles[index].noiseCoordinates1;\rlet noiseCoordinates2 : vec3<f32>=particlesIn.particles[index].noiseCoordinates2;\rlet 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;\rlet 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;\rlet 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;\rlet force : vec3<f32>=vec3<f32>(-1.+2.*fetchedR,-1.+2.*fetchedG,-1.+2.*fetchedB)*params.noiseStrength;\rparticlesOut.particles[index].direction=particlesOut.particles[index].direction+force*timeDelta;\rparticlesOut.particles[index].noiseCoordinates1=noiseCoordinates1;\rparticlesOut.particles[index].noiseCoordinates2=noiseCoordinates2;\r#endif \n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nlet angularSpeed : f32=textureSampleLevel(angularSpeedGradientTexture,angularSpeedGradientSampler,vec2<f32>(ageGradient,0.),0.).r;\rparticlesOut.particles[index].angle=particlesIn.particles[index].angle+angularSpeed*timeDelta;\r#else\nlet angle : vec2<f32>=particlesIn.particles[index].angle;\rparticlesOut.particles[index].angle=vec2<f32>(angle.x+angle.y*timeDelta,angle.y);\r#endif\n#ifdef ANIMATESHEET \nvar offsetAge : f32=particlesOut.particles[index].age;\rlet dist : f32=params.cellInfos.y-params.cellInfos.x;\r#ifdef ANIMATESHEETRANDOMSTART\nlet cellStartOffset : f32=particlesIn.particles[index].cellStartOffset;\rparticlesOut.particles[index].cellStartOffset=cellStartOffset;\roffsetAge=offsetAge+cellStartOffset;\r#else\nlet cellStartOffset : f32=0.;\r#endif \nvar ratio : f32;\rif (params.cellInfos.w==1.0) {\rratio=clamp(((cellStartOffset+params.cellInfos.z*offsetAge) % life)/life,0.,1.0);\r}\relse {\rratio=clamp((cellStartOffset+params.cellInfos.z*offsetAge)/life,0.,1.0);\r}\rparticlesOut.particles[index].cellIndex=f32(i32(params.cellInfos.x+ratio*dist));\r#endif\n}\r}\r`;\n// Sideeffect\nShaderStore.ShadersStoreWGSL[name] = shader;\n/** @hidden */\nexport const gpuUpdateParticlesComputeShader = { name, shader };\n"]}
|