UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

96 lines (94 loc) 3.63 kB
var particleVS = ` fn unpack3NFloats(src: f32) -> vec3f { let r = fract(src); let g = fract(src * 256.0); let b = fract(src * 65536.0); return vec3f(r, g, b); } fn saturate(x: f32) -> f32 { return clamp(x, 0.0, 1.0); } struct TexLerpUnpackResult { result: vec4f, unpacked: vec3f } fn tex1Dlod_lerp_simple(tex: texture_2d<f32>, texSampler: sampler, tc: vec2f) -> vec4f { let tc_next = tc + vec2f(uniform.graphSampleSize); return mix( textureSample(tex, texSampler, tc), textureSample(tex, texSampler, tc_next), fract(tc.x * uniform.graphNumSamples) ); } fn tex1Dlod_lerp_unpack(tex: texture_2d<f32>, texSampler: sampler, tc: vec2f) -> TexLerpUnpackResult { let tc_next = tc + vec2f(uniform.graphSampleSize); let a = textureSampleLevel(tex, texSampler, tc, 0.0); let b = textureSampleLevel(tex, texSampler, tc_next, 0.0); let c = fract(tc.x * uniform.graphNumSamples); let unpackedA = unpack3NFloats(a.w); let unpackedB = unpack3NFloats(b.w); let w_out = mix(unpackedA, unpackedB, c); return TexLerpUnpackResult(mix(a, b, c), w_out); } struct RotateResult { rotatedVec: vec2f, matrix: mat2x2f } fn rotateWithMatrix(quadXY: vec2f, pRotation: f32) -> RotateResult { let c = cos(pRotation); let s = sin(pRotation); let m = mat2x2f(vec2f(c, s), vec2f(-s, c)); return RotateResult(m * quadXY, m); } fn billboard(InstanceCoords: vec3f, quadXY: vec2f) -> vec3f { var pos: vec3f; #ifdef SCREEN_SPACE pos = vec3f(-1.0, 0.0, 0.0) * quadXY.x + vec3f(0.0, -1.0, 0.0) * quadXY.y; #else pos = -uniform.matrix_viewInverse[0].xyz * quadXY.x + -uniform.matrix_viewInverse[1].xyz * quadXY.y; #endif return pos; } fn customFace(InstanceCoords: vec3f, quadXY: vec2f) -> vec3f { let pos = uniform.faceTangent * quadXY.x + uniform.faceBinorm * quadXY.y; return pos; } fn safeNormalize(v: vec2f) -> vec2f { let l = length(v); return select(v, v / l, l > 1e-06); } @vertex fn vertexMain(input: VertexInput) -> VertexOutput { var output: VertexOutput; let meshLocalPos_in = input.particle_vertexData.xyz; let id = floor(input.particle_vertexData.w); let rndFactor = fract(sin(id + 1.0 + uniform.seed)); let rndFactor3 = vec3f(rndFactor, fract(rndFactor*10.0), fract(rndFactor*100.0)); let uv = id / uniform.numParticlesPot; readInput(uv); #ifdef LOCAL_SPACE let modelRotation = mat3x3f(uniform.matrix_model[0].xyz, uniform.matrix_model[1].xyz, uniform.matrix_model[2].xyz); inVel = modelRotation * inVel; #endif let viewRotation = mat3x3f(uniform.matrix_view[0].xyz, uniform.matrix_view[1].xyz, uniform.matrix_view[2].xyz); let velocityV = safeNormalize((viewRotation * inVel).xy); let particleLifetime = uniform.lifetime; var meshLocalPos = meshLocalPos_in; if (inLife <= 0.0 || inLife > particleLifetime || !inShow) { meshLocalPos = vec3f(0.0); } let quadXY = meshLocalPos.xy; let nlife = clamp(inLife / particleLifetime, 0.0, 1.0); let lerp_result = tex1Dlod_lerp_unpack(internalTex2, internalTex2Sampler, vec2f(nlife, 0.0)); let params = lerp_result.result; let paramDiv = lerp_result.unpacked; var scale = params.y; let scaleDiv = paramDiv.x; let alphaDiv = paramDiv.z; scale = scale + (scaleDiv * 2.0 - 1.0) * uniform.scaleDivMult * fract(rndFactor*10000.0); #ifndef USE_MESH output.texCoordsAlphaLife = vec4f(quadXY * -0.5 + 0.5, (alphaDiv * 2.0 - 1.0) * uniform.alphaDivMult * fract(rndFactor*1000.0), nlife); #else output.texCoordsAlphaLife = vec4f(particle_uv, (alphaDiv * 2.0 - 1.0) * uniform.alphaDivMult * fract(rndFactor*1000.0), nlife); #endif var particlePos = inPos; var particlePosMoved = vec3f(0.0); var rotMatrix: mat2x2f; `; export { particleVS as default };