@galacean/engine-core 2.0.0-alpha.25 → 2.0.0-alpha.26
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/dist/main.js +909 -110
- package/dist/main.js.map +1 -1
- package/dist/module.js +909 -111
- package/dist/module.js.map +1 -1
- package/package.json +3 -3
- package/types/particle/ParticleGenerator.d.ts +3 -0
- package/types/particle/index.d.ts +1 -0
- package/types/particle/modules/NoiseModule.d.ts +90 -0
- package/types/shader/Shader.d.ts +2 -0
- package/types/shader/ShaderMacroProcessor.d.ts +1 -0
- package/types/shader/ShaderPass.d.ts +17 -3
- package/types/shader/enums/ShaderPreprocessorDirective.d.ts +16 -0
- package/types/shaderlib/ShaderLib.d.ts +1 -0
- package/types/shaderlib/particle/index.d.ts +1 -0
package/dist/main.js
CHANGED
|
@@ -1327,6 +1327,12 @@ SystemInfo._initialize();
|
|
|
1327
1327
|
case TextureFormat.ETC2_RGB:
|
|
1328
1328
|
case TextureFormat.ETC2_RGBA8:
|
|
1329
1329
|
case TextureFormat.ASTC_4x4:
|
|
1330
|
+
case TextureFormat.ASTC_5x5:
|
|
1331
|
+
case TextureFormat.ASTC_6x6:
|
|
1332
|
+
case TextureFormat.ASTC_8x8:
|
|
1333
|
+
case TextureFormat.ASTC_10x10:
|
|
1334
|
+
case TextureFormat.ASTC_12x12:
|
|
1335
|
+
case TextureFormat.ETC2_RGBA5:
|
|
1330
1336
|
return true;
|
|
1331
1337
|
default:
|
|
1332
1338
|
return false;
|
|
@@ -1865,7 +1871,7 @@ SystemInfo._initialize();
|
|
|
1865
1871
|
_this = ReferResource.call(this, engine) || this, _this._charInfoMap = {}, _this._space = 1, _this._curX = 1, _this._curY = 1, _this._nextY = 1;
|
|
1866
1872
|
_this.isGCIgnored = true;
|
|
1867
1873
|
var format = engine._hardwareRenderer.isWebGL2 ? TextureFormat.R8 : TextureFormat.Alpha8;
|
|
1868
|
-
var texture = new Texture2D(engine, 512, 512, format, false);
|
|
1874
|
+
var texture = new Texture2D(engine, 512, 512, format, false, false);
|
|
1869
1875
|
texture.filterMode = TextureFilterMode.Bilinear;
|
|
1870
1876
|
texture.isGCIgnored = true;
|
|
1871
1877
|
_this.texture = texture;
|
|
@@ -4918,7 +4924,9 @@ var force_over_lifetime_module = "#if defined(RENDERER_FOL_CONSTANT_MODE) || def
|
|
|
4918
4924
|
|
|
4919
4925
|
var limit_velocity_over_lifetime_module = "#ifdef RENDERER_LVL_MODULE_ENABLED\n uniform int renderer_LVLSpace;\n uniform float renderer_LVLDampen;\n\n // Scalar limit\n #ifndef RENDERER_LVL_SEPARATE_AXES\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n uniform float renderer_LVLSpeedMaxConst;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n uniform float renderer_LVLSpeedMinConst;\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n uniform vec2 renderer_LVLSpeedMaxCurve[4];\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n uniform vec2 renderer_LVLSpeedMinCurve[4];\n #endif\n #endif\n #endif\n\n // Per-axis limit\n #ifdef RENDERER_LVL_SEPARATE_AXES\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n uniform vec3 renderer_LVLSpeedMaxConstVector;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n uniform vec3 renderer_LVLSpeedMinConstVector;\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n uniform vec2 renderer_LVLSpeedXMaxCurve[4];\n uniform vec2 renderer_LVLSpeedYMaxCurve[4];\n uniform vec2 renderer_LVLSpeedZMaxCurve[4];\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n uniform vec2 renderer_LVLSpeedXMinCurve[4];\n uniform vec2 renderer_LVLSpeedYMinCurve[4];\n uniform vec2 renderer_LVLSpeedZMinCurve[4];\n #endif\n #endif\n #endif\n\n // Drag curve\n #ifdef RENDERER_LVL_DRAG_CURVE_MODE\n uniform vec2 renderer_LVLDragMaxCurve[4];\n #ifdef RENDERER_LVL_DRAG_IS_RANDOM_TWO\n uniform vec2 renderer_LVLDragMinCurve[4];\n #endif\n #endif\n\n float evaluateLVLDrag(float normalizedAge, float dragRand) {\n #ifdef RENDERER_LVL_DRAG_CURVE_MODE\n float dragMax = evaluateParticleCurve(renderer_LVLDragMaxCurve, normalizedAge);\n #ifdef RENDERER_LVL_DRAG_IS_RANDOM_TWO\n float dragMin = evaluateParticleCurve(renderer_LVLDragMinCurve, normalizedAge);\n return mix(dragMin, dragMax, dragRand);\n #else\n return dragMax;\n #endif\n #else\n return mix(renderer_LVLDragConstant.x, renderer_LVLDragConstant.y, dragRand);\n #endif\n }\n\n vec3 applyLVLSpeedLimitTF(vec3 velocity, float normalizedAge, float limitRand, float effectiveDampen) {\n #ifdef RENDERER_LVL_SEPARATE_AXES\n vec3 limitSpeed;\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n limitSpeed = renderer_LVLSpeedMaxConstVector;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n limitSpeed = mix(renderer_LVLSpeedMinConstVector, limitSpeed, limitRand);\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n limitSpeed = vec3(\n evaluateParticleCurve(renderer_LVLSpeedXMaxCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedYMaxCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedZMaxCurve, normalizedAge)\n );\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n vec3 minLimitSpeed = vec3(\n evaluateParticleCurve(renderer_LVLSpeedXMinCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedYMinCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedZMinCurve, normalizedAge)\n );\n limitSpeed = mix(minLimitSpeed, limitSpeed, limitRand);\n #endif\n #endif\n\n vec3 absVel = abs(velocity);\n vec3 excess = max(absVel - limitSpeed, vec3(0.0));\n velocity = sign(velocity) * (absVel - excess * effectiveDampen);\n #else\n float limitSpeed;\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n limitSpeed = renderer_LVLSpeedMaxConst;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n limitSpeed = mix(renderer_LVLSpeedMinConst, limitSpeed, limitRand);\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n limitSpeed = evaluateParticleCurve(renderer_LVLSpeedMaxCurve, normalizedAge);\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n float minLimitSpeed = evaluateParticleCurve(renderer_LVLSpeedMinCurve, normalizedAge);\n limitSpeed = mix(minLimitSpeed, limitSpeed, limitRand);\n #endif\n #endif\n\n float speed = length(velocity);\n if (speed > limitSpeed && speed > 0.0) {\n float excess = speed - limitSpeed;\n velocity = velocity * ((speed - excess * effectiveDampen) / speed);\n }\n #endif\n return velocity;\n }\n\n#endif\n"; // eslint-disable-line
|
|
4920
4926
|
|
|
4921
|
-
var particle_feedback_simulation = "// Transform Feedback update shader for particle simulation.\n// Update order: VOL/FOL → Dampen → Drag → Position.\n// Runs once per particle per frame (no rasterization).\n\n// Previous frame TF data\nattribute vec3 a_FeedbackPosition;\nattribute vec3 a_FeedbackVelocity;\n\n// Per-particle instance data\nattribute vec4 a_ShapePositionStartLifeTime;\nattribute vec4 a_DirectionTime;\nattribute vec3 a_StartSize;\nattribute float a_StartSpeed;\nattribute vec4 a_Random0;\nattribute vec4 a_Random1;\nattribute vec3 a_SimulationWorldPosition;\nattribute vec4 a_SimulationWorldRotation;\nattribute vec4 a_Random2;\n\n// Uniforms\nuniform float renderer_CurrentTime;\nuniform float renderer_DeltaTime;\nuniform vec3 renderer_Gravity;\nuniform vec2 renderer_LVLDragConstant;\nuniform vec3 renderer_WorldPosition;\nuniform vec4 renderer_WorldRotation;\nuniform int renderer_SimulationSpace;\n\n// TF outputs\nvarying vec3 v_FeedbackPosition;\nvarying vec3 v_FeedbackVelocity;\n\n#include <particle_common>\n#include <velocity_over_lifetime_module>\n#include <force_over_lifetime_module>\n#include <limit_velocity_over_lifetime_module>\n\n// Get VOL instantaneous velocity at normalizedAge\nvec3 getVOLVelocity(float normalizedAge) {\n vec3 vel = vec3(0.0);\n #ifdef _VOL_MODULE_ENABLED\n #ifdef RENDERER_VOL_CONSTANT_MODE\n vel = renderer_VOLMaxConst;\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vel = mix(renderer_VOLMinConst, vel, a_Random1.yzw);\n #endif\n #endif\n #ifdef RENDERER_VOL_CURVE_MODE\n vel = vec3(\n evaluateParticleCurve(renderer_VOLMaxGradientX, normalizedAge),\n evaluateParticleCurve(renderer_VOLMaxGradientY, normalizedAge),\n evaluateParticleCurve(renderer_VOLMaxGradientZ, normalizedAge)\n );\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vec3 minVel = vec3(\n evaluateParticleCurve(renderer_VOLMinGradientX, normalizedAge),\n evaluateParticleCurve(renderer_VOLMinGradientY, normalizedAge),\n evaluateParticleCurve(renderer_VOLMinGradientZ, normalizedAge)\n );\n vel = mix(minVel, vel, a_Random1.yzw);\n #endif\n #endif\n #endif\n return vel;\n}\n\n// Get FOL instantaneous acceleration at normalizedAge\nvec3 getFOLAcceleration(float normalizedAge) {\n vec3 acc = vec3(0.0);\n #ifdef _FOL_MODULE_ENABLED\n #ifdef RENDERER_FOL_CONSTANT_MODE\n acc = renderer_FOLMaxConst;\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n acc = mix(renderer_FOLMinConst, acc, vec3(a_Random2.x, a_Random2.y, a_Random2.z));\n #endif\n #endif\n #ifdef RENDERER_FOL_CURVE_MODE\n acc = vec3(\n evaluateParticleCurve(renderer_FOLMaxGradientX, normalizedAge),\n evaluateParticleCurve(renderer_FOLMaxGradientY, normalizedAge),\n evaluateParticleCurve(renderer_FOLMaxGradientZ, normalizedAge)\n );\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n vec3 minAcc = vec3(\n evaluateParticleCurve(renderer_FOLMinGradientX, normalizedAge),\n evaluateParticleCurve(renderer_FOLMinGradientY, normalizedAge),\n evaluateParticleCurve(renderer_FOLMinGradientZ, normalizedAge)\n );\n acc = mix(minAcc, acc, vec3(a_Random2.x, a_Random2.y, a_Random2.z));\n #endif\n #endif\n #endif\n return acc;\n}\n\nvoid main() {\n float age = renderer_CurrentTime - a_DirectionTime.w;\n float lifetime = a_ShapePositionStartLifeTime.w;\n float normalizedAge = age / lifetime;\n // Clamp to age on the first TF pass: particles emitted mid-frame have age < dt,\n // so using the full dt would over-integrate. Subsequent passes are unaffected (age >= dt).\n float dt = min(renderer_DeltaTime, age);\n\n // normalizedAge < 0.0: stale TF slot whose startTime is from a previous playback (e.g. after StopEmittingAndClear).\n if (normalizedAge >= 1.0 || normalizedAge < 0.0) {\n v_FeedbackPosition = a_FeedbackPosition;\n v_FeedbackVelocity = a_FeedbackVelocity;\n gl_Position = vec4(0.0);\n return;\n }\n\n vec4 worldRotation;\n if (renderer_SimulationSpace == 0) {\n worldRotation = renderer_WorldRotation;\n } else {\n worldRotation = a_SimulationWorldRotation;\n }\n vec4 invWorldRotation = quaternionConjugate(worldRotation);\n\n // Read previous frame state (initialized by CPU on particle birth)\n vec3 localVelocity = a_FeedbackVelocity;\n\n // =====================================================\n // Step 1: Apply velocity module deltas (VOL + FOL + Gravity)\n // =====================================================\n\n // Gravity (world space)\n vec3 gravityDelta = renderer_Gravity * a_Random0.x * dt;\n\n // VOL instantaneous velocity (animated velocity, not persisted)\n vec3 volLocal = vec3(0.0);\n vec3 volWorld = vec3(0.0);\n #ifdef _VOL_MODULE_ENABLED\n vec3 vol = getVOLVelocity(normalizedAge);\n if (renderer_VOLSpace == 0) {\n volLocal = vol;\n } else {\n volWorld = vol;\n }\n #endif\n\n // FOL acceleration → velocity delta (always persisted, like gravity)\n vec3 folDeltaLocal = vec3(0.0);\n #ifdef _FOL_MODULE_ENABLED\n vec3 folAcc = getFOLAcceleration(normalizedAge);\n vec3 folVelDelta = folAcc * dt;\n if (renderer_FOLSpace == 0) {\n folDeltaLocal = folVelDelta;\n } else {\n // World FOL: convert to local and persist, same as gravity\n folDeltaLocal = rotationByQuaternions(folVelDelta, invWorldRotation);\n }\n #endif\n\n // Gravity and FOL contribute to base velocity (persisted, subject to dampen/drag).\n vec3 gravityLocal = rotationByQuaternions(gravityDelta, invWorldRotation);\n localVelocity += folDeltaLocal + gravityLocal;\n\n // =====================================================\n // Step 2 & 3: Dampen (Limit Velocity) + Drag\n // VOL must be projected into the LVL target space so that\n // limit/drag see the full velocity regardless of VOL.space vs LVL.space.\n // =====================================================\n #ifdef RENDERER_LVL_MODULE_ENABLED\n // Precompute VOL in both spaces\n vec3 volAsLocal = volLocal + rotationByQuaternions(volWorld, invWorldRotation);\n vec3 volAsWorld = rotationByQuaternions(volLocal, worldRotation) + volWorld;\n\n float limitRand = a_Random2.w;\n float dampen = renderer_LVLDampen;\n // Frame-rate independent dampen (30fps as reference)\n float effectiveDampen = 1.0 - pow(1.0 - dampen, dt * 30.0);\n\n if (renderer_LVLSpace == 0) {\n // Local space: total = base + all VOL projected to local\n vec3 totalLocal = localVelocity + volAsLocal;\n vec3 dampenedTotal = applyLVLSpeedLimitTF(totalLocal, normalizedAge, limitRand, effectiveDampen);\n localVelocity = dampenedTotal - volAsLocal;\n } else {\n // World space: total = rotated base + all VOL projected to world\n vec3 totalWorld = rotationByQuaternions(localVelocity, worldRotation) + volAsWorld;\n vec3 dampenedTotal = applyLVLSpeedLimitTF(totalWorld, normalizedAge, limitRand, effectiveDampen);\n localVelocity = rotationByQuaternions(dampenedTotal - volAsWorld, invWorldRotation);\n }\n\n // Drag: same space as dampen\n {\n float dragCoeff = evaluateLVLDrag(normalizedAge, a_Random2.w);\n if (dragCoeff > 0.0) {\n vec3 totalVel;\n if (renderer_LVLSpace == 0) {\n totalVel = localVelocity + volAsLocal;\n } else {\n totalVel = rotationByQuaternions(localVelocity, worldRotation) + volAsWorld;\n }\n float velMagSqr = dot(totalVel, totalVel);\n float velMag = sqrt(velMagSqr);\n\n float drag = dragCoeff;\n\n #ifdef RENDERER_LVL_DRAG_MULTIPLY_SIZE\n float maxDim = max(a_StartSize.x, max(a_StartSize.y, a_StartSize.z));\n float radius = maxDim * 0.5;\n drag *= 3.14159265 * radius * radius;\n #endif\n\n #ifdef RENDERER_LVL_DRAG_MULTIPLY_VELOCITY\n drag *= velMagSqr;\n #endif\n\n if (velMag > 0.0) {\n float newVelMag = max(0.0, velMag - drag * dt);\n vec3 draggedTotal = totalVel * (newVelMag / velMag);\n if (renderer_LVLSpace == 0) {\n localVelocity = draggedTotal - volAsLocal;\n } else {\n localVelocity = rotationByQuaternions(draggedTotal - volAsWorld, invWorldRotation);\n }\n }\n }\n }\n #endif\n\n // =====================================================\n // Step 4: Integrate position in simulation space\n // Local mode: position in local space, velocity rotated to local\n // World mode: position in world space, velocity rotated to world\n // =====================================================\n // FOL is now fully in localVelocity (both local and world-space FOL).\n // Only VOL overlay needs to be added here.\n vec3 totalVelocity;\n if (renderer_SimulationSpace == 0) {\n // Local: integrate in local space\n totalVelocity = localVelocity + volLocal\n + rotationByQuaternions(volWorld, invWorldRotation);\n } else {\n // World: integrate in world space\n totalVelocity = rotationByQuaternions(localVelocity + volLocal, worldRotation) + volWorld;\n }\n vec3 position = a_FeedbackPosition + totalVelocity * dt;\n\n v_FeedbackPosition = position;\n v_FeedbackVelocity = localVelocity;\n gl_Position = vec4(0.0);\n}\n"; // eslint-disable-line
|
|
4927
|
+
var noise_module = "#ifdef RENDERER_NOISE_MODULE_ENABLED\n\n#include <noise_common>\n#include <noise_simplex_3D>\n\nuniform vec4 renderer_NoiseParams; // xyz = strength (constant mode only), w = frequency\nuniform vec4 renderer_NoiseOctaveParams; // x = scrollSpeed, y = octaveCount, z = octaveIntensityMultiplier, w = octaveFrequencyMultiplier\n\n#ifdef RENDERER_NOISE_STRENGTH_CURVE\n uniform vec2 renderer_NoiseStrengthMaxCurveX[4];\n #ifdef RENDERER_NOISE_IS_SEPARATE\n uniform vec2 renderer_NoiseStrengthMaxCurveY[4];\n uniform vec2 renderer_NoiseStrengthMaxCurveZ[4];\n #endif\n #ifdef RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO\n uniform vec2 renderer_NoiseStrengthMinCurveX[4];\n #ifdef RENDERER_NOISE_IS_SEPARATE\n uniform vec2 renderer_NoiseStrengthMinCurveY[4];\n uniform vec2 renderer_NoiseStrengthMinCurveZ[4];\n #endif\n #endif\n#else\n #ifdef RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO\n uniform vec3 renderer_NoiseStrengthMinConst;\n #endif\n#endif\n\nvec3 sampleSimplexNoise3D(vec3 coord) {\n float axisOffset = 100.0;\n return vec3(\n simplex(vec3(coord.z, coord.y, coord.x)),\n simplex(vec3(coord.x + axisOffset, coord.z, coord.y)),\n simplex(vec3(coord.y, coord.x + axisOffset, coord.z))\n );\n}\n\nvec3 computeNoiseDisplacement(vec3 currentPosition, float normalizedAge) {\n vec3 coord = currentPosition * renderer_NoiseParams.w\n + vec3(renderer_CurrentTime * renderer_NoiseOctaveParams.x);\n\n int octaveCount = int(renderer_NoiseOctaveParams.y);\n float octaveIntensityMultiplier = renderer_NoiseOctaveParams.z;\n float octaveFrequencyMultiplier = renderer_NoiseOctaveParams.w;\n\n vec3 noiseValue = sampleSimplexNoise3D(coord);\n float totalAmplitude = 1.0;\n\n // Unrolled octave loop (GLSL ES 1.0 requires constant loop bounds)\n if (octaveCount >= 2) {\n float amplitude = octaveIntensityMultiplier;\n totalAmplitude += amplitude;\n noiseValue += amplitude * sampleSimplexNoise3D(coord * octaveFrequencyMultiplier);\n\n if (octaveCount >= 3) {\n amplitude *= octaveIntensityMultiplier;\n totalAmplitude += amplitude;\n noiseValue += amplitude * sampleSimplexNoise3D(coord * octaveFrequencyMultiplier * octaveFrequencyMultiplier);\n }\n }\n\n // Evaluate strength (supports Constant, TwoConstants, Curve, TwoCurves).\n vec3 strength;\n #ifdef RENDERER_NOISE_STRENGTH_CURVE\n float sx = evaluateParticleCurve(renderer_NoiseStrengthMaxCurveX, normalizedAge);\n #ifdef RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO\n sx = mix(evaluateParticleCurve(renderer_NoiseStrengthMinCurveX, normalizedAge), sx, a_Random0.z);\n #endif\n #ifdef RENDERER_NOISE_IS_SEPARATE\n float sy = evaluateParticleCurve(renderer_NoiseStrengthMaxCurveY, normalizedAge);\n float sz = evaluateParticleCurve(renderer_NoiseStrengthMaxCurveZ, normalizedAge);\n #ifdef RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO\n sy = mix(evaluateParticleCurve(renderer_NoiseStrengthMinCurveY, normalizedAge), sy, a_Random0.z);\n sz = mix(evaluateParticleCurve(renderer_NoiseStrengthMinCurveZ, normalizedAge), sz, a_Random0.z);\n #endif\n strength = vec3(sx, sy, sz);\n #else\n strength = vec3(sx);\n #endif\n #else\n strength = renderer_NoiseParams.xyz;\n #ifdef RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO\n strength = mix(renderer_NoiseStrengthMinConst, strength, a_Random0.z);\n #endif\n #endif\n\n return (noiseValue / totalAmplitude) * strength;\n}\n\n#endif\n"; // eslint-disable-line
|
|
4928
|
+
|
|
4929
|
+
var particle_feedback_simulation = "// Transform Feedback update shader for particle simulation.\n// Update order: VOL/FOL → Dampen → Drag → Position.\n// Runs once per particle per frame (no rasterization).\n\n// Previous frame TF data\nattribute vec3 a_FeedbackPosition;\nattribute vec3 a_FeedbackVelocity;\n\n// Per-particle instance data\nattribute vec4 a_ShapePositionStartLifeTime;\nattribute vec4 a_DirectionTime;\nattribute vec3 a_StartSize;\nattribute float a_StartSpeed;\nattribute vec4 a_Random0;\nattribute vec4 a_Random1;\nattribute vec3 a_SimulationWorldPosition;\nattribute vec4 a_SimulationWorldRotation;\nattribute vec4 a_Random2;\n\n// Uniforms\nuniform float renderer_CurrentTime;\nuniform float renderer_DeltaTime;\nuniform vec3 renderer_Gravity;\nuniform vec2 renderer_LVLDragConstant;\nuniform vec3 renderer_WorldPosition;\nuniform vec4 renderer_WorldRotation;\nuniform int renderer_SimulationSpace;\n\n// TF outputs\nvarying vec3 v_FeedbackPosition;\nvarying vec3 v_FeedbackVelocity;\n\n#include <particle_common>\n#include <velocity_over_lifetime_module>\n#include <force_over_lifetime_module>\n#include <limit_velocity_over_lifetime_module>\n#include <noise_module>\n\n// Get VOL instantaneous velocity at normalizedAge\nvec3 getVOLVelocity(float normalizedAge) {\n vec3 vel = vec3(0.0);\n #ifdef _VOL_MODULE_ENABLED\n #ifdef RENDERER_VOL_CONSTANT_MODE\n vel = renderer_VOLMaxConst;\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vel = mix(renderer_VOLMinConst, vel, a_Random1.yzw);\n #endif\n #endif\n #ifdef RENDERER_VOL_CURVE_MODE\n vel = vec3(\n evaluateParticleCurve(renderer_VOLMaxGradientX, normalizedAge),\n evaluateParticleCurve(renderer_VOLMaxGradientY, normalizedAge),\n evaluateParticleCurve(renderer_VOLMaxGradientZ, normalizedAge)\n );\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vec3 minVel = vec3(\n evaluateParticleCurve(renderer_VOLMinGradientX, normalizedAge),\n evaluateParticleCurve(renderer_VOLMinGradientY, normalizedAge),\n evaluateParticleCurve(renderer_VOLMinGradientZ, normalizedAge)\n );\n vel = mix(minVel, vel, a_Random1.yzw);\n #endif\n #endif\n #endif\n return vel;\n}\n\n// Get FOL instantaneous acceleration at normalizedAge\nvec3 getFOLAcceleration(float normalizedAge) {\n vec3 acc = vec3(0.0);\n #ifdef _FOL_MODULE_ENABLED\n #ifdef RENDERER_FOL_CONSTANT_MODE\n acc = renderer_FOLMaxConst;\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n acc = mix(renderer_FOLMinConst, acc, vec3(a_Random2.x, a_Random2.y, a_Random2.z));\n #endif\n #endif\n #ifdef RENDERER_FOL_CURVE_MODE\n acc = vec3(\n evaluateParticleCurve(renderer_FOLMaxGradientX, normalizedAge),\n evaluateParticleCurve(renderer_FOLMaxGradientY, normalizedAge),\n evaluateParticleCurve(renderer_FOLMaxGradientZ, normalizedAge)\n );\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n vec3 minAcc = vec3(\n evaluateParticleCurve(renderer_FOLMinGradientX, normalizedAge),\n evaluateParticleCurve(renderer_FOLMinGradientY, normalizedAge),\n evaluateParticleCurve(renderer_FOLMinGradientZ, normalizedAge)\n );\n acc = mix(minAcc, acc, vec3(a_Random2.x, a_Random2.y, a_Random2.z));\n #endif\n #endif\n #endif\n return acc;\n}\n\nvoid main() {\n float age = renderer_CurrentTime - a_DirectionTime.w;\n float lifetime = a_ShapePositionStartLifeTime.w;\n float normalizedAge = age / lifetime;\n // Clamp to age on the first TF pass: particles emitted mid-frame have age < dt,\n // so using the full dt would over-integrate. Subsequent passes are unaffected (age >= dt).\n float dt = min(renderer_DeltaTime, age);\n\n // normalizedAge < 0.0: stale TF slot whose startTime is from a previous playback (e.g. after StopEmittingAndClear).\n if (normalizedAge >= 1.0 || normalizedAge < 0.0) {\n v_FeedbackPosition = a_FeedbackPosition;\n v_FeedbackVelocity = a_FeedbackVelocity;\n gl_Position = vec4(0.0);\n return;\n }\n\n vec4 worldRotation;\n if (renderer_SimulationSpace == 0) {\n worldRotation = renderer_WorldRotation;\n } else {\n worldRotation = a_SimulationWorldRotation;\n }\n vec4 invWorldRotation = quaternionConjugate(worldRotation);\n\n // Read previous frame state (initialized by CPU on particle birth)\n vec3 localVelocity = a_FeedbackVelocity;\n\n // =====================================================\n // Step 1: Apply velocity module deltas (VOL + FOL + Gravity)\n // =====================================================\n\n // Gravity (world space)\n vec3 gravityDelta = renderer_Gravity * a_Random0.x * dt;\n\n // VOL instantaneous velocity (animated velocity, not persisted)\n vec3 volLocal = vec3(0.0);\n vec3 volWorld = vec3(0.0);\n #ifdef _VOL_MODULE_ENABLED\n vec3 vol = getVOLVelocity(normalizedAge);\n if (renderer_VOLSpace == 0) {\n volLocal = vol;\n } else {\n volWorld = vol;\n }\n #endif\n\n // FOL acceleration → velocity delta (always persisted, like gravity)\n vec3 folDeltaLocal = vec3(0.0);\n #ifdef _FOL_MODULE_ENABLED\n vec3 folAcc = getFOLAcceleration(normalizedAge);\n vec3 folVelDelta = folAcc * dt;\n if (renderer_FOLSpace == 0) {\n folDeltaLocal = folVelDelta;\n } else {\n // World FOL: convert to local and persist, same as gravity\n folDeltaLocal = rotationByQuaternions(folVelDelta, invWorldRotation);\n }\n #endif\n\n // Gravity and FOL contribute to base velocity (persisted, subject to dampen/drag).\n vec3 gravityLocal = rotationByQuaternions(gravityDelta, invWorldRotation);\n localVelocity += folDeltaLocal + gravityLocal;\n\n // =====================================================\n // Step 2 & 3: Dampen (Limit Velocity) + Drag\n // VOL must be projected into the LVL target space so that\n // limit/drag see the full velocity regardless of VOL.space vs LVL.space.\n // =====================================================\n #ifdef RENDERER_LVL_MODULE_ENABLED\n // Precompute VOL in both spaces\n vec3 volAsLocal = volLocal + rotationByQuaternions(volWorld, invWorldRotation);\n vec3 volAsWorld = rotationByQuaternions(volLocal, worldRotation) + volWorld;\n\n float limitRand = a_Random2.w;\n float dampen = renderer_LVLDampen;\n // Frame-rate independent dampen (30fps as reference)\n float effectiveDampen = 1.0 - pow(1.0 - dampen, dt * 30.0);\n\n if (renderer_LVLSpace == 0) {\n // Local space: total = base + all VOL projected to local\n vec3 totalLocal = localVelocity + volAsLocal;\n vec3 dampenedTotal = applyLVLSpeedLimitTF(totalLocal, normalizedAge, limitRand, effectiveDampen);\n localVelocity = dampenedTotal - volAsLocal;\n } else {\n // World space: total = rotated base + all VOL projected to world\n vec3 totalWorld = rotationByQuaternions(localVelocity, worldRotation) + volAsWorld;\n vec3 dampenedTotal = applyLVLSpeedLimitTF(totalWorld, normalizedAge, limitRand, effectiveDampen);\n localVelocity = rotationByQuaternions(dampenedTotal - volAsWorld, invWorldRotation);\n }\n\n // Drag: same space as dampen\n {\n float dragCoeff = evaluateLVLDrag(normalizedAge, a_Random2.w);\n if (dragCoeff > 0.0) {\n vec3 totalVel;\n if (renderer_LVLSpace == 0) {\n totalVel = localVelocity + volAsLocal;\n } else {\n totalVel = rotationByQuaternions(localVelocity, worldRotation) + volAsWorld;\n }\n float velMagSqr = dot(totalVel, totalVel);\n float velMag = sqrt(velMagSqr);\n\n float drag = dragCoeff;\n\n #ifdef RENDERER_LVL_DRAG_MULTIPLY_SIZE\n float maxDim = max(a_StartSize.x, max(a_StartSize.y, a_StartSize.z));\n float radius = maxDim * 0.5;\n drag *= 3.14159265 * radius * radius;\n #endif\n\n #ifdef RENDERER_LVL_DRAG_MULTIPLY_VELOCITY\n drag *= velMagSqr;\n #endif\n\n if (velMag > 0.0) {\n float newVelMag = max(0.0, velMag - drag * dt);\n vec3 draggedTotal = totalVel * (newVelMag / velMag);\n if (renderer_LVLSpace == 0) {\n localVelocity = draggedTotal - volAsLocal;\n } else {\n localVelocity = rotationByQuaternions(draggedTotal - volAsWorld, invWorldRotation);\n }\n }\n }\n }\n #endif\n\n // =====================================================\n // Step 4: Integrate position in simulation space\n // Local mode: position in local space, velocity rotated to local\n // World mode: position in world space, velocity rotated to world\n // =====================================================\n // FOL is now fully in localVelocity (both local and world-space FOL).\n // VOL and Noise overlays are added here (not persisted).\n\n vec3 totalVelocity;\n if (renderer_SimulationSpace == 0) {\n totalVelocity = localVelocity + volLocal + rotationByQuaternions(volWorld, invWorldRotation);\n } else {\n totalVelocity = rotationByQuaternions(localVelocity + volLocal, worldRotation) + volWorld;\n }\n #ifdef RENDERER_NOISE_MODULE_ENABLED\n // Noise velocity overlay (not persisted)\n // computeNoiseDisplacement returns noise * strength (position-scale)\n // Dividing by lifetime converts to velocity so that integration over lifetime\n // recovers the original displacement magnitude\n // Use analytical base position (birth + initial velocity * age) instead of\n // a_FeedbackPosition to avoid feedback loop: position → noise → velocity → position\n vec3 noiseBasePos;\n if (renderer_SimulationSpace == 0) {\n noiseBasePos = a_ShapePositionStartLifeTime.xyz + a_DirectionTime.xyz * a_StartSpeed * age;\n } else {\n noiseBasePos = rotationByQuaternions(\n a_ShapePositionStartLifeTime.xyz + a_DirectionTime.xyz * a_StartSpeed * age,\n worldRotation) + a_SimulationWorldPosition;\n }\n totalVelocity += computeNoiseDisplacement(noiseBasePos, normalizedAge) / lifetime;\n #endif\n vec3 position = a_FeedbackPosition + totalVelocity * dt;\n\n v_FeedbackPosition = position;\n v_FeedbackVelocity = localVelocity;\n gl_Position = vec4(0.0);\n}\n"; // eslint-disable-line
|
|
4922
4930
|
|
|
4923
4931
|
var sphere_billboard = "#ifdef RENDERER_MODE_SPHERE_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n\tvec3 sideVector = normalize(cross(camera_Forward, camera_Up));\n\tvec3 upVector = normalize(cross(sideVector, camera_Forward));\n\tcorner *= computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n if (renderer_ThreeDStartRotation) {\n vec3 rotation = radians(vec3(a_StartRotation0.xy, computeParticleRotationFloat(a_StartRotation0.z, age, normalizedAge)));\n center += renderer_SizeScale.xzy * rotationByEuler(corner.x * sideVector + corner.y * upVector, rotation);\n } else {\n float rot = radians(computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge));\n float c = cos(rot);\n float s = sin(rot);\n mat2 rotation = mat2(c, -s, s, c);\n corner = rotation * corner;\n center += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n }\n #else\n if (renderer_ThreeDStartRotation) {\n center += renderer_SizeScale.xzy * rotationByEuler(corner.x * sideVector + corner.y * upVector, radians(a_StartRotation0));\n } else {\n float c = cos(radians(a_StartRotation0.x));\n float s = sin(radians(a_StartRotation0.x));\n mat2 rotation = mat2(c, -s, s, c);\n corner = rotation * corner;\n center += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n }\n #endif\n#endif"; // eslint-disable-line
|
|
4924
4932
|
|
|
@@ -4939,6 +4947,7 @@ var ParticleShaderLib = {
|
|
|
4939
4947
|
texture_sheet_animation_module: texture_sheet_animation_module,
|
|
4940
4948
|
force_over_lifetime_module: force_over_lifetime_module,
|
|
4941
4949
|
limit_velocity_over_lifetime_module: limit_velocity_over_lifetime_module,
|
|
4950
|
+
noise_module: noise_module,
|
|
4942
4951
|
particle_feedback_simulation: particle_feedback_simulation,
|
|
4943
4952
|
sphere_billboard: sphere_billboard,
|
|
4944
4953
|
stretched_billboard: stretched_billboard,
|
|
@@ -5787,26 +5796,492 @@ ShaderTagKey._nameMap = Object.create(null);
|
|
|
5787
5796
|
}();
|
|
5788
5797
|
ShaderProgram._counter = 0;
|
|
5789
5798
|
|
|
5799
|
+
function _array_like_to_array(arr, len) {
|
|
5800
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
5801
|
+
|
|
5802
|
+
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
5803
|
+
|
|
5804
|
+
return arr2;
|
|
5805
|
+
}
|
|
5806
|
+
|
|
5807
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
5808
|
+
if (!o) return;
|
|
5809
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
5810
|
+
|
|
5811
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
5812
|
+
|
|
5813
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
5814
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
5815
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
5816
|
+
}
|
|
5817
|
+
|
|
5818
|
+
function _create_for_of_iterator_helper_loose(o, allowArrayLike) {
|
|
5819
|
+
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
|
5820
|
+
|
|
5821
|
+
if (it) return (it = it.call(o)).next.bind(it);
|
|
5822
|
+
// Fallback for engines without symbol support
|
|
5823
|
+
if (Array.isArray(o) || (it = _unsupported_iterable_to_array(o)) || allowArrayLike && o && typeof o.length === "number") {
|
|
5824
|
+
if (it) o = it;
|
|
5825
|
+
|
|
5826
|
+
var i = 0;
|
|
5827
|
+
|
|
5828
|
+
return function() {
|
|
5829
|
+
if (i >= o.length) return { done: true };
|
|
5830
|
+
|
|
5831
|
+
return { done: false, value: o[i++] };
|
|
5832
|
+
};
|
|
5833
|
+
}
|
|
5834
|
+
|
|
5835
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
5836
|
+
}
|
|
5837
|
+
|
|
5838
|
+
/**
|
|
5839
|
+
* Directive types for shader preprocessor instructions.
|
|
5840
|
+
*/ var ShaderPreprocessorDirective = /*#__PURE__*/ function(ShaderPreprocessorDirective) {
|
|
5841
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["Text"] = 0] = "Text";
|
|
5842
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["IfDef"] = 1] = "IfDef";
|
|
5843
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["IfNdef"] = 2] = "IfNdef";
|
|
5844
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["IfCmp"] = 3] = "IfCmp";
|
|
5845
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["IfExpr"] = 4] = "IfExpr";
|
|
5846
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["Else"] = 5] = "Else";
|
|
5847
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["Endif"] = 6] = "Endif";
|
|
5848
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["Define"] = 7] = "Define";
|
|
5849
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["DefineVal"] = 8] = "DefineVal";
|
|
5850
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["DefineFunc"] = 9] = "DefineFunc";
|
|
5851
|
+
ShaderPreprocessorDirective[ShaderPreprocessorDirective["Undef"] = 10] = "Undef";
|
|
5852
|
+
return ShaderPreprocessorDirective;
|
|
5853
|
+
}({});
|
|
5854
|
+
|
|
5855
|
+
/**
|
|
5856
|
+
* @internal
|
|
5857
|
+
*/ var ShaderMacroProcessor = /*#__PURE__*/ function() {
|
|
5858
|
+
function ShaderMacroProcessor() {}
|
|
5859
|
+
/**
|
|
5860
|
+
* Evaluate a flat instruction array with active macros.
|
|
5861
|
+
* Macros are expanded immediately when text chunks are collected,
|
|
5862
|
+
* using the current macro state at that point (conforming to GLSL/C99 §6.10 standard).
|
|
5863
|
+
* @param instructions - Pre-parsed instruction array
|
|
5864
|
+
* @param macros - Active runtime macros
|
|
5865
|
+
* @returns Pure GLSL string with all conditionals resolved and macros expanded
|
|
5866
|
+
*/ ShaderMacroProcessor.evaluate = function evaluate(instructions, macros) {
|
|
5867
|
+
var valueMacros = ShaderMacroProcessor._valueMacros;
|
|
5868
|
+
var funcMacros = ShaderMacroProcessor._funcMacros;
|
|
5869
|
+
var shaderChunks = ShaderMacroProcessor._shaderChunks;
|
|
5870
|
+
valueMacros.clear();
|
|
5871
|
+
funcMacros.clear();
|
|
5872
|
+
shaderChunks.length = 0;
|
|
5873
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(macros), _step; !(_step = _iterator()).done;){
|
|
5874
|
+
var _step_value = _step.value, name = _step_value[0], value = _step_value[1];
|
|
5875
|
+
valueMacros.set(name, value);
|
|
5876
|
+
}
|
|
5877
|
+
ShaderMacroProcessor._macroFirstCharsDirty = true;
|
|
5878
|
+
var index = 0;
|
|
5879
|
+
var length = instructions.length;
|
|
5880
|
+
while(index < length){
|
|
5881
|
+
var instruction = instructions[index];
|
|
5882
|
+
switch(instruction[0]){
|
|
5883
|
+
case ShaderPreprocessorDirective.Text:
|
|
5884
|
+
// Immediately expand macros using current macro state (GLSL/C99 conformant)
|
|
5885
|
+
shaderChunks.push(ShaderMacroProcessor._expandChunk(instruction[1], valueMacros, funcMacros));
|
|
5886
|
+
index++;
|
|
5887
|
+
break;
|
|
5888
|
+
case ShaderPreprocessorDirective.IfDef:
|
|
5889
|
+
{
|
|
5890
|
+
var name1 = instruction[1];
|
|
5891
|
+
index = valueMacros.has(name1) || funcMacros.has(name1) ? index + 1 : instruction[2];
|
|
5892
|
+
break;
|
|
5893
|
+
}
|
|
5894
|
+
case ShaderPreprocessorDirective.IfNdef:
|
|
5895
|
+
{
|
|
5896
|
+
var name2 = instruction[1];
|
|
5897
|
+
index = !valueMacros.has(name2) && !funcMacros.has(name2) ? index + 1 : instruction[2];
|
|
5898
|
+
break;
|
|
5899
|
+
}
|
|
5900
|
+
case ShaderPreprocessorDirective.IfCmp:
|
|
5901
|
+
{
|
|
5902
|
+
var name3 = instruction[1];
|
|
5903
|
+
var val = valueMacros.get(name3);
|
|
5904
|
+
var matched = val !== undefined && ShaderMacroProcessor._compareValues(Number(val) || 0, instruction[2], instruction[3]);
|
|
5905
|
+
index = matched ? index + 1 : instruction[4];
|
|
5906
|
+
break;
|
|
5907
|
+
}
|
|
5908
|
+
case ShaderPreprocessorDirective.IfExpr:
|
|
5909
|
+
index = ShaderMacroProcessor._evalCondition(instruction[1], valueMacros, funcMacros) ? index + 1 : instruction[2];
|
|
5910
|
+
break;
|
|
5911
|
+
case ShaderPreprocessorDirective.Else:
|
|
5912
|
+
index = instruction[1];
|
|
5913
|
+
break;
|
|
5914
|
+
case ShaderPreprocessorDirective.Endif:
|
|
5915
|
+
index++;
|
|
5916
|
+
break;
|
|
5917
|
+
case ShaderPreprocessorDirective.Define:
|
|
5918
|
+
valueMacros.set(instruction[1], "");
|
|
5919
|
+
index++;
|
|
5920
|
+
break;
|
|
5921
|
+
case ShaderPreprocessorDirective.DefineVal:
|
|
5922
|
+
valueMacros.set(instruction[1], instruction[2]);
|
|
5923
|
+
ShaderMacroProcessor._macroFirstCharsDirty = true;
|
|
5924
|
+
index++;
|
|
5925
|
+
break;
|
|
5926
|
+
case ShaderPreprocessorDirective.DefineFunc:
|
|
5927
|
+
funcMacros.set(instruction[1], {
|
|
5928
|
+
params: instruction[2],
|
|
5929
|
+
body: instruction[3]
|
|
5930
|
+
});
|
|
5931
|
+
ShaderMacroProcessor._macroFirstCharsDirty = true;
|
|
5932
|
+
index++;
|
|
5933
|
+
break;
|
|
5934
|
+
case ShaderPreprocessorDirective.Undef:
|
|
5935
|
+
valueMacros.delete(instruction[1]);
|
|
5936
|
+
funcMacros.delete(instruction[1]);
|
|
5937
|
+
index++;
|
|
5938
|
+
break;
|
|
5939
|
+
default:
|
|
5940
|
+
index++;
|
|
5941
|
+
break;
|
|
5942
|
+
}
|
|
5943
|
+
}
|
|
5944
|
+
return ShaderMacroProcessor._concatChunks(shaderChunks);
|
|
5945
|
+
};
|
|
5946
|
+
/**
|
|
5947
|
+
* Expand macros in a single text chunk using the current macro state.
|
|
5948
|
+
* Returns the chunk as-is if no expandable macros exist.
|
|
5949
|
+
*/ ShaderMacroProcessor._expandChunk = function _expandChunk(chunk, valueMacros, funcMacros) {
|
|
5950
|
+
// Fast path: no expandable macros at this point
|
|
5951
|
+
if (funcMacros.size === 0) {
|
|
5952
|
+
var hasExpandable = false;
|
|
5953
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(valueMacros), _step; !(_step = _iterator()).done;){
|
|
5954
|
+
var _step_value = _step.value, val = _step_value[1];
|
|
5955
|
+
if (val !== "") {
|
|
5956
|
+
hasExpandable = true;
|
|
5957
|
+
break;
|
|
5958
|
+
}
|
|
5959
|
+
}
|
|
5960
|
+
if (!hasExpandable) return chunk;
|
|
5961
|
+
}
|
|
5962
|
+
// Rebuild first-char filter if macros changed
|
|
5963
|
+
if (ShaderMacroProcessor._macroFirstCharsDirty) {
|
|
5964
|
+
var macroFirstChars = ShaderMacroProcessor._macroFirstChars;
|
|
5965
|
+
macroFirstChars.clear();
|
|
5966
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(valueMacros.keys()), _step1; !(_step1 = _iterator1()).done;){
|
|
5967
|
+
var name = _step1.value;
|
|
5968
|
+
macroFirstChars.add(name.charCodeAt(0));
|
|
5969
|
+
}
|
|
5970
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(funcMacros.keys()), _step2; !(_step2 = _iterator2()).done;){
|
|
5971
|
+
var name1 = _step2.value;
|
|
5972
|
+
macroFirstChars.add(name1.charCodeAt(0));
|
|
5973
|
+
}
|
|
5974
|
+
ShaderMacroProcessor._macroFirstCharsDirty = false;
|
|
5975
|
+
}
|
|
5976
|
+
var macroFirstChars1 = ShaderMacroProcessor._macroFirstChars;
|
|
5977
|
+
var expandedNames = ShaderMacroProcessor._expandedNames;
|
|
5978
|
+
var out = ShaderMacroProcessor._out;
|
|
5979
|
+
out.length = 0;
|
|
5980
|
+
var len = chunk.length;
|
|
5981
|
+
var i = 0;
|
|
5982
|
+
while(i < len){
|
|
5983
|
+
var cc = chunk.charCodeAt(i);
|
|
5984
|
+
if (ShaderMacroProcessor._isIdentifierStart(cc)) {
|
|
5985
|
+
var start = i;
|
|
5986
|
+
i++;
|
|
5987
|
+
while(i < len && ShaderMacroProcessor._isIdentifierPart(chunk.charCodeAt(i)))i++;
|
|
5988
|
+
// Fast path: first char not in any macro name
|
|
5989
|
+
if (!macroFirstChars1.has(chunk.charCodeAt(start))) {
|
|
5990
|
+
out.push(chunk.substring(start, i));
|
|
5991
|
+
continue;
|
|
5992
|
+
}
|
|
5993
|
+
var name2 = chunk.substring(start, i);
|
|
5994
|
+
// Try function macro
|
|
5995
|
+
var func = funcMacros.get(name2);
|
|
5996
|
+
if (func) {
|
|
5997
|
+
var lookAhead = i;
|
|
5998
|
+
while(lookAhead < len && (chunk.charCodeAt(lookAhead) === 32 /* space */ || chunk.charCodeAt(lookAhead) === 9))lookAhead++;
|
|
5999
|
+
if (lookAhead < len && chunk.charCodeAt(lookAhead) === 40 /* '(' */ ) {
|
|
6000
|
+
var args = ShaderMacroProcessor._parseFuncArgs(chunk, lookAhead);
|
|
6001
|
+
if (args) {
|
|
6002
|
+
i = args.end;
|
|
6003
|
+
var expanded = ShaderMacroProcessor._expandFuncBody(func, args.values);
|
|
6004
|
+
expandedNames.clear();
|
|
6005
|
+
expandedNames.add(name2);
|
|
6006
|
+
out.push(ShaderMacroProcessor._recursiveExpandMacro(expanded, valueMacros, funcMacros, expandedNames));
|
|
6007
|
+
continue;
|
|
6008
|
+
}
|
|
6009
|
+
}
|
|
6010
|
+
}
|
|
6011
|
+
// Try value macro
|
|
6012
|
+
var val1 = valueMacros.get(name2);
|
|
6013
|
+
if (val1 !== undefined && val1 !== "") {
|
|
6014
|
+
expandedNames.clear();
|
|
6015
|
+
expandedNames.add(name2);
|
|
6016
|
+
out.push(ShaderMacroProcessor._recursiveExpandMacro(val1, valueMacros, funcMacros, expandedNames));
|
|
6017
|
+
continue;
|
|
6018
|
+
}
|
|
6019
|
+
out.push(name2);
|
|
6020
|
+
continue;
|
|
6021
|
+
}
|
|
6022
|
+
// Batch collect non-identifier characters
|
|
6023
|
+
var batchStart = i;
|
|
6024
|
+
while(i < len && !ShaderMacroProcessor._isIdentifierStart(chunk.charCodeAt(i)))i++;
|
|
6025
|
+
out.push(chunk.substring(batchStart, i));
|
|
6026
|
+
}
|
|
6027
|
+
return out.join("");
|
|
6028
|
+
};
|
|
6029
|
+
/**
|
|
6030
|
+
* Recursively expand macro substitution results until no more macros remain.
|
|
6031
|
+
* @param macroExpansion - Intermediate text from a macro substitution that may contain further macro references
|
|
6032
|
+
* @param valueMacros - Current value macro definitions
|
|
6033
|
+
* @param funcMacros - Current function macro definitions
|
|
6034
|
+
* @param expandedNames - Macro names already on the expansion chain, prevents circular references (C99 §6.10.3.4)
|
|
6035
|
+
*/ ShaderMacroProcessor._recursiveExpandMacro = function _recursiveExpandMacro(macroExpansion, valueMacros, funcMacros, expandedNames) {
|
|
6036
|
+
if (macroExpansion.length === 0) return macroExpansion;
|
|
6037
|
+
var len = macroExpansion.length;
|
|
6038
|
+
var out = [];
|
|
6039
|
+
var i = 0;
|
|
6040
|
+
while(i < len){
|
|
6041
|
+
var cc = macroExpansion.charCodeAt(i);
|
|
6042
|
+
if (ShaderMacroProcessor._isIdentifierStart(cc)) {
|
|
6043
|
+
var start = i;
|
|
6044
|
+
i++;
|
|
6045
|
+
while(i < len && ShaderMacroProcessor._isIdentifierPart(macroExpansion.charCodeAt(i)))i++;
|
|
6046
|
+
var name = macroExpansion.substring(start, i);
|
|
6047
|
+
// Skip already-expanded names (circular reference prevention)
|
|
6048
|
+
// Skip GL_ prefixed names (reserved GLSL built-ins, charCodes: G=71, L=76, _=95)
|
|
6049
|
+
if (expandedNames.has(name) || name.charCodeAt(0) === 71 && name.charCodeAt(1) === 76 && name.charCodeAt(2) === 95) {
|
|
6050
|
+
out.push(name);
|
|
6051
|
+
continue;
|
|
6052
|
+
}
|
|
6053
|
+
var func = funcMacros.get(name);
|
|
6054
|
+
if (func) {
|
|
6055
|
+
var lookAhead = i;
|
|
6056
|
+
while(lookAhead < len && (macroExpansion.charCodeAt(lookAhead) === 32 /* space */ || macroExpansion.charCodeAt(lookAhead) === 9))lookAhead++;
|
|
6057
|
+
if (lookAhead < len && macroExpansion.charCodeAt(lookAhead) === 40 /* '(' */ ) {
|
|
6058
|
+
var args = ShaderMacroProcessor._parseFuncArgs(macroExpansion, lookAhead);
|
|
6059
|
+
if (args) {
|
|
6060
|
+
i = args.end;
|
|
6061
|
+
expandedNames.add(name);
|
|
6062
|
+
out.push(ShaderMacroProcessor._recursiveExpandMacro(ShaderMacroProcessor._expandFuncBody(func, args.values), valueMacros, funcMacros, expandedNames));
|
|
6063
|
+
expandedNames.delete(name);
|
|
6064
|
+
continue;
|
|
6065
|
+
}
|
|
6066
|
+
}
|
|
6067
|
+
}
|
|
6068
|
+
var val = valueMacros.get(name);
|
|
6069
|
+
if (val !== undefined && val !== "") {
|
|
6070
|
+
expandedNames.add(name);
|
|
6071
|
+
out.push(ShaderMacroProcessor._recursiveExpandMacro(val, valueMacros, funcMacros, expandedNames));
|
|
6072
|
+
expandedNames.delete(name);
|
|
6073
|
+
continue;
|
|
6074
|
+
}
|
|
6075
|
+
out.push(name);
|
|
6076
|
+
continue;
|
|
6077
|
+
}
|
|
6078
|
+
// Batch collect non-identifier characters
|
|
6079
|
+
var batchStart = i;
|
|
6080
|
+
while(i < len && !ShaderMacroProcessor._isIdentifierStart(macroExpansion.charCodeAt(i)))i++;
|
|
6081
|
+
out.push(macroExpansion.substring(batchStart, i));
|
|
6082
|
+
}
|
|
6083
|
+
return out.join("");
|
|
6084
|
+
};
|
|
6085
|
+
/**
|
|
6086
|
+
* Substitute function macro params in body.
|
|
6087
|
+
*/ ShaderMacroProcessor._expandFuncBody = function _expandFuncBody(func, args) {
|
|
6088
|
+
if (func.params.length === 0 || args.length !== func.params.length) return func.body;
|
|
6089
|
+
var result = func.body;
|
|
6090
|
+
for(var i = 0; i < func.params.length; i++){
|
|
6091
|
+
result = ShaderMacroProcessor._replaceWord(result, func.params[i], args[i]);
|
|
6092
|
+
}
|
|
6093
|
+
return result;
|
|
6094
|
+
};
|
|
6095
|
+
/**
|
|
6096
|
+
* Evaluate a compound condition tree.
|
|
6097
|
+
*/ ShaderMacroProcessor._evalCondition = function _evalCondition(cond, valueMacros, funcMacros) {
|
|
6098
|
+
switch(cond.t){
|
|
6099
|
+
case "def":
|
|
6100
|
+
return valueMacros.has(cond.m) || funcMacros.has(cond.m);
|
|
6101
|
+
case "ndef":
|
|
6102
|
+
return !valueMacros.has(cond.m) && !funcMacros.has(cond.m);
|
|
6103
|
+
case "cmp":
|
|
6104
|
+
{
|
|
6105
|
+
var val = valueMacros.get(cond.m);
|
|
6106
|
+
if (val === undefined) return false;
|
|
6107
|
+
return ShaderMacroProcessor._compareValues(Number(val) || 0, cond.op, cond.v);
|
|
6108
|
+
}
|
|
6109
|
+
case "and":
|
|
6110
|
+
return ShaderMacroProcessor._evalCondition(cond.l, valueMacros, funcMacros) && ShaderMacroProcessor._evalCondition(cond.r, valueMacros, funcMacros);
|
|
6111
|
+
case "or":
|
|
6112
|
+
return ShaderMacroProcessor._evalCondition(cond.l, valueMacros, funcMacros) || ShaderMacroProcessor._evalCondition(cond.r, valueMacros, funcMacros);
|
|
6113
|
+
case "not":
|
|
6114
|
+
return !ShaderMacroProcessor._evalCondition(cond.c, valueMacros, funcMacros);
|
|
6115
|
+
case "bool":
|
|
6116
|
+
return cond.v;
|
|
6117
|
+
}
|
|
6118
|
+
};
|
|
6119
|
+
/**
|
|
6120
|
+
* Evaluate a comparison operator.
|
|
6121
|
+
*/ ShaderMacroProcessor._compareValues = function _compareValues(numVal, op, value) {
|
|
6122
|
+
switch(op){
|
|
6123
|
+
case "==":
|
|
6124
|
+
return numVal === value;
|
|
6125
|
+
case "!=":
|
|
6126
|
+
return numVal !== value;
|
|
6127
|
+
case ">":
|
|
6128
|
+
return numVal > value;
|
|
6129
|
+
case "<":
|
|
6130
|
+
return numVal < value;
|
|
6131
|
+
case ">=":
|
|
6132
|
+
return numVal >= value;
|
|
6133
|
+
case "<=":
|
|
6134
|
+
return numVal <= value;
|
|
6135
|
+
default:
|
|
6136
|
+
return false;
|
|
6137
|
+
}
|
|
6138
|
+
};
|
|
6139
|
+
/**
|
|
6140
|
+
* Parse function macro call arguments.
|
|
6141
|
+
* Returns reusable static result object to avoid allocation.
|
|
6142
|
+
*/ ShaderMacroProcessor._parseFuncArgs = function _parseFuncArgs(text, openParen) {
|
|
6143
|
+
var result = ShaderMacroProcessor._parsedFuncArgs;
|
|
6144
|
+
result.values.length = 0;
|
|
6145
|
+
var level = 1;
|
|
6146
|
+
var argStart = openParen + 1;
|
|
6147
|
+
var k = argStart;
|
|
6148
|
+
var len = text.length;
|
|
6149
|
+
while(k < len && level > 0){
|
|
6150
|
+
var cc = text.charCodeAt(k);
|
|
6151
|
+
if (cc === 40 /* '(' */ ) {
|
|
6152
|
+
level++;
|
|
6153
|
+
} else if (cc === 41 /* ')' */ ) {
|
|
6154
|
+
if (--level === 0) {
|
|
6155
|
+
var arg = text.substring(argStart, k).trim();
|
|
6156
|
+
if (arg.length > 0 || result.values.length > 0) result.values.push(arg);
|
|
6157
|
+
result.end = k + 1;
|
|
6158
|
+
return result;
|
|
6159
|
+
}
|
|
6160
|
+
} else if (cc === 44 /* ',' */ && level === 1) {
|
|
6161
|
+
result.values.push(text.substring(argStart, k).trim());
|
|
6162
|
+
argStart = k + 1;
|
|
6163
|
+
}
|
|
6164
|
+
k++;
|
|
6165
|
+
}
|
|
6166
|
+
return null;
|
|
6167
|
+
};
|
|
6168
|
+
/**
|
|
6169
|
+
* Replace all whole-word occurrences of `word` in `text` with `replacement`.
|
|
6170
|
+
*/ ShaderMacroProcessor._replaceWord = function _replaceWord(text, word, replacement) {
|
|
6171
|
+
var wLen = word.length;
|
|
6172
|
+
var parts = ShaderMacroProcessor._replaceWordParts;
|
|
6173
|
+
parts.length = 0;
|
|
6174
|
+
var start = 0;
|
|
6175
|
+
var idx = text.indexOf(word, start);
|
|
6176
|
+
while(idx !== -1){
|
|
6177
|
+
if (idx > 0 && ShaderMacroProcessor._isIdentifierPart(text.charCodeAt(idx - 1))) {
|
|
6178
|
+
idx = text.indexOf(word, idx + 1);
|
|
6179
|
+
continue;
|
|
6180
|
+
}
|
|
6181
|
+
var afterIdx = idx + wLen;
|
|
6182
|
+
if (afterIdx < text.length && ShaderMacroProcessor._isIdentifierPart(text.charCodeAt(afterIdx))) {
|
|
6183
|
+
idx = text.indexOf(word, idx + 1);
|
|
6184
|
+
continue;
|
|
6185
|
+
}
|
|
6186
|
+
parts.push(text.substring(start, idx));
|
|
6187
|
+
parts.push(replacement);
|
|
6188
|
+
start = afterIdx;
|
|
6189
|
+
idx = text.indexOf(word, start);
|
|
6190
|
+
}
|
|
6191
|
+
if (start === 0) return text;
|
|
6192
|
+
parts.push(text.substring(start));
|
|
6193
|
+
return parts.join("");
|
|
6194
|
+
};
|
|
6195
|
+
/**
|
|
6196
|
+
* Concatenate shader chunks with consecutive blank lines collapsed to a single newline.
|
|
6197
|
+
*/ ShaderMacroProcessor._concatChunks = function _concatChunks(shaderChunks) {
|
|
6198
|
+
var out = ShaderMacroProcessor._out;
|
|
6199
|
+
out.length = 0;
|
|
6200
|
+
var lastNewline = false;
|
|
6201
|
+
for(var p = 0; p < shaderChunks.length; p++){
|
|
6202
|
+
var text = shaderChunks[p];
|
|
6203
|
+
var len = text.length;
|
|
6204
|
+
var i = 0;
|
|
6205
|
+
while(i < len){
|
|
6206
|
+
if (text.charCodeAt(i) === 10 /* \n */ ) {
|
|
6207
|
+
if (!lastNewline) {
|
|
6208
|
+
out.push("\n");
|
|
6209
|
+
lastNewline = true;
|
|
6210
|
+
}
|
|
6211
|
+
i++;
|
|
6212
|
+
while(i < len){
|
|
6213
|
+
var c = text.charCodeAt(i);
|
|
6214
|
+
if (c === 32 /* space */ || c === 9 /* tab */ || c === 10 /* \n */ ) i++;
|
|
6215
|
+
else break;
|
|
6216
|
+
}
|
|
6217
|
+
} else {
|
|
6218
|
+
var batchStart = i;
|
|
6219
|
+
while(i < len && text.charCodeAt(i) !== 10 /* \n */ )i++;
|
|
6220
|
+
out.push(text.substring(batchStart, i));
|
|
6221
|
+
lastNewline = false;
|
|
6222
|
+
}
|
|
6223
|
+
}
|
|
6224
|
+
}
|
|
6225
|
+
return out.join("");
|
|
6226
|
+
};
|
|
6227
|
+
/**
|
|
6228
|
+
* Check if char code is a valid identifier start.
|
|
6229
|
+
* Matches: [A-Z] | [a-z] | _
|
|
6230
|
+
*/ ShaderMacroProcessor._isIdentifierStart = function _isIdentifierStart(charCode) {
|
|
6231
|
+
return charCode >= 65 && charCode <= 90 || charCode >= 97 && charCode <= 122 || charCode === 95;
|
|
6232
|
+
};
|
|
6233
|
+
/**
|
|
6234
|
+
* Check if char code is a valid identifier part.
|
|
6235
|
+
* Matches: [A-Z] | [a-z] | [0-9] | _
|
|
6236
|
+
*/ ShaderMacroProcessor._isIdentifierPart = function _isIdentifierPart(charCode) {
|
|
6237
|
+
return charCode >= 65 && charCode <= 90 || charCode >= 97 && charCode <= 122 || charCode >= 48 && charCode <= 57 || charCode === 95;
|
|
6238
|
+
};
|
|
6239
|
+
return ShaderMacroProcessor;
|
|
6240
|
+
}();
|
|
6241
|
+
ShaderMacroProcessor._valueMacros = new Map();
|
|
6242
|
+
ShaderMacroProcessor._funcMacros = new Map();
|
|
6243
|
+
ShaderMacroProcessor._shaderChunks = [];
|
|
6244
|
+
ShaderMacroProcessor._out = [];
|
|
6245
|
+
ShaderMacroProcessor._expandedNames = new Set();
|
|
6246
|
+
ShaderMacroProcessor._macroFirstChars = new Set();
|
|
6247
|
+
ShaderMacroProcessor._macroFirstCharsDirty = true;
|
|
6248
|
+
ShaderMacroProcessor._replaceWordParts = [];
|
|
6249
|
+
ShaderMacroProcessor._parsedFuncArgs = {
|
|
6250
|
+
values: [],
|
|
6251
|
+
end: 0
|
|
6252
|
+
};
|
|
6253
|
+
|
|
5790
6254
|
var precisionStr = "\n #ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n precision highp int;\n #else\n precision mediump float;\n precision mediump int;\n #endif\n ";
|
|
5791
6255
|
/**
|
|
5792
6256
|
* Shader pass containing vertex and fragment source.
|
|
5793
6257
|
*/ var ShaderPass = /*#__PURE__*/ function(ShaderPart) {
|
|
5794
6258
|
_inherits(ShaderPass, ShaderPart);
|
|
5795
|
-
function ShaderPass(nameOrVertexSource,
|
|
6259
|
+
function ShaderPass(nameOrVertexSource, vertexSourceOrFragmentSourceOrInstructions, fragmentSourceOrTags, tagsOrPlatformTarget, tags) {
|
|
5796
6260
|
var _this;
|
|
5797
6261
|
_this = ShaderPart.call(this) || this, /** @internal */ _this._shaderPassId = 0, /** @internal */ _this._renderStateDataMap = {}, /** @internal */ _this._shaderProgramPools = [];
|
|
5798
6262
|
_this._shaderPassId = ShaderPass._shaderPassCounter++;
|
|
5799
|
-
if (
|
|
6263
|
+
if (Array.isArray(vertexSourceOrFragmentSourceOrInstructions)) {
|
|
6264
|
+
// Instructions overload: (name, vertexInst, fragInst, platformTarget, tags?)
|
|
5800
6265
|
_this._name = nameOrVertexSource;
|
|
5801
|
-
_this.
|
|
5802
|
-
_this.
|
|
6266
|
+
_this._vertexShaderInstructions = vertexSourceOrFragmentSourceOrInstructions;
|
|
6267
|
+
_this._fragmentShaderInstructions = fragmentSourceOrTags;
|
|
6268
|
+
_this._platformTarget = tagsOrPlatformTarget;
|
|
5803
6269
|
tags = _extends({
|
|
5804
6270
|
pipelineStage: PipelineStage.Forward
|
|
5805
6271
|
}, tags);
|
|
6272
|
+
} else if (typeof fragmentSourceOrTags === "string") {
|
|
6273
|
+
// Named overload: (name, vertexSource, fragmentSource, tags?)
|
|
6274
|
+
_this._name = nameOrVertexSource;
|
|
6275
|
+
_this._vertexSource = vertexSourceOrFragmentSourceOrInstructions;
|
|
6276
|
+
_this._fragmentSource = fragmentSourceOrTags;
|
|
6277
|
+
tags = _extends({
|
|
6278
|
+
pipelineStage: PipelineStage.Forward
|
|
6279
|
+
}, tagsOrPlatformTarget);
|
|
5806
6280
|
} else {
|
|
6281
|
+
// Unnamed overload: (vertexSource, fragmentSource, tags?)
|
|
5807
6282
|
_this._name = "Default";
|
|
5808
6283
|
_this._vertexSource = nameOrVertexSource;
|
|
5809
|
-
_this._fragmentSource =
|
|
6284
|
+
_this._fragmentSource = vertexSourceOrFragmentSourceOrInstructions;
|
|
5810
6285
|
tags = _extends({
|
|
5811
6286
|
pipelineStage: PipelineStage.Forward
|
|
5812
6287
|
}, fragmentSourceOrTags);
|
|
@@ -5842,15 +6317,16 @@ var precisionStr = "\n #ifdef GL_FRAGMENT_PRECISION_HIGH\n precision hig
|
|
|
5842
6317
|
shaderProgramPools.length = 0;
|
|
5843
6318
|
};
|
|
5844
6319
|
_proto._getCanonicalShaderProgram = function _getCanonicalShaderProgram(engine, macroCollection) {
|
|
5845
|
-
|
|
5846
|
-
return this._getShaderLabProgram(engine, macroCollection);
|
|
5847
|
-
}
|
|
5848
|
-
var _ShaderFactory_compilePlatformSource = ShaderFactory.compilePlatformSource(engine, macroCollection, this._vertexSource, this._fragmentSource), vertexSource = _ShaderFactory_compilePlatformSource.vertexSource, fragmentSource = _ShaderFactory_compilePlatformSource.fragmentSource;
|
|
6320
|
+
var _ref = this._platformTarget != undefined ? this._compileShaderLabSource(engine, macroCollection) : this._compilePlatformSource(engine, macroCollection), vertexSource = _ref.vertexSource, fragmentSource = _ref.fragmentSource;
|
|
5849
6321
|
return new ShaderProgram(engine, vertexSource, fragmentSource);
|
|
5850
6322
|
};
|
|
5851
|
-
_proto.
|
|
6323
|
+
_proto._compilePlatformSource = function _compilePlatformSource(engine, macroCollection) {
|
|
6324
|
+
return ShaderFactory.compilePlatformSource(engine, macroCollection, this._vertexSource, this._fragmentSource);
|
|
6325
|
+
};
|
|
6326
|
+
_proto._compileShaderLabSource = function _compileShaderLabSource(engine, macroCollection) {
|
|
5852
6327
|
var isWebGL2 = engine._hardwareRenderer.isWebGL2;
|
|
5853
|
-
var shaderMacroList =
|
|
6328
|
+
var shaderMacroList = ShaderPass._shaderMacroList;
|
|
6329
|
+
shaderMacroList.length = 0;
|
|
5854
6330
|
ShaderMacro._getMacrosElements(macroCollection, shaderMacroList);
|
|
5855
6331
|
shaderMacroList.push(ShaderMacro.getByName(isWebGL2 ? "GRAPHICS_API_WEBGL2" : "GRAPHICS_API_WEBGL1"));
|
|
5856
6332
|
if (engine._hardwareRenderer.canIUse(GLCapabilityType.shaderTextureLod)) {
|
|
@@ -5859,23 +6335,31 @@ var precisionStr = "\n #ifdef GL_FRAGMENT_PRECISION_HIGH\n precision hig
|
|
|
5859
6335
|
if (engine._hardwareRenderer.canIUse(GLCapabilityType.standardDerivatives)) {
|
|
5860
6336
|
shaderMacroList.push(ShaderMacro.getByName("HAS_DERIVATIVES"));
|
|
5861
6337
|
}
|
|
5862
|
-
var
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
6338
|
+
var macroMap = ShaderPass._macroMap;
|
|
6339
|
+
macroMap.clear();
|
|
6340
|
+
for(var i = 0, n = shaderMacroList.length; i < n; i++){
|
|
6341
|
+
var macro = shaderMacroList[i];
|
|
6342
|
+
var _macro_value;
|
|
6343
|
+
macroMap.set(macro.name, (_macro_value = macro.value) != null ? _macro_value : "");
|
|
6344
|
+
}
|
|
6345
|
+
var vertexSource = ShaderMacroProcessor.evaluate(this._vertexShaderInstructions, macroMap);
|
|
6346
|
+
var fragmentSource = ShaderMacroProcessor.evaluate(this._fragmentShaderInstructions, macroMap);
|
|
5866
6347
|
if (isWebGL2 && this._platformTarget === ShaderLanguage.GLSLES100) {
|
|
5867
|
-
|
|
5868
|
-
|
|
6348
|
+
vertexSource = ShaderFactory.convertTo300(vertexSource);
|
|
6349
|
+
fragmentSource = ShaderFactory.convertTo300(fragmentSource, true);
|
|
5869
6350
|
}
|
|
5870
6351
|
var versionStr = isWebGL2 ? "#version 300 es" : "#version 100";
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
6352
|
+
return {
|
|
6353
|
+
vertexSource: " " + versionStr + "\n " + vertexSource + "\n ",
|
|
6354
|
+
fragmentSource: " " + versionStr + "\n " + (isWebGL2 ? "" : ShaderFactory._shaderExtension) + "\n " + precisionStr + "\n " + fragmentSource + "\n "
|
|
6355
|
+
};
|
|
5874
6356
|
};
|
|
5875
6357
|
return ShaderPass;
|
|
5876
6358
|
}(ShaderPart);
|
|
5877
6359
|
/** @internal */ ShaderPass._shaderPassCounter = 0;
|
|
5878
6360
|
/** @internal */ ShaderPass._shaderRootPath = "shaders://root/";
|
|
6361
|
+
ShaderPass._shaderMacroList = [];
|
|
6362
|
+
ShaderPass._macroMap = new Map();
|
|
5879
6363
|
|
|
5880
6364
|
/**
|
|
5881
6365
|
* Sub shader.
|
|
@@ -6624,36 +7108,14 @@ __decorate([
|
|
|
6624
7108
|
var subShaderList = shaderSource.subShaders.map(function(subShaderSource) {
|
|
6625
7109
|
var passList = subShaderSource.passes.map(function(passSource) {
|
|
6626
7110
|
if (passSource.isUsePass) {
|
|
6627
|
-
|
|
6628
|
-
var _passSource_name_split = passSource.name.split("/"), shaderName = _passSource_name_split[0], subShaderName = _passSource_name_split[1], passName = _passSource_name_split[2];
|
|
6629
|
-
return (_Shader_find = Shader.find(shaderName)) == null ? void 0 : (_Shader_find_subShaders_find = _Shader_find.subShaders.find(function(subShader) {
|
|
6630
|
-
return subShader.name === subShaderName;
|
|
6631
|
-
})) == null ? void 0 : _Shader_find_subShaders_find.passes.find(function(pass) {
|
|
6632
|
-
return pass.name === passName;
|
|
6633
|
-
});
|
|
7111
|
+
return Shader._resolveUsePass(passSource.name);
|
|
6634
7112
|
}
|
|
6635
7113
|
var shaderPassSource = Shader._shaderLab._parseShaderPass(passSource.contents, passSource.vertexEntry, passSource.fragmentEntry, vertexSourceOrShaderPassesOrSubShadersOrPlatformTarget, new URL(fragmentSourceOrPath != null ? fragmentSourceOrPath : "", ShaderPass._shaderRootPath).href);
|
|
6636
7114
|
if (!shaderPassSource) {
|
|
6637
7115
|
throw 'Shader pass "' + shaderSource.name + "." + subShaderSource.name + "." + passSource.name + '" parse failed, please check the shader source code.';
|
|
6638
7116
|
}
|
|
6639
|
-
var shaderPass = new ShaderPass(passSource.name, shaderPassSource.
|
|
6640
|
-
shaderPass.
|
|
6641
|
-
var _passSource_renderStates = passSource.renderStates, constantMap = _passSource_renderStates.constantMap, variableMap = _passSource_renderStates.variableMap;
|
|
6642
|
-
// Compatible shader lab no render state use material `renderState` to modify render state
|
|
6643
|
-
if (Object.keys(constantMap).length > 0 || Object.keys(variableMap).length > 0) {
|
|
6644
|
-
// Parse const render state
|
|
6645
|
-
var renderState = new RenderState();
|
|
6646
|
-
for(var k in constantMap){
|
|
6647
|
-
Shader._applyConstRenderStates(renderState, +k, constantMap[k]);
|
|
6648
|
-
}
|
|
6649
|
-
shaderPass._renderState = renderState;
|
|
6650
|
-
// Parse variable render state
|
|
6651
|
-
var renderStateDataMap = {};
|
|
6652
|
-
for(var k1 in variableMap){
|
|
6653
|
-
renderStateDataMap[k1] = ShaderProperty.getByName(variableMap[k1]);
|
|
6654
|
-
}
|
|
6655
|
-
shaderPass._renderStateDataMap = renderStateDataMap;
|
|
6656
|
-
}
|
|
7117
|
+
var shaderPass = new ShaderPass(passSource.name, shaderPassSource.vertexShaderInstructions, shaderPassSource.fragmentShaderInstructions, vertexSourceOrShaderPassesOrSubShadersOrPlatformTarget, passSource.tags);
|
|
7118
|
+
Shader._applyRenderStates(shaderPass, passSource.renderStates.constantMap, passSource.renderStates.variableMap, false);
|
|
6657
7119
|
return shaderPass;
|
|
6658
7120
|
});
|
|
6659
7121
|
return new SubShader(subShaderSource.name, passList, subShaderSource.tags);
|
|
@@ -6698,6 +7160,29 @@ __decorate([
|
|
|
6698
7160
|
};
|
|
6699
7161
|
/**
|
|
6700
7162
|
* @internal
|
|
7163
|
+
*/ Shader._createFromPrecompiled = function _createFromPrecompiled(data) {
|
|
7164
|
+
var shaderMap = Shader._shaderMap;
|
|
7165
|
+
if (shaderMap[data.name]) {
|
|
7166
|
+
console.error('Shader named "' + data.name + '" already exists.');
|
|
7167
|
+
return;
|
|
7168
|
+
}
|
|
7169
|
+
var subShaderList = data.subShaders.map(function(subData) {
|
|
7170
|
+
var passList = subData.passes.map(function(passData) {
|
|
7171
|
+
if (passData.isUsePass) {
|
|
7172
|
+
return Shader._resolveUsePass(passData.name);
|
|
7173
|
+
}
|
|
7174
|
+
var shaderPass = new ShaderPass(passData.name, passData.vertexShaderInstructions, passData.fragmentShaderInstructions, data.platformTarget, passData.tags);
|
|
7175
|
+
Shader._applyRenderStates(shaderPass, passData.renderStates.constantMap, passData.renderStates.variableMap, true);
|
|
7176
|
+
return shaderPass;
|
|
7177
|
+
});
|
|
7178
|
+
return new SubShader(subData.name, passList, subData.tags);
|
|
7179
|
+
});
|
|
7180
|
+
var shader = new Shader(data.name, subShaderList);
|
|
7181
|
+
shaderMap[data.name] = shader;
|
|
7182
|
+
return shader;
|
|
7183
|
+
};
|
|
7184
|
+
/**
|
|
7185
|
+
* @internal
|
|
6701
7186
|
*/ Shader._clear = function _clear(engine) {
|
|
6702
7187
|
var shaderMap = Shader._shaderMap;
|
|
6703
7188
|
for(var key in shaderMap){
|
|
@@ -6718,6 +7203,34 @@ __decorate([
|
|
|
6718
7203
|
}
|
|
6719
7204
|
}
|
|
6720
7205
|
};
|
|
7206
|
+
Shader._resolveUsePass = function _resolveUsePass(passName) {
|
|
7207
|
+
var _Shader_find_subShaders_find, _Shader_find;
|
|
7208
|
+
var _passName_split = passName.split("/"), shaderName = _passName_split[0], subShaderName = _passName_split[1], passNamePart = _passName_split[2];
|
|
7209
|
+
return (_Shader_find = Shader.find(shaderName)) == null ? void 0 : (_Shader_find_subShaders_find = _Shader_find.subShaders.find(function(subShader) {
|
|
7210
|
+
return subShader.name === subShaderName;
|
|
7211
|
+
})) == null ? void 0 : _Shader_find_subShaders_find.passes.find(function(pass) {
|
|
7212
|
+
return pass.name === passNamePart;
|
|
7213
|
+
});
|
|
7214
|
+
};
|
|
7215
|
+
Shader._applyRenderStates = function _applyRenderStates(shaderPass, constantMap, variableMap, deserializeColor) {
|
|
7216
|
+
if (Object.keys(constantMap).length > 0 || Object.keys(variableMap).length > 0) {
|
|
7217
|
+
var renderState = new RenderState();
|
|
7218
|
+
for(var k in constantMap){
|
|
7219
|
+
var value = constantMap[k];
|
|
7220
|
+
if (deserializeColor && Array.isArray(value)) {
|
|
7221
|
+
Shader._applyConstRenderStates(renderState, +k, new engineMath.Color(value[0], value[1], value[2], value[3]));
|
|
7222
|
+
} else {
|
|
7223
|
+
Shader._applyConstRenderStates(renderState, +k, value);
|
|
7224
|
+
}
|
|
7225
|
+
}
|
|
7226
|
+
shaderPass._renderState = renderState;
|
|
7227
|
+
var renderStateDataMap = {};
|
|
7228
|
+
for(var k1 in variableMap){
|
|
7229
|
+
renderStateDataMap[k1] = ShaderProperty.getByName(variableMap[k1]);
|
|
7230
|
+
}
|
|
7231
|
+
shaderPass._renderStateDataMap = renderStateDataMap;
|
|
7232
|
+
}
|
|
7233
|
+
};
|
|
6721
7234
|
Shader._applyConstRenderStates = function _applyConstRenderStates(renderState, key, value) {
|
|
6722
7235
|
switch(key){
|
|
6723
7236
|
case RenderStateElementKey.BlendStateEnabled0:
|
|
@@ -9158,7 +9671,15 @@ exports.Camera = /*#__PURE__*/ function(Component) {
|
|
|
9158
9671
|
*/ _proto._getInvViewProjMat = function _getInvViewProjMat() {
|
|
9159
9672
|
if (this._isInvViewProjDirty.flag) {
|
|
9160
9673
|
this._isInvViewProjDirty.flag = false;
|
|
9161
|
-
|
|
9674
|
+
var matrix = this._invViewProjMat;
|
|
9675
|
+
if (this._isCustomViewMatrix) {
|
|
9676
|
+
engineMath.Matrix.invert(this.viewMatrix, matrix);
|
|
9677
|
+
} else {
|
|
9678
|
+
// Ignore scale, consistent with viewMatrix getter
|
|
9679
|
+
var transform = this._entity.transform;
|
|
9680
|
+
engineMath.Matrix.rotationTranslation(transform.worldRotationQuaternion, transform.worldPosition, matrix);
|
|
9681
|
+
}
|
|
9682
|
+
matrix.multiply(this._getInverseProjectionMatrix());
|
|
9162
9683
|
}
|
|
9163
9684
|
return this._invViewProjMat;
|
|
9164
9685
|
};
|
|
@@ -22447,7 +22968,7 @@ __decorate([
|
|
|
22447
22968
|
deepClone
|
|
22448
22969
|
], Skin.prototype, "inverseBindMatrices", void 0);
|
|
22449
22970
|
__decorate([
|
|
22450
|
-
|
|
22971
|
+
deepClone
|
|
22451
22972
|
], Skin.prototype, "_skinMatrices", void 0);
|
|
22452
22973
|
__decorate([
|
|
22453
22974
|
ignoreClone
|
|
@@ -23447,7 +23968,10 @@ var ComponentCloner = /*#__PURE__*/ function() {
|
|
|
23447
23968
|
_proto._setActiveComponents = function _setActiveComponents(isActive, activeChangeFlag) {
|
|
23448
23969
|
var activeChangedComponents = this._activeChangedComponents;
|
|
23449
23970
|
for(var i = 0, length = activeChangedComponents.length; i < length; ++i){
|
|
23450
|
-
activeChangedComponents[i]
|
|
23971
|
+
var component = activeChangedComponents[i];
|
|
23972
|
+
// Skip components whose scene was already cleared by an earlier callback's removeChild
|
|
23973
|
+
if (!isActive && !component._entity._scene) continue;
|
|
23974
|
+
component._setActive(isActive, activeChangeFlag);
|
|
23451
23975
|
}
|
|
23452
23976
|
this._scene._componentsManager.putActiveChangedTempList(activeChangedComponents);
|
|
23453
23977
|
this._activeChangedComponents = null;
|
|
@@ -23467,18 +23991,19 @@ var ComponentCloner = /*#__PURE__*/ function() {
|
|
|
23467
23991
|
}
|
|
23468
23992
|
};
|
|
23469
23993
|
_proto._setInActiveInHierarchy = function _setInActiveInHierarchy(activeChangedComponents, activeChangeFlag) {
|
|
23994
|
+
// Children-first, reverse traversal for safe removeChild during callbacks
|
|
23995
|
+
var children = this._children;
|
|
23996
|
+
for(var i = children.length - 1; i >= 0; i--){
|
|
23997
|
+
var child = children[i];
|
|
23998
|
+
child.isActive && child._setInActiveInHierarchy(activeChangedComponents, activeChangeFlag);
|
|
23999
|
+
}
|
|
23470
24000
|
activeChangeFlag & ActiveChangeFlag.Hierarchy && (this._isActiveInHierarchy = false);
|
|
23471
24001
|
activeChangeFlag & ActiveChangeFlag.Scene && (this._isActiveInScene = false);
|
|
23472
24002
|
var components = this._components;
|
|
23473
|
-
for(var
|
|
23474
|
-
var component = components[
|
|
24003
|
+
for(var i1 = 0, n = components.length; i1 < n; i1++){
|
|
24004
|
+
var component = components[i1];
|
|
23475
24005
|
component.enabled && activeChangedComponents.push(component);
|
|
23476
24006
|
}
|
|
23477
|
-
var children = this._children;
|
|
23478
|
-
for(var i1 = 0, n1 = children.length; i1 < n1; i1++){
|
|
23479
|
-
var child = children[i1];
|
|
23480
|
-
child.isActive && child._setInActiveInHierarchy(activeChangedComponents, activeChangeFlag);
|
|
23481
|
-
}
|
|
23482
24007
|
};
|
|
23483
24008
|
_proto._setSiblingIndex = function _setSiblingIndex(sibling, target) {
|
|
23484
24009
|
target = Math.min(target, sibling.length - 1);
|
|
@@ -26390,7 +26915,7 @@ var depthOnlyVs = "#define MATERIAL_OMIT_NORMAL\n#include <common>\n#include <co
|
|
|
26390
26915
|
|
|
26391
26916
|
var particleFs = "#include <common>\n\nvarying vec4 v_Color;\nvarying vec2 v_TextureCoordinate;\nuniform sampler2D material_BaseTexture;\nuniform vec4 material_BaseColor;\n \nuniform mediump vec3 material_EmissiveColor;\n#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n uniform sampler2D material_EmissiveTexture;\n#endif\n\n#ifdef RENDERER_MODE_MESH\n\tvarying vec4 v_MeshColor;\n#endif\n\nvoid main() {\n\tvec4 color = material_BaseColor * v_Color;\n\n\t#if defined(RENDERER_MODE_MESH) && defined(RENDERER_ENABLE_VERTEXCOLOR)\n\t\tcolor *= v_MeshColor;\n\t#endif\n\n\t#ifdef MATERIAL_HAS_BASETEXTURE\n\t\tcolor *= texture2DSRGB(material_BaseTexture, v_TextureCoordinate);\n\t#endif\n\t\n\t// Emissive\n\tvec3 emissiveRadiance = material_EmissiveColor;\n\t#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n\t\temissiveRadiance *= texture2DSRGB(material_EmissiveTexture, v_TextureCoordinate).rgb;\n\t#endif\n\n\tcolor.rgb += emissiveRadiance;\n\n\tgl_FragColor = color;\n}"; // eslint-disable-line
|
|
26392
26917
|
|
|
26393
|
-
var particleVs = "#if defined(RENDERER_MODE_SPHERE_BILLBOARD) || defined(RENDERER_MODE_STRETCHED_BILLBOARD) || defined(RENDERER_MODE_HORIZONTAL_BILLBOARD) || defined(RENDERER_MODE_VERTICAL_BILLBOARD)\n attribute vec4 a_CornerTextureCoordinate;\n#endif\n\n#ifdef RENDERER_MODE_MESH\n attribute vec3 POSITION;\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n attribute vec4 COLOR_0;\n #endif\n attribute vec2 TEXCOORD_0;\n varying vec4 v_MeshColor;\n#endif\n\nattribute vec4 a_ShapePositionStartLifeTime;\nattribute vec4 a_DirectionTime;\nattribute vec4 a_StartColor;\nattribute vec3 a_StartSize;\nattribute vec3 a_StartRotation0;\nattribute float a_StartSpeed;\n\n//#if defined(COLOR_OVER_LIFETIME) || defined(RENDERER_COL_RANDOM_GRADIENTS) || defined(RENDERER_SOL_RANDOM_CURVES) || defined(RENDERER_SOL_RANDOM_CURVES_SEPARATE) || defined(ROTATION_OVER_LIFE_TIME_RANDOM_CONSTANTS) || defined(ROTATION_OVER_LIFETIME_RANDOM_CURVES)\n attribute vec4 a_Random0;\n//#endif\n\n#if defined(RENDERER_TSA_FRAME_RANDOM_CURVES) || defined(RENDERER_VOL_IS_RANDOM_TWO)\n attribute vec4 a_Random1; // x:texture sheet animation random\n#endif\n\n#if defined(RENDERER_FOL_CONSTANT_MODE) || defined(RENDERER_FOL_CURVE_MODE) || defined(RENDERER_LVL_MODULE_ENABLED)\n attribute vec4 a_Random2;\n#endif\n\nattribute vec3 a_SimulationWorldPosition;\nattribute vec4 a_SimulationWorldRotation;\n\n#ifdef RENDERER_TRANSFORM_FEEDBACK\n attribute vec3 a_FeedbackPosition;\n attribute vec3 a_FeedbackVelocity;\n#endif\n\nvarying vec4 v_Color;\n#ifdef MATERIAL_HAS_BASETEXTURE\n attribute vec4 a_SimulationUV;\n varying vec2 v_TextureCoordinate;\n#endif\n\nuniform float renderer_CurrentTime;\nuniform vec3 renderer_Gravity;\nuniform vec3 renderer_WorldPosition;\nuniform vec4 renderer_WorldRotation;\nuniform bool renderer_ThreeDStartRotation;\nuniform int renderer_ScalingMode;\nuniform vec3 renderer_PositionScale;\nuniform vec3 renderer_SizeScale;\nuniform vec3 renderer_PivotOffset;\n\nuniform mat4 camera_ViewMat;\nuniform mat4 camera_ProjMat;\n\n#ifdef RENDERER_MODE_STRETCHED_BILLBOARD\n uniform vec3 camera_Position;\n#endif\nuniform vec3 camera_Forward; // TODO:只有几种广告牌模式需要用\nuniform vec3 camera_Up;\n\nuniform float renderer_StretchedBillboardLengthScale;\nuniform float renderer_StretchedBillboardSpeedScale;\nuniform int renderer_SimulationSpace;\n\n#include <particle_common>\n#include <velocity_over_lifetime_module>\n#include <force_over_lifetime_module>\n#include <color_over_lifetime_module>\n#include <size_over_lifetime_module>\n#include <rotation_over_lifetime_module>\n#include <texture_sheet_animation_module>\n\nvec3 computeParticlePosition(in vec3 startVelocity, in float age, in float normalizedAge, vec3 gravityVelocity, vec4 worldRotation, inout vec3 localVelocity, inout vec3 worldVelocity) {\n vec3 startPosition = startVelocity * age;\n\n vec3 finalPosition;\n vec3 localPositionOffset = startPosition;\n vec3 worldPositionOffset;\n\n #ifdef _VOL_MODULE_ENABLED\n vec3 lifeVelocity; \n vec3 velocityPositionOffset = computeVelocityPositionOffset(normalizedAge, age, lifeVelocity);\n if (renderer_VOLSpace == 0) {\n localVelocity += lifeVelocity;\n localPositionOffset += velocityPositionOffset;\n } else {\n worldVelocity += lifeVelocity;\n worldPositionOffset += velocityPositionOffset;\n }\n #endif\n\n #ifdef _FOL_MODULE_ENABLED\n vec3 forceVelocity;\n vec3 forcePositionOffset = computeForcePositionOffset(normalizedAge, age, forceVelocity);\n if (renderer_FOLSpace == 0) {\n localVelocity += forceVelocity;\n localPositionOffset += forcePositionOffset;\n } else {\n worldVelocity += forceVelocity;\n worldPositionOffset += forcePositionOffset;\n }\n #endif\n\n finalPosition = rotationByQuaternions(a_ShapePositionStartLifeTime.xyz + localPositionOffset, worldRotation) + worldPositionOffset;\n\n if (renderer_SimulationSpace == 0) {\n finalPosition = finalPosition + renderer_WorldPosition;\n } else if (renderer_SimulationSpace == 1) {\n\t finalPosition = finalPosition + a_SimulationWorldPosition;\n\t}\n\n finalPosition += 0.5 * gravityVelocity * age;\n\n return finalPosition;\n}\n\nvoid main() {\n float age = renderer_CurrentTime - a_DirectionTime.w;\n float normalizedAge = age / a_ShapePositionStartLifeTime.w;\n // normalizedAge >= 0.0: skip stale TF slots whose startTime is from a previous playback (e.g. after StopEmittingAndClear).\n if (normalizedAge >= 0.0 && normalizedAge < 1.0) {\n vec4 worldRotation;\n if (renderer_SimulationSpace == 0) {\n worldRotation = renderer_WorldRotation;\n } else {\n worldRotation = a_SimulationWorldRotation;\n }\n\n vec3 localVelocity;\n vec3 worldVelocity;\n\n #ifdef RENDERER_TRANSFORM_FEEDBACK\n // Transform Feedback mode: position in simulation space (local or world).\n // Local: transform to world; World: use directly.\n vec3 center;\n if (renderer_SimulationSpace == 0) {\n center = rotationByQuaternions(a_FeedbackPosition, worldRotation) + renderer_WorldPosition;\n } else if (renderer_SimulationSpace == 1) {\n center = a_FeedbackPosition;\n }\n localVelocity = a_FeedbackVelocity;\n worldVelocity = vec3(0.0);\n\n #ifdef _VOL_MODULE_ENABLED\n vec3 instantVOLVelocity;\n computeVelocityPositionOffset(normalizedAge, age, instantVOLVelocity);\n if (renderer_VOLSpace == 0) {\n localVelocity += instantVOLVelocity;\n } else {\n worldVelocity += instantVOLVelocity;\n }\n #endif\n #else\n // Original analytical path\n vec3 startVelocity = a_DirectionTime.xyz * a_StartSpeed;\n vec3 gravityVelocity = renderer_Gravity * a_Random0.x * age;\n localVelocity = startVelocity;\n worldVelocity = gravityVelocity;\n vec3 center = computeParticlePosition(startVelocity, age, normalizedAge, gravityVelocity, worldRotation, localVelocity, worldVelocity);\n #endif\n\n #include <sphere_billboard>\n #include <stretched_billboard>\n #include <horizontal_billboard>\n #include <vertical_billboard>\n #include <particle_mesh>\n\n gl_Position = camera_ProjMat * camera_ViewMat * vec4(center, 1.0);\n v_Color = computeParticleColor(a_StartColor, normalizedAge);\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n vec2 simulateUV;\n #if defined(RENDERER_MODE_SPHERE_BILLBOARD) || defined(RENDERER_MODE_STRETCHED_BILLBOARD) || defined(RENDERER_MODE_HORIZONTAL_BILLBOARD) || defined(RENDERER_MODE_VERTICAL_BILLBOARD)\n simulateUV = a_CornerTextureCoordinate.zw * a_SimulationUV.xy + a_SimulationUV.zw;\n v_TextureCoordinate = computeParticleUV(simulateUV, normalizedAge);\n #endif\n #ifdef RENDERER_MODE_MESH\n simulateUV = a_SimulationUV.zw + TEXCOORD_0 * a_SimulationUV.xy;\n v_TextureCoordinate = computeParticleUV(simulateUV, normalizedAge);\n #endif\n #endif\n } else {\n\t gl_Position = vec4(2.0, 2.0, 2.0, 1.0); // Discard use out of X(-1,1),Y(-1,1),Z(0,1)\n }\n}"; // eslint-disable-line
|
|
26918
|
+
var particleVs = "#if defined(RENDERER_MODE_SPHERE_BILLBOARD) || defined(RENDERER_MODE_STRETCHED_BILLBOARD) || defined(RENDERER_MODE_HORIZONTAL_BILLBOARD) || defined(RENDERER_MODE_VERTICAL_BILLBOARD)\n attribute vec4 a_CornerTextureCoordinate;\n#endif\n\n#ifdef RENDERER_MODE_MESH\n attribute vec3 POSITION;\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n attribute vec4 COLOR_0;\n #endif\n attribute vec2 TEXCOORD_0;\n varying vec4 v_MeshColor;\n#endif\n\nattribute vec4 a_ShapePositionStartLifeTime;\nattribute vec4 a_DirectionTime;\nattribute vec4 a_StartColor;\nattribute vec3 a_StartSize;\nattribute vec3 a_StartRotation0;\nattribute float a_StartSpeed;\n\n//#if defined(COLOR_OVER_LIFETIME) || defined(RENDERER_COL_RANDOM_GRADIENTS) || defined(RENDERER_SOL_RANDOM_CURVES) || defined(RENDERER_SOL_RANDOM_CURVES_SEPARATE) || defined(ROTATION_OVER_LIFE_TIME_RANDOM_CONSTANTS) || defined(ROTATION_OVER_LIFETIME_RANDOM_CURVES)\n attribute vec4 a_Random0;\n//#endif\n\n#if defined(RENDERER_TSA_FRAME_RANDOM_CURVES) || defined(RENDERER_VOL_IS_RANDOM_TWO)\n attribute vec4 a_Random1; // x:texture sheet animation random\n#endif\n\n#if defined(RENDERER_FOL_CONSTANT_MODE) || defined(RENDERER_FOL_CURVE_MODE) || defined(RENDERER_LVL_MODULE_ENABLED)\n attribute vec4 a_Random2;\n#endif\n\nattribute vec3 a_SimulationWorldPosition;\nattribute vec4 a_SimulationWorldRotation;\n\n#ifdef RENDERER_TRANSFORM_FEEDBACK\n attribute vec3 a_FeedbackPosition;\n attribute vec3 a_FeedbackVelocity;\n#endif\n\nvarying vec4 v_Color;\n#ifdef MATERIAL_HAS_BASETEXTURE\n attribute vec4 a_SimulationUV;\n varying vec2 v_TextureCoordinate;\n#endif\n\nuniform float renderer_CurrentTime;\nuniform vec3 renderer_Gravity;\nuniform vec3 renderer_WorldPosition;\nuniform vec4 renderer_WorldRotation;\nuniform bool renderer_ThreeDStartRotation;\nuniform int renderer_ScalingMode;\nuniform vec3 renderer_PositionScale;\nuniform vec3 renderer_SizeScale;\nuniform vec3 renderer_PivotOffset;\n\nuniform mat4 camera_ViewMat;\nuniform mat4 camera_ProjMat;\n\n#ifdef RENDERER_MODE_STRETCHED_BILLBOARD\n uniform vec3 camera_Position;\n#endif\nuniform vec3 camera_Forward; // TODO:只有几种广告牌模式需要用\nuniform vec3 camera_Up;\n\nuniform float renderer_StretchedBillboardLengthScale;\nuniform float renderer_StretchedBillboardSpeedScale;\nuniform int renderer_SimulationSpace;\n\n#include <particle_common>\n#include <velocity_over_lifetime_module>\n#include <force_over_lifetime_module>\n#include <color_over_lifetime_module>\n#include <size_over_lifetime_module>\n#include <rotation_over_lifetime_module>\n#include <texture_sheet_animation_module>\n#include <noise_module>\n\nvec3 computeParticlePosition(in vec3 startVelocity, in float age, in float normalizedAge, vec3 gravityVelocity, vec4 worldRotation, inout vec3 localVelocity, inout vec3 worldVelocity) {\n vec3 startPosition = startVelocity * age;\n\n vec3 finalPosition;\n vec3 localPositionOffset = startPosition;\n vec3 worldPositionOffset;\n\n #ifdef _VOL_MODULE_ENABLED\n vec3 lifeVelocity; \n vec3 velocityPositionOffset = computeVelocityPositionOffset(normalizedAge, age, lifeVelocity);\n if (renderer_VOLSpace == 0) {\n localVelocity += lifeVelocity;\n localPositionOffset += velocityPositionOffset;\n } else {\n worldVelocity += lifeVelocity;\n worldPositionOffset += velocityPositionOffset;\n }\n #endif\n\n #ifdef _FOL_MODULE_ENABLED\n vec3 forceVelocity;\n vec3 forcePositionOffset = computeForcePositionOffset(normalizedAge, age, forceVelocity);\n if (renderer_FOLSpace == 0) {\n localVelocity += forceVelocity;\n localPositionOffset += forcePositionOffset;\n } else {\n worldVelocity += forceVelocity;\n worldPositionOffset += forcePositionOffset;\n }\n #endif\n\n finalPosition = rotationByQuaternions(a_ShapePositionStartLifeTime.xyz + localPositionOffset, worldRotation) + worldPositionOffset;\n\n if (renderer_SimulationSpace == 0) {\n finalPosition = finalPosition + renderer_WorldPosition;\n } else if (renderer_SimulationSpace == 1) {\n\t finalPosition = finalPosition + a_SimulationWorldPosition;\n\t}\n\n finalPosition += 0.5 * gravityVelocity * age;\n\n return finalPosition;\n}\n\nvoid main() {\n float age = renderer_CurrentTime - a_DirectionTime.w;\n float normalizedAge = age / a_ShapePositionStartLifeTime.w;\n // normalizedAge >= 0.0: skip stale TF slots whose startTime is from a previous playback (e.g. after StopEmittingAndClear).\n if (normalizedAge >= 0.0 && normalizedAge < 1.0) {\n vec4 worldRotation;\n if (renderer_SimulationSpace == 0) {\n worldRotation = renderer_WorldRotation;\n } else {\n worldRotation = a_SimulationWorldRotation;\n }\n\n vec3 localVelocity;\n vec3 worldVelocity;\n\n #ifdef RENDERER_TRANSFORM_FEEDBACK\n // Transform Feedback mode: position in simulation space (local or world).\n // Local: transform to world; World: use directly.\n vec3 center;\n if (renderer_SimulationSpace == 0) {\n center = rotationByQuaternions(a_FeedbackPosition, worldRotation) + renderer_WorldPosition;\n } else if (renderer_SimulationSpace == 1) {\n center = a_FeedbackPosition;\n }\n localVelocity = a_FeedbackVelocity;\n worldVelocity = vec3(0.0);\n\n #ifdef _VOL_MODULE_ENABLED\n vec3 instantVOLVelocity;\n computeVelocityPositionOffset(normalizedAge, age, instantVOLVelocity);\n if (renderer_VOLSpace == 0) {\n localVelocity += instantVOLVelocity;\n } else {\n worldVelocity += instantVOLVelocity;\n }\n #endif\n #else\n // Original analytical path\n vec3 startVelocity = a_DirectionTime.xyz * a_StartSpeed;\n vec3 gravityVelocity = renderer_Gravity * a_Random0.x * age;\n localVelocity = startVelocity;\n worldVelocity = gravityVelocity;\n vec3 center = computeParticlePosition(startVelocity, age, normalizedAge, gravityVelocity, worldRotation, localVelocity, worldVelocity);\n #endif\n\n #include <sphere_billboard>\n #include <stretched_billboard>\n #include <horizontal_billboard>\n #include <vertical_billboard>\n #include <particle_mesh>\n\n gl_Position = camera_ProjMat * camera_ViewMat * vec4(center, 1.0);\n v_Color = computeParticleColor(a_StartColor, normalizedAge);\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n vec2 simulateUV;\n #if defined(RENDERER_MODE_SPHERE_BILLBOARD) || defined(RENDERER_MODE_STRETCHED_BILLBOARD) || defined(RENDERER_MODE_HORIZONTAL_BILLBOARD) || defined(RENDERER_MODE_VERTICAL_BILLBOARD)\n simulateUV = a_CornerTextureCoordinate.zw * a_SimulationUV.xy + a_SimulationUV.zw;\n v_TextureCoordinate = computeParticleUV(simulateUV, normalizedAge);\n #endif\n #ifdef RENDERER_MODE_MESH\n simulateUV = a_SimulationUV.zw + TEXCOORD_0 * a_SimulationUV.xy;\n v_TextureCoordinate = computeParticleUV(simulateUV, normalizedAge);\n #endif\n #endif\n } else {\n\t gl_Position = vec4(2.0, 2.0, 2.0, 1.0); // Discard use out of X(-1,1),Y(-1,1),Z(0,1)\n }\n}"; // eslint-disable-line
|
|
26394
26919
|
|
|
26395
26920
|
var pbrSpecularFs = "#include <common>\n#include <camera_declare>\n\n#include <FogFragmentDeclaration>\n\n#include <uv_share>\n#include <normal_share>\n#include <color_share>\n#include <worldpos_share>\n\n#include <light_frag_define>\n\n\n#include <pbr_frag_define>\n#include <pbr_helper>\n\nvoid main() {\n #include <pbr_frag>\n #include <FogFragment>\n}\n"; // eslint-disable-line
|
|
26396
26921
|
|
|
@@ -28860,45 +29385,6 @@ Scene._fogColorProperty = ShaderProperty.getByName("scene_FogColor");
|
|
|
28860
29385
|
Scene._fogParamsProperty = ShaderProperty.getByName("scene_FogParams");
|
|
28861
29386
|
Scene._prefilterdDFGProperty = ShaderProperty.getByName("scene_PrefilteredDFG");
|
|
28862
29387
|
|
|
28863
|
-
function _array_like_to_array(arr, len) {
|
|
28864
|
-
if (len == null || len > arr.length) len = arr.length;
|
|
28865
|
-
|
|
28866
|
-
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
28867
|
-
|
|
28868
|
-
return arr2;
|
|
28869
|
-
}
|
|
28870
|
-
|
|
28871
|
-
function _unsupported_iterable_to_array(o, minLen) {
|
|
28872
|
-
if (!o) return;
|
|
28873
|
-
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
28874
|
-
|
|
28875
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
28876
|
-
|
|
28877
|
-
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
28878
|
-
if (n === "Map" || n === "Set") return Array.from(n);
|
|
28879
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
28880
|
-
}
|
|
28881
|
-
|
|
28882
|
-
function _create_for_of_iterator_helper_loose(o, allowArrayLike) {
|
|
28883
|
-
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
|
28884
|
-
|
|
28885
|
-
if (it) return (it = it.call(o)).next.bind(it);
|
|
28886
|
-
// Fallback for engines without symbol support
|
|
28887
|
-
if (Array.isArray(o) || (it = _unsupported_iterable_to_array(o)) || allowArrayLike && o && typeof o.length === "number") {
|
|
28888
|
-
if (it) o = it;
|
|
28889
|
-
|
|
28890
|
-
var i = 0;
|
|
28891
|
-
|
|
28892
|
-
return function() {
|
|
28893
|
-
if (i >= o.length) return { done: true };
|
|
28894
|
-
|
|
28895
|
-
return { done: false, value: o[i++] };
|
|
28896
|
-
};
|
|
28897
|
-
}
|
|
28898
|
-
|
|
28899
|
-
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
28900
|
-
}
|
|
28901
|
-
|
|
28902
29388
|
/**
|
|
28903
29389
|
* Script class, used for logic writing.
|
|
28904
29390
|
*/ var Script = /*#__PURE__*/ function(Component) {
|
|
@@ -33293,7 +33779,7 @@ var ParticleStopMode = /*#__PURE__*/ function(ParticleStopMode) {
|
|
|
33293
33779
|
_inherits(ParticleRenderer, Renderer);
|
|
33294
33780
|
function ParticleRenderer(entity) {
|
|
33295
33781
|
var _this;
|
|
33296
|
-
_this = Renderer.call(this, entity) || this, /** Specifies how much particles stretch depending on their velocity. */ _this.velocityScale = 0, /** How much are the particles stretched in their direction of motion, defined as the length of the particle compared to its width. */ _this.lengthScale = 2, /** The pivot of particle. */ _this.pivot = new engineMath.Vector3(), /** @internal */ _this._generatorBounds = new engineMath.BoundingBox(), /** @internal */ _this._transformedBounds = new engineMath.BoundingBox();
|
|
33782
|
+
_this = Renderer.call(this, entity) || this, /** Specifies how much particles stretch depending on their velocity. */ _this.velocityScale = 0, /** How much are the particles stretched in their direction of motion, defined as the length of the particle compared to its width. */ _this.lengthScale = 2, /** The pivot of particle. */ _this.pivot = new engineMath.Vector3(), /** @internal */ _this._generatorBounds = new engineMath.BoundingBox(), /** @internal */ _this._transformedBounds = new engineMath.BoundingBox(), _this._renderMode = ParticleRenderMode.Billboard;
|
|
33297
33783
|
_this._onGeneratorParamsChanged = _this._onGeneratorParamsChanged.bind(_this);
|
|
33298
33784
|
_this.generator = new ParticleGenerator(_this);
|
|
33299
33785
|
_this._currentRenderModeMacro = ParticleRenderer._billboardModeMacro;
|
|
@@ -33899,6 +34385,7 @@ ParticleTransformFeedbackSimulator._deltaTimeProperty = ShaderProperty.getByName
|
|
|
33899
34385
|
ParticleRandomSubSeeds[ParticleRandomSubSeeds["GravityModifier"] = 2759560269] = "GravityModifier";
|
|
33900
34386
|
ParticleRandomSubSeeds[ParticleRandomSubSeeds["ForceOverLifetime"] = 3875246972] = "ForceOverLifetime";
|
|
33901
34387
|
ParticleRandomSubSeeds[ParticleRandomSubSeeds["LimitVelocityOverLifetime"] = 3047300990] = "LimitVelocityOverLifetime";
|
|
34388
|
+
ParticleRandomSubSeeds[ParticleRandomSubSeeds["Noise"] = 4105357473] = "Noise";
|
|
33902
34389
|
return ParticleRandomSubSeeds;
|
|
33903
34390
|
}({});
|
|
33904
34391
|
|
|
@@ -35282,7 +35769,7 @@ __decorate([
|
|
|
35282
35769
|
return;
|
|
35283
35770
|
}
|
|
35284
35771
|
this._enabled = value;
|
|
35285
|
-
this._generator._setTransformFeedback(
|
|
35772
|
+
this._generator._setTransformFeedback();
|
|
35286
35773
|
this._generator._renderer._onGeneratorParamsChanged();
|
|
35287
35774
|
}
|
|
35288
35775
|
}
|
|
@@ -36228,6 +36715,298 @@ __decorate([
|
|
|
36228
36715
|
ignoreClone
|
|
36229
36716
|
], TextureSheetAnimationModule.prototype, "_onTilingChanged", null);
|
|
36230
36717
|
|
|
36718
|
+
/**
|
|
36719
|
+
* Noise module for particle system.
|
|
36720
|
+
* Adds simplex noise-based turbulence displacement to particles.
|
|
36721
|
+
*/ var NoiseModule = /*#__PURE__*/ function(ParticleGeneratorModule) {
|
|
36722
|
+
_inherits(NoiseModule, ParticleGeneratorModule);
|
|
36723
|
+
function NoiseModule(generator) {
|
|
36724
|
+
var _this;
|
|
36725
|
+
_this = ParticleGeneratorModule.call(this, generator) || this, /** @internal */ _this._noiseRand = new engineMath.Rand(0, ParticleRandomSubSeeds.Noise), _this._noiseParams = new engineMath.Vector4(), _this._noiseOctaveParams = new engineMath.Vector4(), _this._strengthMinConst = new engineMath.Vector3(), _this._scrollSpeed = 0, _this._separateAxes = false, _this._frequency = 0.5, _this._octaveCount = 1, _this._octaveIntensityMultiplier = 0.5, _this._octaveFrequencyMultiplier = 2.0;
|
|
36726
|
+
_this.strengthX = new ParticleCompositeCurve(1);
|
|
36727
|
+
_this.strengthY = new ParticleCompositeCurve(1);
|
|
36728
|
+
_this.strengthZ = new ParticleCompositeCurve(1);
|
|
36729
|
+
return _this;
|
|
36730
|
+
}
|
|
36731
|
+
var _proto = NoiseModule.prototype;
|
|
36732
|
+
/**
|
|
36733
|
+
* @internal
|
|
36734
|
+
*/ _proto._updateShaderData = function _updateShaderData(shaderData) {
|
|
36735
|
+
var enabledMacro = null;
|
|
36736
|
+
var strengthCurveMacro = null;
|
|
36737
|
+
var strengthIsRandomTwoMacro = null;
|
|
36738
|
+
var separateAxesMacro = null;
|
|
36739
|
+
if (this.enabled) {
|
|
36740
|
+
enabledMacro = NoiseModule._enabledMacro;
|
|
36741
|
+
var strengthX = this._strengthX;
|
|
36742
|
+
var strengthY = this._strengthY;
|
|
36743
|
+
var strengthZ = this._strengthZ;
|
|
36744
|
+
var separateAxes = this._separateAxes;
|
|
36745
|
+
// Determine strength curve mode (following SOL pattern)
|
|
36746
|
+
var isRandomCurveMode = separateAxes ? strengthX.mode === ParticleCurveMode.TwoCurves && strengthY.mode === ParticleCurveMode.TwoCurves && strengthZ.mode === ParticleCurveMode.TwoCurves : strengthX.mode === ParticleCurveMode.TwoCurves;
|
|
36747
|
+
var isCurveMode = isRandomCurveMode || (separateAxes ? strengthX.mode === ParticleCurveMode.Curve && strengthY.mode === ParticleCurveMode.Curve && strengthZ.mode === ParticleCurveMode.Curve : strengthX.mode === ParticleCurveMode.Curve);
|
|
36748
|
+
var isRandomConstMode = separateAxes ? strengthX.mode === ParticleCurveMode.TwoConstants && strengthY.mode === ParticleCurveMode.TwoConstants && strengthZ.mode === ParticleCurveMode.TwoConstants : strengthX.mode === ParticleCurveMode.TwoConstants;
|
|
36749
|
+
// noiseParams.w = frequency (always needed)
|
|
36750
|
+
var noiseParams = this._noiseParams;
|
|
36751
|
+
if (isCurveMode) {
|
|
36752
|
+
// Curve/TwoCurves: encode curve data as float arrays
|
|
36753
|
+
shaderData.setFloatArray(NoiseModule._strengthMaxCurveXProperty, strengthX.curveMax._getTypeArray());
|
|
36754
|
+
if (separateAxes) {
|
|
36755
|
+
shaderData.setFloatArray(NoiseModule._strengthMaxCurveYProperty, strengthY.curveMax._getTypeArray());
|
|
36756
|
+
shaderData.setFloatArray(NoiseModule._strengthMaxCurveZProperty, strengthZ.curveMax._getTypeArray());
|
|
36757
|
+
}
|
|
36758
|
+
if (isRandomCurveMode) {
|
|
36759
|
+
shaderData.setFloatArray(NoiseModule._strengthMinCurveXProperty, strengthX.curveMin._getTypeArray());
|
|
36760
|
+
if (separateAxes) {
|
|
36761
|
+
shaderData.setFloatArray(NoiseModule._strengthMinCurveYProperty, strengthY.curveMin._getTypeArray());
|
|
36762
|
+
shaderData.setFloatArray(NoiseModule._strengthMinCurveZProperty, strengthZ.curveMin._getTypeArray());
|
|
36763
|
+
}
|
|
36764
|
+
strengthIsRandomTwoMacro = NoiseModule._strengthIsRandomTwoMacro;
|
|
36765
|
+
}
|
|
36766
|
+
strengthCurveMacro = NoiseModule._strengthCurveMacro;
|
|
36767
|
+
// xyz unused in curve mode, just set frequency
|
|
36768
|
+
noiseParams.set(0, 0, 0, this._frequency);
|
|
36769
|
+
} else {
|
|
36770
|
+
// Constant/TwoConstants: pack strength into noiseParams.xyz
|
|
36771
|
+
if (separateAxes) {
|
|
36772
|
+
noiseParams.set(strengthX.constantMax, strengthY.constantMax, strengthZ.constantMax, this._frequency);
|
|
36773
|
+
} else {
|
|
36774
|
+
var s = strengthX.constantMax;
|
|
36775
|
+
noiseParams.set(s, s, s, this._frequency);
|
|
36776
|
+
}
|
|
36777
|
+
if (isRandomConstMode) {
|
|
36778
|
+
var minConst = this._strengthMinConst;
|
|
36779
|
+
if (separateAxes) {
|
|
36780
|
+
minConst.set(strengthX.constantMin, strengthY.constantMin, strengthZ.constantMin);
|
|
36781
|
+
} else {
|
|
36782
|
+
var sMin = strengthX.constantMin;
|
|
36783
|
+
minConst.set(sMin, sMin, sMin);
|
|
36784
|
+
}
|
|
36785
|
+
shaderData.setVector3(NoiseModule._strengthMinConstProperty, minConst);
|
|
36786
|
+
strengthIsRandomTwoMacro = NoiseModule._strengthIsRandomTwoMacro;
|
|
36787
|
+
}
|
|
36788
|
+
}
|
|
36789
|
+
shaderData.setVector4(NoiseModule._noiseProperty, noiseParams);
|
|
36790
|
+
if (separateAxes) {
|
|
36791
|
+
separateAxesMacro = NoiseModule._separateAxesMacro;
|
|
36792
|
+
}
|
|
36793
|
+
var noiseOctaveParams = this._noiseOctaveParams;
|
|
36794
|
+
noiseOctaveParams.set(this._scrollSpeed, this._octaveCount, this._octaveIntensityMultiplier, this._octaveFrequencyMultiplier);
|
|
36795
|
+
shaderData.setVector4(NoiseModule._noiseOctaveProperty, noiseOctaveParams);
|
|
36796
|
+
}
|
|
36797
|
+
this._enabledModuleMacro = this._enableMacro(shaderData, this._enabledModuleMacro, enabledMacro);
|
|
36798
|
+
this._strengthCurveModeMacro = this._enableMacro(shaderData, this._strengthCurveModeMacro, strengthCurveMacro);
|
|
36799
|
+
this._strengthIsRandomTwoModeMacro = this._enableMacro(shaderData, this._strengthIsRandomTwoModeMacro, strengthIsRandomTwoMacro);
|
|
36800
|
+
this._separateAxesModeMacro = this._enableMacro(shaderData, this._separateAxesModeMacro, separateAxesMacro);
|
|
36801
|
+
};
|
|
36802
|
+
/**
|
|
36803
|
+
* @internal
|
|
36804
|
+
*/ _proto._resetRandomSeed = function _resetRandomSeed(seed) {
|
|
36805
|
+
this._noiseRand.reset(seed, ParticleRandomSubSeeds.Noise);
|
|
36806
|
+
};
|
|
36807
|
+
_create_class(NoiseModule, [
|
|
36808
|
+
{
|
|
36809
|
+
key: "separateAxes",
|
|
36810
|
+
get: /**
|
|
36811
|
+
* Specifies whether the strength is separate on each axis, when disabled, only `strength` is used.
|
|
36812
|
+
*/ function get() {
|
|
36813
|
+
return this._separateAxes;
|
|
36814
|
+
},
|
|
36815
|
+
set: function set(value) {
|
|
36816
|
+
if (value !== this._separateAxes) {
|
|
36817
|
+
this._separateAxes = value;
|
|
36818
|
+
this._generator._renderer._onGeneratorParamsChanged();
|
|
36819
|
+
}
|
|
36820
|
+
}
|
|
36821
|
+
},
|
|
36822
|
+
{
|
|
36823
|
+
key: "strengthX",
|
|
36824
|
+
get: /**
|
|
36825
|
+
* Noise strength. When `separateAxes` is disabled, applies to all axes.
|
|
36826
|
+
* When `separateAxes` is enabled, applies only to x axis.
|
|
36827
|
+
*/ function get() {
|
|
36828
|
+
return this._strengthX;
|
|
36829
|
+
},
|
|
36830
|
+
set: function set(value) {
|
|
36831
|
+
var lastValue = this._strengthX;
|
|
36832
|
+
if (value !== lastValue) {
|
|
36833
|
+
this._strengthX = value;
|
|
36834
|
+
this._onCompositeCurveChange(lastValue, value);
|
|
36835
|
+
}
|
|
36836
|
+
}
|
|
36837
|
+
},
|
|
36838
|
+
{
|
|
36839
|
+
key: "strengthY",
|
|
36840
|
+
get: /**
|
|
36841
|
+
* Noise strength for y axis, used when `separateAxes` is enabled.
|
|
36842
|
+
*/ function get() {
|
|
36843
|
+
return this._strengthY;
|
|
36844
|
+
},
|
|
36845
|
+
set: function set(value) {
|
|
36846
|
+
var lastValue = this._strengthY;
|
|
36847
|
+
if (value !== lastValue) {
|
|
36848
|
+
this._strengthY = value;
|
|
36849
|
+
this._onCompositeCurveChange(lastValue, value);
|
|
36850
|
+
}
|
|
36851
|
+
}
|
|
36852
|
+
},
|
|
36853
|
+
{
|
|
36854
|
+
key: "strengthZ",
|
|
36855
|
+
get: /**
|
|
36856
|
+
* Noise strength for z axis, used when `separateAxes` is enabled.
|
|
36857
|
+
*/ function get() {
|
|
36858
|
+
return this._strengthZ;
|
|
36859
|
+
},
|
|
36860
|
+
set: function set(value) {
|
|
36861
|
+
var lastValue = this._strengthZ;
|
|
36862
|
+
if (value !== lastValue) {
|
|
36863
|
+
this._strengthZ = value;
|
|
36864
|
+
this._onCompositeCurveChange(lastValue, value);
|
|
36865
|
+
}
|
|
36866
|
+
}
|
|
36867
|
+
},
|
|
36868
|
+
{
|
|
36869
|
+
key: "frequency",
|
|
36870
|
+
get: /**
|
|
36871
|
+
* Noise spatial frequency.
|
|
36872
|
+
*/ function get() {
|
|
36873
|
+
return this._frequency;
|
|
36874
|
+
},
|
|
36875
|
+
set: function set(value) {
|
|
36876
|
+
value = Math.max(1e-6, value);
|
|
36877
|
+
if (value !== this._frequency) {
|
|
36878
|
+
this._frequency = value;
|
|
36879
|
+
this._generator._renderer._onGeneratorParamsChanged();
|
|
36880
|
+
}
|
|
36881
|
+
}
|
|
36882
|
+
},
|
|
36883
|
+
{
|
|
36884
|
+
key: "scrollSpeed",
|
|
36885
|
+
get: /**
|
|
36886
|
+
* Noise field scroll speed over time.
|
|
36887
|
+
*/ function get() {
|
|
36888
|
+
return this._scrollSpeed;
|
|
36889
|
+
},
|
|
36890
|
+
set: function set(value) {
|
|
36891
|
+
if (value !== this._scrollSpeed) {
|
|
36892
|
+
this._scrollSpeed = value;
|
|
36893
|
+
this._generator._renderer._onGeneratorParamsChanged();
|
|
36894
|
+
}
|
|
36895
|
+
}
|
|
36896
|
+
},
|
|
36897
|
+
{
|
|
36898
|
+
key: "octaveCount",
|
|
36899
|
+
get: /**
|
|
36900
|
+
* Number of noise octave layers (1-3).
|
|
36901
|
+
*/ function get() {
|
|
36902
|
+
return this._octaveCount;
|
|
36903
|
+
},
|
|
36904
|
+
set: function set(value) {
|
|
36905
|
+
value = Math.max(1, Math.min(3, Math.floor(value)));
|
|
36906
|
+
if (value !== this._octaveCount) {
|
|
36907
|
+
this._octaveCount = value;
|
|
36908
|
+
this._generator._renderer._onGeneratorParamsChanged();
|
|
36909
|
+
}
|
|
36910
|
+
}
|
|
36911
|
+
},
|
|
36912
|
+
{
|
|
36913
|
+
key: "octaveIntensityMultiplier",
|
|
36914
|
+
get: /**
|
|
36915
|
+
* Intensity multiplier for each successive octave, only effective when `octaveCount` > 1.
|
|
36916
|
+
* Each layer's contribution is scaled by this factor relative to the previous layer, range [0, 1].
|
|
36917
|
+
*/ function get() {
|
|
36918
|
+
return this._octaveIntensityMultiplier;
|
|
36919
|
+
},
|
|
36920
|
+
set: function set(value) {
|
|
36921
|
+
value = Math.max(0, Math.min(1, value));
|
|
36922
|
+
if (value !== this._octaveIntensityMultiplier) {
|
|
36923
|
+
this._octaveIntensityMultiplier = value;
|
|
36924
|
+
this._generator._renderer._onGeneratorParamsChanged();
|
|
36925
|
+
}
|
|
36926
|
+
}
|
|
36927
|
+
},
|
|
36928
|
+
{
|
|
36929
|
+
key: "octaveFrequencyMultiplier",
|
|
36930
|
+
get: /**
|
|
36931
|
+
* Frequency multiplier for each successive octave, only effective when `octaveCount` > 1.
|
|
36932
|
+
* Each layer samples at this multiple of the previous layer's frequency, range [1, 4].
|
|
36933
|
+
*/ function get() {
|
|
36934
|
+
return this._octaveFrequencyMultiplier;
|
|
36935
|
+
},
|
|
36936
|
+
set: function set(value) {
|
|
36937
|
+
value = Math.max(1, Math.min(4, value));
|
|
36938
|
+
if (value !== this._octaveFrequencyMultiplier) {
|
|
36939
|
+
this._octaveFrequencyMultiplier = value;
|
|
36940
|
+
this._generator._renderer._onGeneratorParamsChanged();
|
|
36941
|
+
}
|
|
36942
|
+
}
|
|
36943
|
+
},
|
|
36944
|
+
{
|
|
36945
|
+
key: "enabled",
|
|
36946
|
+
get: function get() {
|
|
36947
|
+
return this._enabled;
|
|
36948
|
+
},
|
|
36949
|
+
set: function set(value) {
|
|
36950
|
+
if (value !== this._enabled) {
|
|
36951
|
+
if (value && !this._generator._renderer.engine._hardwareRenderer.isWebGL2) {
|
|
36952
|
+
return;
|
|
36953
|
+
}
|
|
36954
|
+
this._enabled = value;
|
|
36955
|
+
this._generator._setTransformFeedback();
|
|
36956
|
+
this._generator._renderer._onGeneratorParamsChanged();
|
|
36957
|
+
}
|
|
36958
|
+
}
|
|
36959
|
+
}
|
|
36960
|
+
]);
|
|
36961
|
+
return NoiseModule;
|
|
36962
|
+
}(ParticleGeneratorModule);
|
|
36963
|
+
NoiseModule._enabledMacro = ShaderMacro.getByName("RENDERER_NOISE_MODULE_ENABLED");
|
|
36964
|
+
NoiseModule._strengthCurveMacro = ShaderMacro.getByName("RENDERER_NOISE_STRENGTH_CURVE");
|
|
36965
|
+
NoiseModule._strengthIsRandomTwoMacro = ShaderMacro.getByName("RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO");
|
|
36966
|
+
NoiseModule._separateAxesMacro = ShaderMacro.getByName("RENDERER_NOISE_IS_SEPARATE");
|
|
36967
|
+
NoiseModule._noiseProperty = ShaderProperty.getByName("renderer_NoiseParams");
|
|
36968
|
+
NoiseModule._noiseOctaveProperty = ShaderProperty.getByName("renderer_NoiseOctaveParams");
|
|
36969
|
+
NoiseModule._strengthMinConstProperty = ShaderProperty.getByName("renderer_NoiseStrengthMinConst");
|
|
36970
|
+
NoiseModule._strengthMaxCurveXProperty = ShaderProperty.getByName("renderer_NoiseStrengthMaxCurveX");
|
|
36971
|
+
NoiseModule._strengthMaxCurveYProperty = ShaderProperty.getByName("renderer_NoiseStrengthMaxCurveY");
|
|
36972
|
+
NoiseModule._strengthMaxCurveZProperty = ShaderProperty.getByName("renderer_NoiseStrengthMaxCurveZ");
|
|
36973
|
+
NoiseModule._strengthMinCurveXProperty = ShaderProperty.getByName("renderer_NoiseStrengthMinCurveX");
|
|
36974
|
+
NoiseModule._strengthMinCurveYProperty = ShaderProperty.getByName("renderer_NoiseStrengthMinCurveY");
|
|
36975
|
+
NoiseModule._strengthMinCurveZProperty = ShaderProperty.getByName("renderer_NoiseStrengthMinCurveZ");
|
|
36976
|
+
__decorate([
|
|
36977
|
+
ignoreClone
|
|
36978
|
+
], NoiseModule.prototype, "_enabledModuleMacro", void 0);
|
|
36979
|
+
__decorate([
|
|
36980
|
+
ignoreClone
|
|
36981
|
+
], NoiseModule.prototype, "_strengthCurveModeMacro", void 0);
|
|
36982
|
+
__decorate([
|
|
36983
|
+
ignoreClone
|
|
36984
|
+
], NoiseModule.prototype, "_strengthIsRandomTwoModeMacro", void 0);
|
|
36985
|
+
__decorate([
|
|
36986
|
+
ignoreClone
|
|
36987
|
+
], NoiseModule.prototype, "_separateAxesModeMacro", void 0);
|
|
36988
|
+
__decorate([
|
|
36989
|
+
ignoreClone
|
|
36990
|
+
], NoiseModule.prototype, "_noiseRand", void 0);
|
|
36991
|
+
__decorate([
|
|
36992
|
+
ignoreClone
|
|
36993
|
+
], NoiseModule.prototype, "_noiseParams", void 0);
|
|
36994
|
+
__decorate([
|
|
36995
|
+
ignoreClone
|
|
36996
|
+
], NoiseModule.prototype, "_noiseOctaveParams", void 0);
|
|
36997
|
+
__decorate([
|
|
36998
|
+
ignoreClone
|
|
36999
|
+
], NoiseModule.prototype, "_strengthMinConst", void 0);
|
|
37000
|
+
__decorate([
|
|
37001
|
+
deepClone
|
|
37002
|
+
], NoiseModule.prototype, "_strengthX", void 0);
|
|
37003
|
+
__decorate([
|
|
37004
|
+
deepClone
|
|
37005
|
+
], NoiseModule.prototype, "_strengthY", void 0);
|
|
37006
|
+
__decorate([
|
|
37007
|
+
deepClone
|
|
37008
|
+
], NoiseModule.prototype, "_strengthZ", void 0);
|
|
37009
|
+
|
|
36231
37010
|
/**
|
|
36232
37011
|
* Velocity over lifetime module.
|
|
36233
37012
|
*/ var VelocityOverLifetimeModule = /*#__PURE__*/ function(ParticleGeneratorModule) {
|
|
@@ -36434,6 +37213,7 @@ __decorate([
|
|
|
36434
37213
|
this.forceOverLifetime = new ForceOverLifetimeModule(this);
|
|
36435
37214
|
this.sizeOverLifetime = new SizeOverLifetimeModule(this);
|
|
36436
37215
|
this.limitVelocityOverLifetime = new LimitVelocityOverLifetimeModule(this);
|
|
37216
|
+
this.noise = new NoiseModule(this);
|
|
36437
37217
|
this.emission.enabled = true;
|
|
36438
37218
|
}
|
|
36439
37219
|
var _proto = ParticleGenerator.prototype;
|
|
@@ -36741,6 +37521,7 @@ __decorate([
|
|
|
36741
37521
|
this.sizeOverLifetime._updateShaderData(shaderData);
|
|
36742
37522
|
this.rotationOverLifetime._updateShaderData(shaderData);
|
|
36743
37523
|
this.colorOverLifetime._updateShaderData(shaderData);
|
|
37524
|
+
this.noise._updateShaderData(shaderData);
|
|
36744
37525
|
};
|
|
36745
37526
|
/**
|
|
36746
37527
|
* @internal
|
|
@@ -36754,16 +37535,19 @@ __decorate([
|
|
|
36754
37535
|
this.limitVelocityOverLifetime._resetRandomSeed(seed);
|
|
36755
37536
|
this.rotationOverLifetime._resetRandomSeed(seed);
|
|
36756
37537
|
this.colorOverLifetime._resetRandomSeed(seed);
|
|
37538
|
+
this.noise._resetRandomSeed(seed);
|
|
36757
37539
|
};
|
|
36758
37540
|
/**
|
|
36759
37541
|
* @internal
|
|
36760
|
-
*/ _proto._setTransformFeedback = function _setTransformFeedback(
|
|
36761
|
-
this.
|
|
37542
|
+
*/ _proto._setTransformFeedback = function _setTransformFeedback() {
|
|
37543
|
+
var needed = this.limitVelocityOverLifetime.enabled || this.noise.enabled;
|
|
37544
|
+
if (needed === this._useTransformFeedback) return;
|
|
37545
|
+
this._useTransformFeedback = needed;
|
|
36762
37546
|
// Switching TF mode invalidates all active particle state: feedback buffers and instance
|
|
36763
37547
|
// buffer layout are incompatible between the two paths. Clear rather than show a one-frame
|
|
36764
37548
|
// jump; new particles will fill in naturally from the next emit cycle.
|
|
36765
37549
|
this._clearActiveParticles();
|
|
36766
|
-
if (
|
|
37550
|
+
if (needed) {
|
|
36767
37551
|
if (!this._feedbackSimulator) {
|
|
36768
37552
|
this._feedbackSimulator = new ParticleTransformFeedbackSimulator(this._renderer.engine);
|
|
36769
37553
|
}
|
|
@@ -36813,9 +37597,7 @@ __decorate([
|
|
|
36813
37597
|
/**
|
|
36814
37598
|
* @internal
|
|
36815
37599
|
*/ _proto._cloneTo = function _cloneTo(target) {
|
|
36816
|
-
|
|
36817
|
-
target._setTransformFeedback(true);
|
|
36818
|
-
}
|
|
37600
|
+
target._setTransformFeedback();
|
|
36819
37601
|
};
|
|
36820
37602
|
/**
|
|
36821
37603
|
* @internal
|
|
@@ -36977,10 +37759,6 @@ __decorate([
|
|
|
36977
37759
|
// Start rotation
|
|
36978
37760
|
var startRotationRand = main._startRotationRand, flipRotation = main.flipRotation;
|
|
36979
37761
|
var isFlip = flipRotation > startRotationRand.random();
|
|
36980
|
-
// @todo:None-Mesh mode should inverse the rotation, maybe should unify it
|
|
36981
|
-
if (this._renderer.renderMode !== ParticleRenderMode.Mesh) {
|
|
36982
|
-
isFlip = !isFlip;
|
|
36983
|
-
}
|
|
36984
37762
|
var rotationZ = main.startRotationZ.evaluate(undefined, startRotationRand.random());
|
|
36985
37763
|
if (main.startRotation3D) {
|
|
36986
37764
|
var rotationX = main.startRotationX.evaluate(undefined, startRotationRand.random());
|
|
@@ -37006,7 +37784,9 @@ __decorate([
|
|
|
37006
37784
|
if (colorOverLifetime.enabled && colorOverLifetime.color.mode === ParticleGradientMode.TwoGradients) {
|
|
37007
37785
|
instanceVertices[offset + 20] = colorOverLifetime._colorGradientRand.random();
|
|
37008
37786
|
}
|
|
37009
|
-
|
|
37787
|
+
if (this.noise.enabled) {
|
|
37788
|
+
instanceVertices[offset + 21] = this.noise._noiseRand.random();
|
|
37789
|
+
}
|
|
37010
37790
|
var rotationOverLifetime = this.rotationOverLifetime;
|
|
37011
37791
|
if (rotationOverLifetime.enabled && rotationOverLifetime.rotationZ.mode === ParticleCurveMode.TwoConstants) {
|
|
37012
37792
|
instanceVertices[offset + 22] = rotationOverLifetime._rotationRand.random();
|
|
@@ -37294,6 +38074,21 @@ __decorate([
|
|
|
37294
38074
|
out.transform(rotateMat);
|
|
37295
38075
|
min.add(worldOffsetMin);
|
|
37296
38076
|
max.add(worldOffsetMax);
|
|
38077
|
+
// Noise module impact: noise output is normalized to [-1, 1],
|
|
38078
|
+
// max displacement = |strength_max|
|
|
38079
|
+
var noise = this.noise;
|
|
38080
|
+
if (noise.enabled) {
|
|
38081
|
+
var noiseMaxX, noiseMaxY, noiseMaxZ;
|
|
38082
|
+
if (noise.separateAxes) {
|
|
38083
|
+
noiseMaxX = Math.abs(noise.strengthX._getMax());
|
|
38084
|
+
noiseMaxY = Math.abs(noise.strengthY._getMax());
|
|
38085
|
+
noiseMaxZ = Math.abs(noise.strengthZ._getMax());
|
|
38086
|
+
} else {
|
|
38087
|
+
noiseMaxX = noiseMaxY = noiseMaxZ = Math.abs(noise.strengthX._getMax());
|
|
38088
|
+
}
|
|
38089
|
+
min.set(min.x - noiseMaxX, min.y - noiseMaxY, min.z - noiseMaxZ);
|
|
38090
|
+
max.set(max.x + noiseMaxX, max.y + noiseMaxY, max.z + noiseMaxZ);
|
|
38091
|
+
}
|
|
37297
38092
|
min.add(worldPosition);
|
|
37298
38093
|
max.add(worldPosition);
|
|
37299
38094
|
};
|
|
@@ -37391,6 +38186,9 @@ __decorate([
|
|
|
37391
38186
|
__decorate([
|
|
37392
38187
|
deepClone
|
|
37393
38188
|
], ParticleGenerator.prototype, "textureSheetAnimation", void 0);
|
|
38189
|
+
__decorate([
|
|
38190
|
+
deepClone
|
|
38191
|
+
], ParticleGenerator.prototype, "noise", void 0);
|
|
37394
38192
|
__decorate([
|
|
37395
38193
|
ignoreClone
|
|
37396
38194
|
], ParticleGenerator.prototype, "_playTime", void 0);
|
|
@@ -39594,6 +40392,7 @@ exports.MeshRenderer = MeshRenderer;
|
|
|
39594
40392
|
exports.MeshShape = MeshShape;
|
|
39595
40393
|
exports.MeshTopology = MeshTopology;
|
|
39596
40394
|
exports.ModelMesh = ModelMesh;
|
|
40395
|
+
exports.NoiseModule = NoiseModule;
|
|
39597
40396
|
exports.OverflowMode = OverflowMode;
|
|
39598
40397
|
exports.PBRMaterial = PBRMaterial;
|
|
39599
40398
|
exports.ParticleCompositeCurve = ParticleCompositeCurve;
|