@galacean/engine-core 2.0.0-alpha.24 → 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/module.js CHANGED
@@ -1323,6 +1323,12 @@ SystemInfo._initialize();
1323
1323
  case TextureFormat.ETC2_RGB:
1324
1324
  case TextureFormat.ETC2_RGBA8:
1325
1325
  case TextureFormat.ASTC_4x4:
1326
+ case TextureFormat.ASTC_5x5:
1327
+ case TextureFormat.ASTC_6x6:
1328
+ case TextureFormat.ASTC_8x8:
1329
+ case TextureFormat.ASTC_10x10:
1330
+ case TextureFormat.ASTC_12x12:
1331
+ case TextureFormat.ETC2_RGBA5:
1326
1332
  return true;
1327
1333
  default:
1328
1334
  return false;
@@ -1861,7 +1867,7 @@ SystemInfo._initialize();
1861
1867
  _this = ReferResource.call(this, engine) || this, _this._charInfoMap = {}, _this._space = 1, _this._curX = 1, _this._curY = 1, _this._nextY = 1;
1862
1868
  _this.isGCIgnored = true;
1863
1869
  var format = engine._hardwareRenderer.isWebGL2 ? TextureFormat.R8 : TextureFormat.Alpha8;
1864
- var texture = new Texture2D(engine, 512, 512, format, false);
1870
+ var texture = new Texture2D(engine, 512, 512, format, false, false);
1865
1871
  texture.filterMode = TextureFilterMode.Bilinear;
1866
1872
  texture.isGCIgnored = true;
1867
1873
  _this.texture = texture;
@@ -4861,7 +4867,7 @@ var brdf = "\n#ifdef MATERIAL_ENABLE_SHEEN\n uniform sampler2D scene_Prefilte
4861
4867
 
4862
4868
  var direct_irradiance_frag_define = "#include <ShadowFragmentDeclaration>\n\nvoid sheenLobe(Geometry geometry, Material material, vec3 incidentDirection, vec3 attenuationIrradiance, inout vec3 diffuseColor, inout vec3 specularColor){\n #ifdef MATERIAL_ENABLE_SHEEN\n diffuseColor *= material.sheenScaling;\n specularColor *= material.sheenScaling;\n\n specularColor += attenuationIrradiance * sheenBRDF(incidentDirection, geometry, material.sheenColor, material.sheenRoughness);\n #endif\n}\n\nvoid addDirectRadiance(vec3 incidentDirection, vec3 color, Geometry geometry, Material material, inout ReflectedLight reflectedLight) {\n float attenuation = 1.0;\n\n #ifdef MATERIAL_ENABLE_CLEAR_COAT\n float clearCoatDotNL = saturate( dot( geometry.clearCoatNormal, incidentDirection ) );\n vec3 clearCoatIrradiance = clearCoatDotNL * color;\n\n reflectedLight.directSpecular += material.clearCoat * clearCoatIrradiance * BRDF_Specular_GGX( incidentDirection, geometry, material, geometry.clearCoatNormal, vec3( 0.04 ), material.clearCoatRoughness );\n attenuation -= material.clearCoat * F_Schlick(0.04, 1.0, geometry.clearCoatDotNV);\n #endif\n\n float dotNL = saturate( dot( geometry.normal, incidentDirection ) );\n vec3 irradiance = dotNL * color * PI;\n\n reflectedLight.directSpecular += attenuation * irradiance * BRDF_Specular_GGX( incidentDirection, geometry, material, geometry.normal, material.specularF0, material.roughness) * material.energyCompensation;\n reflectedLight.directDiffuse += attenuation * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\n // Sheen Lobe\n sheenLobe(geometry, material, incidentDirection, attenuation * irradiance, reflectedLight.directDiffuse, reflectedLight.directSpecular);\n\n}\n\n#ifdef SCENE_DIRECT_LIGHT_COUNT\n\n void addDirectionalDirectLightRadiance(DirectLight directionalLight, Geometry geometry, Material material, inout ReflectedLight reflectedLight) {\n vec3 color = directionalLight.color;\n vec3 direction = -directionalLight.direction;\n\n\t\taddDirectRadiance( direction, color, geometry, material, reflectedLight );\n\n }\n\n#endif\n\n#ifdef SCENE_POINT_LIGHT_COUNT\n\n\tvoid addPointDirectLightRadiance(PointLight pointLight, Geometry geometry, Material material, inout ReflectedLight reflectedLight) {\n\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tvec3 direction = normalize( lVector );\n\n\t\tfloat lightDistance = length( lVector );\n\n\t\tvec3 color = pointLight.color;\n\t\tcolor *= clamp(1.0 - pow(lightDistance/pointLight.distance, 4.0), 0.0, 1.0);\n\n\t\taddDirectRadiance( direction, color, geometry, material, reflectedLight );\n\n\t}\n\n#endif\n\n#ifdef SCENE_SPOT_LIGHT_COUNT\n\n\tvoid addSpotDirectLightRadiance(SpotLight spotLight, Geometry geometry, Material material, inout ReflectedLight reflectedLight) {\n\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tvec3 direction = normalize( lVector );\n\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( direction, -spotLight.direction );\n\n\t\tfloat spotEffect = smoothstep( spotLight.penumbraCos, spotLight.angleCos, angleCos );\n\t\tfloat decayEffect = clamp(1.0 - pow(lightDistance/spotLight.distance, 4.0), 0.0, 1.0);\n\n\t\tvec3 color = spotLight.color;\n\t\tcolor *= spotEffect * decayEffect;\n\n\t\taddDirectRadiance( direction, color, geometry, material, reflectedLight );\n\n\t}\n\n\n#endif\n\nvoid addTotalDirectRadiance(Geometry geometry, Material material, inout ReflectedLight reflectedLight){\n float shadowAttenuation = 1.0;\n\n #ifdef SCENE_DIRECT_LIGHT_COUNT\n shadowAttenuation = 1.0;\n #ifdef SCENE_IS_CALCULATE_SHADOWS\n shadowAttenuation *= sampleShadowMap();\n #endif\n\n DirectLight directionalLight;\n for ( int i = 0; i < SCENE_DIRECT_LIGHT_COUNT; i ++ ) {\n // warning: use `continue` syntax may trigger flickering bug in safri 16.1.\n if(!isRendererCulledByLight(renderer_Layer.xy, scene_DirectLightCullingMask[i])){\n directionalLight.color = scene_DirectLightColor[i];\n #ifdef SCENE_IS_CALCULATE_SHADOWS\n if (i == 0) { // Sun light index is always 0\n directionalLight.color *= shadowAttenuation;\n }\n #endif\n directionalLight.direction = scene_DirectLightDirection[i];\n addDirectionalDirectLightRadiance( directionalLight, geometry, material, reflectedLight );\n }\n }\n\n #endif\n\n #ifdef SCENE_POINT_LIGHT_COUNT\n\n PointLight pointLight;\n\n for ( int i = 0; i < SCENE_POINT_LIGHT_COUNT; i ++ ) {\n if(!isRendererCulledByLight(renderer_Layer.xy, scene_PointLightCullingMask[i])){\n pointLight.color = scene_PointLightColor[i];\n pointLight.position = scene_PointLightPosition[i];\n pointLight.distance = scene_PointLightDistance[i];\n\n addPointDirectLightRadiance( pointLight, geometry, material, reflectedLight );\n } \n }\n\n #endif\n\n #ifdef SCENE_SPOT_LIGHT_COUNT\n\n SpotLight spotLight;\n\n for ( int i = 0; i < SCENE_SPOT_LIGHT_COUNT; i ++ ) {\n if(!isRendererCulledByLight(renderer_Layer.xy, scene_SpotLightCullingMask[i])){\n spotLight.color = scene_SpotLightColor[i];\n spotLight.position = scene_SpotLightPosition[i];\n spotLight.direction = scene_SpotLightDirection[i];\n spotLight.distance = scene_SpotLightDistance[i];\n spotLight.angleCos = scene_SpotLightAngleCos[i];\n spotLight.penumbraCos = scene_SpotLightPenumbraCos[i];\n\n addSpotDirectLightRadiance( spotLight, geometry, material, reflectedLight );\n } \n }\n\n #endif\n}"; // eslint-disable-line
4863
4869
 
4864
- var ibl_frag_define = "// ------------------------Diffuse------------------------\n\n// sh need be pre-scaled in CPU.\nvec3 getLightProbeIrradiance(vec3 sh[9], vec3 normal){\n normal.x = -normal.x;\n vec3 result = sh[0] +\n\n sh[1] * (normal.y) +\n sh[2] * (normal.z) +\n sh[3] * (normal.x) +\n\n sh[4] * (normal.y * normal.x) +\n sh[5] * (normal.y * normal.z) +\n sh[6] * (3.0 * normal.z * normal.z - 1.0) +\n sh[7] * (normal.z * normal.x) +\n sh[8] * (normal.x * normal.x - normal.y * normal.y);\n \n return max(result, vec3(0.0));\n\n}\n\n// ------------------------Specular------------------------\n\n// Returns raw DFG approximation coefficients (split-sum LUT approximation)\nvec2 envDFGApprox(float roughness, float dotNV) {\n const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n vec4 r = roughness * c0 + c1;\n float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n return vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\n\n// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile\nvec3 envBRDFApprox(vec3 f0, float f90, float roughness, float dotNV ) {\n vec2 AB = envDFGApprox(roughness, dotNV);\n return f0 * AB.x + f90 * AB.y;\n}\n\n\nfloat getSpecularMIPLevel(float roughness, int maxMIPLevel ) {\n return roughness * float(maxMIPLevel);\n}\n\nvec3 getReflectedVector(Geometry geometry, vec3 n) {\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n vec3 r = reflect(-geometry.viewDir, geometry.anisotropicN);\n #else\n vec3 r = reflect(-geometry.viewDir, n);\n #endif\n\n return r;\n}\n\nvec3 getLightProbeRadiance(Geometry geometry, vec3 normal, float roughness, int maxMIPLevel, float specularIntensity) {\n\n #ifndef SCENE_USE_SPECULAR_ENV\n return vec3(0);\n #else\n vec3 reflectVec = getReflectedVector(geometry, normal);\n reflectVec.x = -reflectVec.x; // TextureCube is left-hand,so x need inverse\n \n float specularMIPLevel = getSpecularMIPLevel(roughness, maxMIPLevel );\n\n #ifdef HAS_TEX_LOD\n vec4 envMapColor = textureCubeLodEXT( scene_EnvSpecularSampler, reflectVec, specularMIPLevel );\n #else\n vec4 envMapColor = textureCube( scene_EnvSpecularSampler, reflectVec, specularMIPLevel );\n #endif\n\n #ifdef ENGINE_NO_SRGB\n envMapColor = sRGBToLinear(envMapColor);\n #endif\n \n return envMapColor.rgb * specularIntensity;\n\n #endif\n\n}\n\n\nvoid evaluateSheenIBL(Geometry geometry, Material material, float radianceAttenuation, inout vec3 diffuseColor, inout vec3 specularColor){\n #ifdef MATERIAL_ENABLE_SHEEN\n diffuseColor *= material.sheenScaling;\n specularColor *= material.sheenScaling;\n\n vec3 reflectance = material.specularAO * radianceAttenuation * material.approxIBLSheenDG * material.sheenColor;\n specularColor += reflectance;\n #endif\n}"; // eslint-disable-line
4870
+ var ibl_frag_define = "// ------------------------Diffuse------------------------\n\n// sh need be pre-scaled in CPU.\nvec3 getLightProbeIrradiance(vec3 sh[9], vec3 normal){\n vec3 result = sh[0] +\n\n sh[1] * (normal.y) +\n sh[2] * (normal.z) +\n sh[3] * (normal.x) +\n\n sh[4] * (normal.y * normal.x) +\n sh[5] * (normal.y * normal.z) +\n sh[6] * (3.0 * normal.z * normal.z - 1.0) +\n sh[7] * (normal.z * normal.x) +\n sh[8] * (normal.x * normal.x - normal.y * normal.y);\n \n return max(result, vec3(0.0));\n\n}\n\n// ------------------------Specular------------------------\n\n// Returns raw DFG approximation coefficients (split-sum LUT approximation)\nvec2 envDFGApprox(float roughness, float dotNV) {\n const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n vec4 r = roughness * c0 + c1;\n float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n return vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\n\n// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile\nvec3 envBRDFApprox(vec3 f0, float f90, float roughness, float dotNV ) {\n vec2 AB = envDFGApprox(roughness, dotNV);\n return f0 * AB.x + f90 * AB.y;\n}\n\n\nfloat getSpecularMIPLevel(float roughness, int maxMIPLevel ) {\n return roughness * float(maxMIPLevel);\n}\n\nvec3 getReflectedVector(Geometry geometry, vec3 n) {\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n vec3 r = reflect(-geometry.viewDir, geometry.anisotropicN);\n #else\n vec3 r = reflect(-geometry.viewDir, n);\n #endif\n\n return r;\n}\n\nvec3 getLightProbeRadiance(Geometry geometry, vec3 normal, float roughness, int maxMIPLevel, float specularIntensity) {\n\n #ifndef SCENE_USE_SPECULAR_ENV\n return vec3(0);\n #else\n vec3 reflectVec = getReflectedVector(geometry, normal);\n\n float specularMIPLevel = getSpecularMIPLevel(roughness, maxMIPLevel );\n\n #ifdef HAS_TEX_LOD\n vec4 envMapColor = textureCubeLodEXT( scene_EnvSpecularSampler, reflectVec, specularMIPLevel );\n #else\n vec4 envMapColor = textureCube( scene_EnvSpecularSampler, reflectVec, specularMIPLevel );\n #endif\n\n #ifdef ENGINE_NO_SRGB\n envMapColor = sRGBToLinear(envMapColor);\n #endif\n \n return envMapColor.rgb * specularIntensity;\n\n #endif\n\n}\n\n\nvoid evaluateSheenIBL(Geometry geometry, Material material, float radianceAttenuation, inout vec3 diffuseColor, inout vec3 specularColor){\n #ifdef MATERIAL_ENABLE_SHEEN\n diffuseColor *= material.sheenScaling;\n specularColor *= material.sheenScaling;\n\n vec3 reflectance = material.specularAO * radianceAttenuation * material.approxIBLSheenDG * material.sheenColor;\n specularColor += reflectance;\n #endif\n}"; // eslint-disable-line
4865
4871
 
4866
4872
  var pbr_frag = "Geometry geometry;\nMaterial material;\nReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\ninitGeometry(geometry, gl_FrontFacing);\ninitMaterial(material, geometry);\n\n// Direct Light\naddTotalDirectRadiance(geometry, material, reflectedLight);\n\n// IBL diffuse\n#ifdef SCENE_USE_SH\n vec3 irradiance = getLightProbeIrradiance(scene_EnvSH, geometry.normal);\n irradiance *= scene_EnvMapLight.diffuseIntensity;\n#else\n vec3 irradiance = scene_EnvMapLight.diffuse * scene_EnvMapLight.diffuseIntensity;\n irradiance *= PI;\n#endif\n\nreflectedLight.indirectDiffuse += material.diffuseAO * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\n// IBL specular\nvec3 radiance = getLightProbeRadiance(geometry, geometry.normal, material.roughness, int(scene_EnvMapLight.mipMapLevel), scene_EnvMapLight.specularIntensity);\nfloat radianceAttenuation = 1.0;\n\n// IBL Clear Coat\n#ifdef MATERIAL_ENABLE_CLEAR_COAT\n vec3 clearCoatRadiance = getLightProbeRadiance( geometry, geometry.clearCoatNormal, material.clearCoatRoughness, int(scene_EnvMapLight.mipMapLevel), scene_EnvMapLight.specularIntensity );\n\n reflectedLight.indirectSpecular += material.specularAO * clearCoatRadiance * material.clearCoat * envBRDFApprox(vec3( 0.04 ), 1.0, material.clearCoatRoughness, geometry.clearCoatDotNV);\n radianceAttenuation -= material.clearCoat * F_Schlick(0.04, 1.0, geometry.clearCoatDotNV);\n#endif\n\nreflectedLight.indirectSpecular += material.specularAO * radianceAttenuation * radiance * envBRDFApprox(material.resolvedSpecularF0, material.specularF90, material.roughness, geometry.dotNV) * material.energyCompensation;\n\n\n// IBL Sheen\nevaluateSheenIBL(geometry, material, radianceAttenuation, reflectedLight.indirectDiffuse, reflectedLight.indirectSpecular);\n\n\n// Final color\nvec3 totalDiffuseColor = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\nvec3 totalSpecularColor = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\n#ifdef MATERIAL_ENABLE_TRANSMISSION \n vec3 refractionTransmitted = evaluateTransmission(geometry, material);\n totalDiffuseColor = mix(totalDiffuseColor, refractionTransmitted, material.transmission);\n#endif\n\nvec4 finalColor = vec4(totalDiffuseColor + totalSpecularColor, material.opacity);\n\n\n// Emissive\nvec3 emissiveRadiance = material_EmissiveColor;\n#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n emissiveRadiance *= texture2DSRGB(material_EmissiveTexture, v_uv).rgb;\n#endif\n\nfinalColor.rgb += emissiveRadiance;\n\n\ngl_FragColor = finalColor;\n"; // eslint-disable-line
4867
4873
 
@@ -4914,7 +4920,9 @@ var force_over_lifetime_module = "#if defined(RENDERER_FOL_CONSTANT_MODE) || def
4914
4920
 
4915
4921
  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
4916
4922
 
4917
- 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
4923
+ 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
4924
+
4925
+ 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
4918
4926
 
4919
4927
  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
4920
4928
 
@@ -4935,6 +4943,7 @@ var ParticleShaderLib = {
4935
4943
  texture_sheet_animation_module: texture_sheet_animation_module,
4936
4944
  force_over_lifetime_module: force_over_lifetime_module,
4937
4945
  limit_velocity_over_lifetime_module: limit_velocity_over_lifetime_module,
4946
+ noise_module: noise_module,
4938
4947
  particle_feedback_simulation: particle_feedback_simulation,
4939
4948
  sphere_billboard: sphere_billboard,
4940
4949
  stretched_billboard: stretched_billboard,
@@ -5783,26 +5792,492 @@ ShaderTagKey._nameMap = Object.create(null);
5783
5792
  }();
5784
5793
  ShaderProgram._counter = 0;
5785
5794
 
5795
+ function _array_like_to_array(arr, len) {
5796
+ if (len == null || len > arr.length) len = arr.length;
5797
+
5798
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
5799
+
5800
+ return arr2;
5801
+ }
5802
+
5803
+ function _unsupported_iterable_to_array(o, minLen) {
5804
+ if (!o) return;
5805
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
5806
+
5807
+ var n = Object.prototype.toString.call(o).slice(8, -1);
5808
+
5809
+ if (n === "Object" && o.constructor) n = o.constructor.name;
5810
+ if (n === "Map" || n === "Set") return Array.from(n);
5811
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
5812
+ }
5813
+
5814
+ function _create_for_of_iterator_helper_loose(o, allowArrayLike) {
5815
+ var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
5816
+
5817
+ if (it) return (it = it.call(o)).next.bind(it);
5818
+ // Fallback for engines without symbol support
5819
+ if (Array.isArray(o) || (it = _unsupported_iterable_to_array(o)) || allowArrayLike && o && typeof o.length === "number") {
5820
+ if (it) o = it;
5821
+
5822
+ var i = 0;
5823
+
5824
+ return function() {
5825
+ if (i >= o.length) return { done: true };
5826
+
5827
+ return { done: false, value: o[i++] };
5828
+ };
5829
+ }
5830
+
5831
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
5832
+ }
5833
+
5834
+ /**
5835
+ * Directive types for shader preprocessor instructions.
5836
+ */ var ShaderPreprocessorDirective = /*#__PURE__*/ function(ShaderPreprocessorDirective) {
5837
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["Text"] = 0] = "Text";
5838
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["IfDef"] = 1] = "IfDef";
5839
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["IfNdef"] = 2] = "IfNdef";
5840
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["IfCmp"] = 3] = "IfCmp";
5841
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["IfExpr"] = 4] = "IfExpr";
5842
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["Else"] = 5] = "Else";
5843
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["Endif"] = 6] = "Endif";
5844
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["Define"] = 7] = "Define";
5845
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["DefineVal"] = 8] = "DefineVal";
5846
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["DefineFunc"] = 9] = "DefineFunc";
5847
+ ShaderPreprocessorDirective[ShaderPreprocessorDirective["Undef"] = 10] = "Undef";
5848
+ return ShaderPreprocessorDirective;
5849
+ }({});
5850
+
5851
+ /**
5852
+ * @internal
5853
+ */ var ShaderMacroProcessor = /*#__PURE__*/ function() {
5854
+ function ShaderMacroProcessor() {}
5855
+ /**
5856
+ * Evaluate a flat instruction array with active macros.
5857
+ * Macros are expanded immediately when text chunks are collected,
5858
+ * using the current macro state at that point (conforming to GLSL/C99 §6.10 standard).
5859
+ * @param instructions - Pre-parsed instruction array
5860
+ * @param macros - Active runtime macros
5861
+ * @returns Pure GLSL string with all conditionals resolved and macros expanded
5862
+ */ ShaderMacroProcessor.evaluate = function evaluate(instructions, macros) {
5863
+ var valueMacros = ShaderMacroProcessor._valueMacros;
5864
+ var funcMacros = ShaderMacroProcessor._funcMacros;
5865
+ var shaderChunks = ShaderMacroProcessor._shaderChunks;
5866
+ valueMacros.clear();
5867
+ funcMacros.clear();
5868
+ shaderChunks.length = 0;
5869
+ for(var _iterator = _create_for_of_iterator_helper_loose(macros), _step; !(_step = _iterator()).done;){
5870
+ var _step_value = _step.value, name = _step_value[0], value = _step_value[1];
5871
+ valueMacros.set(name, value);
5872
+ }
5873
+ ShaderMacroProcessor._macroFirstCharsDirty = true;
5874
+ var index = 0;
5875
+ var length = instructions.length;
5876
+ while(index < length){
5877
+ var instruction = instructions[index];
5878
+ switch(instruction[0]){
5879
+ case ShaderPreprocessorDirective.Text:
5880
+ // Immediately expand macros using current macro state (GLSL/C99 conformant)
5881
+ shaderChunks.push(ShaderMacroProcessor._expandChunk(instruction[1], valueMacros, funcMacros));
5882
+ index++;
5883
+ break;
5884
+ case ShaderPreprocessorDirective.IfDef:
5885
+ {
5886
+ var name1 = instruction[1];
5887
+ index = valueMacros.has(name1) || funcMacros.has(name1) ? index + 1 : instruction[2];
5888
+ break;
5889
+ }
5890
+ case ShaderPreprocessorDirective.IfNdef:
5891
+ {
5892
+ var name2 = instruction[1];
5893
+ index = !valueMacros.has(name2) && !funcMacros.has(name2) ? index + 1 : instruction[2];
5894
+ break;
5895
+ }
5896
+ case ShaderPreprocessorDirective.IfCmp:
5897
+ {
5898
+ var name3 = instruction[1];
5899
+ var val = valueMacros.get(name3);
5900
+ var matched = val !== undefined && ShaderMacroProcessor._compareValues(Number(val) || 0, instruction[2], instruction[3]);
5901
+ index = matched ? index + 1 : instruction[4];
5902
+ break;
5903
+ }
5904
+ case ShaderPreprocessorDirective.IfExpr:
5905
+ index = ShaderMacroProcessor._evalCondition(instruction[1], valueMacros, funcMacros) ? index + 1 : instruction[2];
5906
+ break;
5907
+ case ShaderPreprocessorDirective.Else:
5908
+ index = instruction[1];
5909
+ break;
5910
+ case ShaderPreprocessorDirective.Endif:
5911
+ index++;
5912
+ break;
5913
+ case ShaderPreprocessorDirective.Define:
5914
+ valueMacros.set(instruction[1], "");
5915
+ index++;
5916
+ break;
5917
+ case ShaderPreprocessorDirective.DefineVal:
5918
+ valueMacros.set(instruction[1], instruction[2]);
5919
+ ShaderMacroProcessor._macroFirstCharsDirty = true;
5920
+ index++;
5921
+ break;
5922
+ case ShaderPreprocessorDirective.DefineFunc:
5923
+ funcMacros.set(instruction[1], {
5924
+ params: instruction[2],
5925
+ body: instruction[3]
5926
+ });
5927
+ ShaderMacroProcessor._macroFirstCharsDirty = true;
5928
+ index++;
5929
+ break;
5930
+ case ShaderPreprocessorDirective.Undef:
5931
+ valueMacros.delete(instruction[1]);
5932
+ funcMacros.delete(instruction[1]);
5933
+ index++;
5934
+ break;
5935
+ default:
5936
+ index++;
5937
+ break;
5938
+ }
5939
+ }
5940
+ return ShaderMacroProcessor._concatChunks(shaderChunks);
5941
+ };
5942
+ /**
5943
+ * Expand macros in a single text chunk using the current macro state.
5944
+ * Returns the chunk as-is if no expandable macros exist.
5945
+ */ ShaderMacroProcessor._expandChunk = function _expandChunk(chunk, valueMacros, funcMacros) {
5946
+ // Fast path: no expandable macros at this point
5947
+ if (funcMacros.size === 0) {
5948
+ var hasExpandable = false;
5949
+ for(var _iterator = _create_for_of_iterator_helper_loose(valueMacros), _step; !(_step = _iterator()).done;){
5950
+ var _step_value = _step.value, val = _step_value[1];
5951
+ if (val !== "") {
5952
+ hasExpandable = true;
5953
+ break;
5954
+ }
5955
+ }
5956
+ if (!hasExpandable) return chunk;
5957
+ }
5958
+ // Rebuild first-char filter if macros changed
5959
+ if (ShaderMacroProcessor._macroFirstCharsDirty) {
5960
+ var macroFirstChars = ShaderMacroProcessor._macroFirstChars;
5961
+ macroFirstChars.clear();
5962
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(valueMacros.keys()), _step1; !(_step1 = _iterator1()).done;){
5963
+ var name = _step1.value;
5964
+ macroFirstChars.add(name.charCodeAt(0));
5965
+ }
5966
+ for(var _iterator2 = _create_for_of_iterator_helper_loose(funcMacros.keys()), _step2; !(_step2 = _iterator2()).done;){
5967
+ var name1 = _step2.value;
5968
+ macroFirstChars.add(name1.charCodeAt(0));
5969
+ }
5970
+ ShaderMacroProcessor._macroFirstCharsDirty = false;
5971
+ }
5972
+ var macroFirstChars1 = ShaderMacroProcessor._macroFirstChars;
5973
+ var expandedNames = ShaderMacroProcessor._expandedNames;
5974
+ var out = ShaderMacroProcessor._out;
5975
+ out.length = 0;
5976
+ var len = chunk.length;
5977
+ var i = 0;
5978
+ while(i < len){
5979
+ var cc = chunk.charCodeAt(i);
5980
+ if (ShaderMacroProcessor._isIdentifierStart(cc)) {
5981
+ var start = i;
5982
+ i++;
5983
+ while(i < len && ShaderMacroProcessor._isIdentifierPart(chunk.charCodeAt(i)))i++;
5984
+ // Fast path: first char not in any macro name
5985
+ if (!macroFirstChars1.has(chunk.charCodeAt(start))) {
5986
+ out.push(chunk.substring(start, i));
5987
+ continue;
5988
+ }
5989
+ var name2 = chunk.substring(start, i);
5990
+ // Try function macro
5991
+ var func = funcMacros.get(name2);
5992
+ if (func) {
5993
+ var lookAhead = i;
5994
+ while(lookAhead < len && (chunk.charCodeAt(lookAhead) === 32 /* space */ || chunk.charCodeAt(lookAhead) === 9))lookAhead++;
5995
+ if (lookAhead < len && chunk.charCodeAt(lookAhead) === 40 /* '(' */ ) {
5996
+ var args = ShaderMacroProcessor._parseFuncArgs(chunk, lookAhead);
5997
+ if (args) {
5998
+ i = args.end;
5999
+ var expanded = ShaderMacroProcessor._expandFuncBody(func, args.values);
6000
+ expandedNames.clear();
6001
+ expandedNames.add(name2);
6002
+ out.push(ShaderMacroProcessor._recursiveExpandMacro(expanded, valueMacros, funcMacros, expandedNames));
6003
+ continue;
6004
+ }
6005
+ }
6006
+ }
6007
+ // Try value macro
6008
+ var val1 = valueMacros.get(name2);
6009
+ if (val1 !== undefined && val1 !== "") {
6010
+ expandedNames.clear();
6011
+ expandedNames.add(name2);
6012
+ out.push(ShaderMacroProcessor._recursiveExpandMacro(val1, valueMacros, funcMacros, expandedNames));
6013
+ continue;
6014
+ }
6015
+ out.push(name2);
6016
+ continue;
6017
+ }
6018
+ // Batch collect non-identifier characters
6019
+ var batchStart = i;
6020
+ while(i < len && !ShaderMacroProcessor._isIdentifierStart(chunk.charCodeAt(i)))i++;
6021
+ out.push(chunk.substring(batchStart, i));
6022
+ }
6023
+ return out.join("");
6024
+ };
6025
+ /**
6026
+ * Recursively expand macro substitution results until no more macros remain.
6027
+ * @param macroExpansion - Intermediate text from a macro substitution that may contain further macro references
6028
+ * @param valueMacros - Current value macro definitions
6029
+ * @param funcMacros - Current function macro definitions
6030
+ * @param expandedNames - Macro names already on the expansion chain, prevents circular references (C99 §6.10.3.4)
6031
+ */ ShaderMacroProcessor._recursiveExpandMacro = function _recursiveExpandMacro(macroExpansion, valueMacros, funcMacros, expandedNames) {
6032
+ if (macroExpansion.length === 0) return macroExpansion;
6033
+ var len = macroExpansion.length;
6034
+ var out = [];
6035
+ var i = 0;
6036
+ while(i < len){
6037
+ var cc = macroExpansion.charCodeAt(i);
6038
+ if (ShaderMacroProcessor._isIdentifierStart(cc)) {
6039
+ var start = i;
6040
+ i++;
6041
+ while(i < len && ShaderMacroProcessor._isIdentifierPart(macroExpansion.charCodeAt(i)))i++;
6042
+ var name = macroExpansion.substring(start, i);
6043
+ // Skip already-expanded names (circular reference prevention)
6044
+ // Skip GL_ prefixed names (reserved GLSL built-ins, charCodes: G=71, L=76, _=95)
6045
+ if (expandedNames.has(name) || name.charCodeAt(0) === 71 && name.charCodeAt(1) === 76 && name.charCodeAt(2) === 95) {
6046
+ out.push(name);
6047
+ continue;
6048
+ }
6049
+ var func = funcMacros.get(name);
6050
+ if (func) {
6051
+ var lookAhead = i;
6052
+ while(lookAhead < len && (macroExpansion.charCodeAt(lookAhead) === 32 /* space */ || macroExpansion.charCodeAt(lookAhead) === 9))lookAhead++;
6053
+ if (lookAhead < len && macroExpansion.charCodeAt(lookAhead) === 40 /* '(' */ ) {
6054
+ var args = ShaderMacroProcessor._parseFuncArgs(macroExpansion, lookAhead);
6055
+ if (args) {
6056
+ i = args.end;
6057
+ expandedNames.add(name);
6058
+ out.push(ShaderMacroProcessor._recursiveExpandMacro(ShaderMacroProcessor._expandFuncBody(func, args.values), valueMacros, funcMacros, expandedNames));
6059
+ expandedNames.delete(name);
6060
+ continue;
6061
+ }
6062
+ }
6063
+ }
6064
+ var val = valueMacros.get(name);
6065
+ if (val !== undefined && val !== "") {
6066
+ expandedNames.add(name);
6067
+ out.push(ShaderMacroProcessor._recursiveExpandMacro(val, valueMacros, funcMacros, expandedNames));
6068
+ expandedNames.delete(name);
6069
+ continue;
6070
+ }
6071
+ out.push(name);
6072
+ continue;
6073
+ }
6074
+ // Batch collect non-identifier characters
6075
+ var batchStart = i;
6076
+ while(i < len && !ShaderMacroProcessor._isIdentifierStart(macroExpansion.charCodeAt(i)))i++;
6077
+ out.push(macroExpansion.substring(batchStart, i));
6078
+ }
6079
+ return out.join("");
6080
+ };
6081
+ /**
6082
+ * Substitute function macro params in body.
6083
+ */ ShaderMacroProcessor._expandFuncBody = function _expandFuncBody(func, args) {
6084
+ if (func.params.length === 0 || args.length !== func.params.length) return func.body;
6085
+ var result = func.body;
6086
+ for(var i = 0; i < func.params.length; i++){
6087
+ result = ShaderMacroProcessor._replaceWord(result, func.params[i], args[i]);
6088
+ }
6089
+ return result;
6090
+ };
6091
+ /**
6092
+ * Evaluate a compound condition tree.
6093
+ */ ShaderMacroProcessor._evalCondition = function _evalCondition(cond, valueMacros, funcMacros) {
6094
+ switch(cond.t){
6095
+ case "def":
6096
+ return valueMacros.has(cond.m) || funcMacros.has(cond.m);
6097
+ case "ndef":
6098
+ return !valueMacros.has(cond.m) && !funcMacros.has(cond.m);
6099
+ case "cmp":
6100
+ {
6101
+ var val = valueMacros.get(cond.m);
6102
+ if (val === undefined) return false;
6103
+ return ShaderMacroProcessor._compareValues(Number(val) || 0, cond.op, cond.v);
6104
+ }
6105
+ case "and":
6106
+ return ShaderMacroProcessor._evalCondition(cond.l, valueMacros, funcMacros) && ShaderMacroProcessor._evalCondition(cond.r, valueMacros, funcMacros);
6107
+ case "or":
6108
+ return ShaderMacroProcessor._evalCondition(cond.l, valueMacros, funcMacros) || ShaderMacroProcessor._evalCondition(cond.r, valueMacros, funcMacros);
6109
+ case "not":
6110
+ return !ShaderMacroProcessor._evalCondition(cond.c, valueMacros, funcMacros);
6111
+ case "bool":
6112
+ return cond.v;
6113
+ }
6114
+ };
6115
+ /**
6116
+ * Evaluate a comparison operator.
6117
+ */ ShaderMacroProcessor._compareValues = function _compareValues(numVal, op, value) {
6118
+ switch(op){
6119
+ case "==":
6120
+ return numVal === value;
6121
+ case "!=":
6122
+ return numVal !== value;
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
+ default:
6132
+ return false;
6133
+ }
6134
+ };
6135
+ /**
6136
+ * Parse function macro call arguments.
6137
+ * Returns reusable static result object to avoid allocation.
6138
+ */ ShaderMacroProcessor._parseFuncArgs = function _parseFuncArgs(text, openParen) {
6139
+ var result = ShaderMacroProcessor._parsedFuncArgs;
6140
+ result.values.length = 0;
6141
+ var level = 1;
6142
+ var argStart = openParen + 1;
6143
+ var k = argStart;
6144
+ var len = text.length;
6145
+ while(k < len && level > 0){
6146
+ var cc = text.charCodeAt(k);
6147
+ if (cc === 40 /* '(' */ ) {
6148
+ level++;
6149
+ } else if (cc === 41 /* ')' */ ) {
6150
+ if (--level === 0) {
6151
+ var arg = text.substring(argStart, k).trim();
6152
+ if (arg.length > 0 || result.values.length > 0) result.values.push(arg);
6153
+ result.end = k + 1;
6154
+ return result;
6155
+ }
6156
+ } else if (cc === 44 /* ',' */ && level === 1) {
6157
+ result.values.push(text.substring(argStart, k).trim());
6158
+ argStart = k + 1;
6159
+ }
6160
+ k++;
6161
+ }
6162
+ return null;
6163
+ };
6164
+ /**
6165
+ * Replace all whole-word occurrences of `word` in `text` with `replacement`.
6166
+ */ ShaderMacroProcessor._replaceWord = function _replaceWord(text, word, replacement) {
6167
+ var wLen = word.length;
6168
+ var parts = ShaderMacroProcessor._replaceWordParts;
6169
+ parts.length = 0;
6170
+ var start = 0;
6171
+ var idx = text.indexOf(word, start);
6172
+ while(idx !== -1){
6173
+ if (idx > 0 && ShaderMacroProcessor._isIdentifierPart(text.charCodeAt(idx - 1))) {
6174
+ idx = text.indexOf(word, idx + 1);
6175
+ continue;
6176
+ }
6177
+ var afterIdx = idx + wLen;
6178
+ if (afterIdx < text.length && ShaderMacroProcessor._isIdentifierPart(text.charCodeAt(afterIdx))) {
6179
+ idx = text.indexOf(word, idx + 1);
6180
+ continue;
6181
+ }
6182
+ parts.push(text.substring(start, idx));
6183
+ parts.push(replacement);
6184
+ start = afterIdx;
6185
+ idx = text.indexOf(word, start);
6186
+ }
6187
+ if (start === 0) return text;
6188
+ parts.push(text.substring(start));
6189
+ return parts.join("");
6190
+ };
6191
+ /**
6192
+ * Concatenate shader chunks with consecutive blank lines collapsed to a single newline.
6193
+ */ ShaderMacroProcessor._concatChunks = function _concatChunks(shaderChunks) {
6194
+ var out = ShaderMacroProcessor._out;
6195
+ out.length = 0;
6196
+ var lastNewline = false;
6197
+ for(var p = 0; p < shaderChunks.length; p++){
6198
+ var text = shaderChunks[p];
6199
+ var len = text.length;
6200
+ var i = 0;
6201
+ while(i < len){
6202
+ if (text.charCodeAt(i) === 10 /* \n */ ) {
6203
+ if (!lastNewline) {
6204
+ out.push("\n");
6205
+ lastNewline = true;
6206
+ }
6207
+ i++;
6208
+ while(i < len){
6209
+ var c = text.charCodeAt(i);
6210
+ if (c === 32 /* space */ || c === 9 /* tab */ || c === 10 /* \n */ ) i++;
6211
+ else break;
6212
+ }
6213
+ } else {
6214
+ var batchStart = i;
6215
+ while(i < len && text.charCodeAt(i) !== 10 /* \n */ )i++;
6216
+ out.push(text.substring(batchStart, i));
6217
+ lastNewline = false;
6218
+ }
6219
+ }
6220
+ }
6221
+ return out.join("");
6222
+ };
6223
+ /**
6224
+ * Check if char code is a valid identifier start.
6225
+ * Matches: [A-Z] | [a-z] | _
6226
+ */ ShaderMacroProcessor._isIdentifierStart = function _isIdentifierStart(charCode) {
6227
+ return charCode >= 65 && charCode <= 90 || charCode >= 97 && charCode <= 122 || charCode === 95;
6228
+ };
6229
+ /**
6230
+ * Check if char code is a valid identifier part.
6231
+ * Matches: [A-Z] | [a-z] | [0-9] | _
6232
+ */ ShaderMacroProcessor._isIdentifierPart = function _isIdentifierPart(charCode) {
6233
+ return charCode >= 65 && charCode <= 90 || charCode >= 97 && charCode <= 122 || charCode >= 48 && charCode <= 57 || charCode === 95;
6234
+ };
6235
+ return ShaderMacroProcessor;
6236
+ }();
6237
+ ShaderMacroProcessor._valueMacros = new Map();
6238
+ ShaderMacroProcessor._funcMacros = new Map();
6239
+ ShaderMacroProcessor._shaderChunks = [];
6240
+ ShaderMacroProcessor._out = [];
6241
+ ShaderMacroProcessor._expandedNames = new Set();
6242
+ ShaderMacroProcessor._macroFirstChars = new Set();
6243
+ ShaderMacroProcessor._macroFirstCharsDirty = true;
6244
+ ShaderMacroProcessor._replaceWordParts = [];
6245
+ ShaderMacroProcessor._parsedFuncArgs = {
6246
+ values: [],
6247
+ end: 0
6248
+ };
6249
+
5786
6250
  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 ";
5787
6251
  /**
5788
6252
  * Shader pass containing vertex and fragment source.
5789
6253
  */ var ShaderPass = /*#__PURE__*/ function(ShaderPart) {
5790
6254
  _inherits(ShaderPass, ShaderPart);
5791
- function ShaderPass(nameOrVertexSource, vertexSourceOrFragmentSource, fragmentSourceOrTags, tags) {
6255
+ function ShaderPass(nameOrVertexSource, vertexSourceOrFragmentSourceOrInstructions, fragmentSourceOrTags, tagsOrPlatformTarget, tags) {
5792
6256
  var _this;
5793
6257
  _this = ShaderPart.call(this) || this, /** @internal */ _this._shaderPassId = 0, /** @internal */ _this._renderStateDataMap = {}, /** @internal */ _this._shaderProgramPools = [];
5794
6258
  _this._shaderPassId = ShaderPass._shaderPassCounter++;
5795
- if (typeof fragmentSourceOrTags === "string") {
6259
+ if (Array.isArray(vertexSourceOrFragmentSourceOrInstructions)) {
6260
+ // Instructions overload: (name, vertexInst, fragInst, platformTarget, tags?)
5796
6261
  _this._name = nameOrVertexSource;
5797
- _this._vertexSource = vertexSourceOrFragmentSource;
5798
- _this._fragmentSource = fragmentSourceOrTags;
6262
+ _this._vertexShaderInstructions = vertexSourceOrFragmentSourceOrInstructions;
6263
+ _this._fragmentShaderInstructions = fragmentSourceOrTags;
6264
+ _this._platformTarget = tagsOrPlatformTarget;
5799
6265
  tags = _extends({
5800
6266
  pipelineStage: PipelineStage.Forward
5801
6267
  }, tags);
6268
+ } else if (typeof fragmentSourceOrTags === "string") {
6269
+ // Named overload: (name, vertexSource, fragmentSource, tags?)
6270
+ _this._name = nameOrVertexSource;
6271
+ _this._vertexSource = vertexSourceOrFragmentSourceOrInstructions;
6272
+ _this._fragmentSource = fragmentSourceOrTags;
6273
+ tags = _extends({
6274
+ pipelineStage: PipelineStage.Forward
6275
+ }, tagsOrPlatformTarget);
5802
6276
  } else {
6277
+ // Unnamed overload: (vertexSource, fragmentSource, tags?)
5803
6278
  _this._name = "Default";
5804
6279
  _this._vertexSource = nameOrVertexSource;
5805
- _this._fragmentSource = vertexSourceOrFragmentSource;
6280
+ _this._fragmentSource = vertexSourceOrFragmentSourceOrInstructions;
5806
6281
  tags = _extends({
5807
6282
  pipelineStage: PipelineStage.Forward
5808
6283
  }, fragmentSourceOrTags);
@@ -5838,15 +6313,16 @@ var precisionStr = "\n #ifdef GL_FRAGMENT_PRECISION_HIGH\n precision hig
5838
6313
  shaderProgramPools.length = 0;
5839
6314
  };
5840
6315
  _proto._getCanonicalShaderProgram = function _getCanonicalShaderProgram(engine, macroCollection) {
5841
- if (this._platformTarget != undefined) {
5842
- return this._getShaderLabProgram(engine, macroCollection);
5843
- }
5844
- var _ShaderFactory_compilePlatformSource = ShaderFactory.compilePlatformSource(engine, macroCollection, this._vertexSource, this._fragmentSource), vertexSource = _ShaderFactory_compilePlatformSource.vertexSource, fragmentSource = _ShaderFactory_compilePlatformSource.fragmentSource;
6316
+ var _ref = this._platformTarget != undefined ? this._compileShaderLabSource(engine, macroCollection) : this._compilePlatformSource(engine, macroCollection), vertexSource = _ref.vertexSource, fragmentSource = _ref.fragmentSource;
5845
6317
  return new ShaderProgram(engine, vertexSource, fragmentSource);
5846
6318
  };
5847
- _proto._getShaderLabProgram = function _getShaderLabProgram(engine, macroCollection) {
6319
+ _proto._compilePlatformSource = function _compilePlatformSource(engine, macroCollection) {
6320
+ return ShaderFactory.compilePlatformSource(engine, macroCollection, this._vertexSource, this._fragmentSource);
6321
+ };
6322
+ _proto._compileShaderLabSource = function _compileShaderLabSource(engine, macroCollection) {
5848
6323
  var isWebGL2 = engine._hardwareRenderer.isWebGL2;
5849
- var shaderMacroList = new Array();
6324
+ var shaderMacroList = ShaderPass._shaderMacroList;
6325
+ shaderMacroList.length = 0;
5850
6326
  ShaderMacro._getMacrosElements(macroCollection, shaderMacroList);
5851
6327
  shaderMacroList.push(ShaderMacro.getByName(isWebGL2 ? "GRAPHICS_API_WEBGL2" : "GRAPHICS_API_WEBGL1"));
5852
6328
  if (engine._hardwareRenderer.canIUse(GLCapabilityType.shaderTextureLod)) {
@@ -5855,23 +6331,31 @@ var precisionStr = "\n #ifdef GL_FRAGMENT_PRECISION_HIGH\n precision hig
5855
6331
  if (engine._hardwareRenderer.canIUse(GLCapabilityType.standardDerivatives)) {
5856
6332
  shaderMacroList.push(ShaderMacro.getByName("HAS_DERIVATIVES"));
5857
6333
  }
5858
- var noIncludeVertex = ShaderFactory.parseIncludes(this._vertexSource);
5859
- var noIncludeFrag = ShaderFactory.parseIncludes(this._fragmentSource);
5860
- noIncludeVertex = Shader._shaderLab._parseMacros(noIncludeVertex, shaderMacroList);
5861
- noIncludeFrag = Shader._shaderLab._parseMacros(noIncludeFrag, shaderMacroList);
6334
+ var macroMap = ShaderPass._macroMap;
6335
+ macroMap.clear();
6336
+ for(var i = 0, n = shaderMacroList.length; i < n; i++){
6337
+ var macro = shaderMacroList[i];
6338
+ var _macro_value;
6339
+ macroMap.set(macro.name, (_macro_value = macro.value) != null ? _macro_value : "");
6340
+ }
6341
+ var vertexSource = ShaderMacroProcessor.evaluate(this._vertexShaderInstructions, macroMap);
6342
+ var fragmentSource = ShaderMacroProcessor.evaluate(this._fragmentShaderInstructions, macroMap);
5862
6343
  if (isWebGL2 && this._platformTarget === ShaderLanguage.GLSLES100) {
5863
- noIncludeVertex = ShaderFactory.convertTo300(noIncludeVertex);
5864
- noIncludeFrag = ShaderFactory.convertTo300(noIncludeFrag, true);
6344
+ vertexSource = ShaderFactory.convertTo300(vertexSource);
6345
+ fragmentSource = ShaderFactory.convertTo300(fragmentSource, true);
5865
6346
  }
5866
6347
  var versionStr = isWebGL2 ? "#version 300 es" : "#version 100";
5867
- var vertexSource = " " + versionStr + "\n " + noIncludeVertex + "\n ";
5868
- var fragmentSource = " " + versionStr + "\n " + (isWebGL2 ? "" : ShaderFactory._shaderExtension) + "\n " + precisionStr + "\n " + noIncludeFrag + "\n ";
5869
- return new ShaderProgram(engine, vertexSource, fragmentSource);
6348
+ return {
6349
+ vertexSource: " " + versionStr + "\n " + vertexSource + "\n ",
6350
+ fragmentSource: " " + versionStr + "\n " + (isWebGL2 ? "" : ShaderFactory._shaderExtension) + "\n " + precisionStr + "\n " + fragmentSource + "\n "
6351
+ };
5870
6352
  };
5871
6353
  return ShaderPass;
5872
6354
  }(ShaderPart);
5873
6355
  /** @internal */ ShaderPass._shaderPassCounter = 0;
5874
6356
  /** @internal */ ShaderPass._shaderRootPath = "shaders://root/";
6357
+ ShaderPass._shaderMacroList = [];
6358
+ ShaderPass._macroMap = new Map();
5875
6359
 
5876
6360
  /**
5877
6361
  * Sub shader.
@@ -6620,36 +7104,14 @@ __decorate([
6620
7104
  var subShaderList = shaderSource.subShaders.map(function(subShaderSource) {
6621
7105
  var passList = subShaderSource.passes.map(function(passSource) {
6622
7106
  if (passSource.isUsePass) {
6623
- var _Shader_find_subShaders_find, _Shader_find;
6624
- var _passSource_name_split = passSource.name.split("/"), shaderName = _passSource_name_split[0], subShaderName = _passSource_name_split[1], passName = _passSource_name_split[2];
6625
- return (_Shader_find = Shader.find(shaderName)) == null ? void 0 : (_Shader_find_subShaders_find = _Shader_find.subShaders.find(function(subShader) {
6626
- return subShader.name === subShaderName;
6627
- })) == null ? void 0 : _Shader_find_subShaders_find.passes.find(function(pass) {
6628
- return pass.name === passName;
6629
- });
7107
+ return Shader._resolveUsePass(passSource.name);
6630
7108
  }
6631
7109
  var shaderPassSource = Shader._shaderLab._parseShaderPass(passSource.contents, passSource.vertexEntry, passSource.fragmentEntry, vertexSourceOrShaderPassesOrSubShadersOrPlatformTarget, new URL(fragmentSourceOrPath != null ? fragmentSourceOrPath : "", ShaderPass._shaderRootPath).href);
6632
7110
  if (!shaderPassSource) {
6633
7111
  throw 'Shader pass "' + shaderSource.name + "." + subShaderSource.name + "." + passSource.name + '" parse failed, please check the shader source code.';
6634
7112
  }
6635
- var shaderPass = new ShaderPass(passSource.name, shaderPassSource.vertex, shaderPassSource.fragment, passSource.tags);
6636
- shaderPass._platformTarget = vertexSourceOrShaderPassesOrSubShadersOrPlatformTarget;
6637
- var _passSource_renderStates = passSource.renderStates, constantMap = _passSource_renderStates.constantMap, variableMap = _passSource_renderStates.variableMap;
6638
- // Compatible shader lab no render state use material `renderState` to modify render state
6639
- if (Object.keys(constantMap).length > 0 || Object.keys(variableMap).length > 0) {
6640
- // Parse const render state
6641
- var renderState = new RenderState();
6642
- for(var k in constantMap){
6643
- Shader._applyConstRenderStates(renderState, +k, constantMap[k]);
6644
- }
6645
- shaderPass._renderState = renderState;
6646
- // Parse variable render state
6647
- var renderStateDataMap = {};
6648
- for(var k1 in variableMap){
6649
- renderStateDataMap[k1] = ShaderProperty.getByName(variableMap[k1]);
6650
- }
6651
- shaderPass._renderStateDataMap = renderStateDataMap;
6652
- }
7113
+ var shaderPass = new ShaderPass(passSource.name, shaderPassSource.vertexShaderInstructions, shaderPassSource.fragmentShaderInstructions, vertexSourceOrShaderPassesOrSubShadersOrPlatformTarget, passSource.tags);
7114
+ Shader._applyRenderStates(shaderPass, passSource.renderStates.constantMap, passSource.renderStates.variableMap, false);
6653
7115
  return shaderPass;
6654
7116
  });
6655
7117
  return new SubShader(subShaderSource.name, passList, subShaderSource.tags);
@@ -6694,6 +7156,29 @@ __decorate([
6694
7156
  };
6695
7157
  /**
6696
7158
  * @internal
7159
+ */ Shader._createFromPrecompiled = function _createFromPrecompiled(data) {
7160
+ var shaderMap = Shader._shaderMap;
7161
+ if (shaderMap[data.name]) {
7162
+ console.error('Shader named "' + data.name + '" already exists.');
7163
+ return;
7164
+ }
7165
+ var subShaderList = data.subShaders.map(function(subData) {
7166
+ var passList = subData.passes.map(function(passData) {
7167
+ if (passData.isUsePass) {
7168
+ return Shader._resolveUsePass(passData.name);
7169
+ }
7170
+ var shaderPass = new ShaderPass(passData.name, passData.vertexShaderInstructions, passData.fragmentShaderInstructions, data.platformTarget, passData.tags);
7171
+ Shader._applyRenderStates(shaderPass, passData.renderStates.constantMap, passData.renderStates.variableMap, true);
7172
+ return shaderPass;
7173
+ });
7174
+ return new SubShader(subData.name, passList, subData.tags);
7175
+ });
7176
+ var shader = new Shader(data.name, subShaderList);
7177
+ shaderMap[data.name] = shader;
7178
+ return shader;
7179
+ };
7180
+ /**
7181
+ * @internal
6697
7182
  */ Shader._clear = function _clear(engine) {
6698
7183
  var shaderMap = Shader._shaderMap;
6699
7184
  for(var key in shaderMap){
@@ -6714,6 +7199,34 @@ __decorate([
6714
7199
  }
6715
7200
  }
6716
7201
  };
7202
+ Shader._resolveUsePass = function _resolveUsePass(passName) {
7203
+ var _Shader_find_subShaders_find, _Shader_find;
7204
+ var _passName_split = passName.split("/"), shaderName = _passName_split[0], subShaderName = _passName_split[1], passNamePart = _passName_split[2];
7205
+ return (_Shader_find = Shader.find(shaderName)) == null ? void 0 : (_Shader_find_subShaders_find = _Shader_find.subShaders.find(function(subShader) {
7206
+ return subShader.name === subShaderName;
7207
+ })) == null ? void 0 : _Shader_find_subShaders_find.passes.find(function(pass) {
7208
+ return pass.name === passNamePart;
7209
+ });
7210
+ };
7211
+ Shader._applyRenderStates = function _applyRenderStates(shaderPass, constantMap, variableMap, deserializeColor) {
7212
+ if (Object.keys(constantMap).length > 0 || Object.keys(variableMap).length > 0) {
7213
+ var renderState = new RenderState();
7214
+ for(var k in constantMap){
7215
+ var value = constantMap[k];
7216
+ if (deserializeColor && Array.isArray(value)) {
7217
+ Shader._applyConstRenderStates(renderState, +k, new Color(value[0], value[1], value[2], value[3]));
7218
+ } else {
7219
+ Shader._applyConstRenderStates(renderState, +k, value);
7220
+ }
7221
+ }
7222
+ shaderPass._renderState = renderState;
7223
+ var renderStateDataMap = {};
7224
+ for(var k1 in variableMap){
7225
+ renderStateDataMap[k1] = ShaderProperty.getByName(variableMap[k1]);
7226
+ }
7227
+ shaderPass._renderStateDataMap = renderStateDataMap;
7228
+ }
7229
+ };
6717
7230
  Shader._applyConstRenderStates = function _applyConstRenderStates(renderState, key, value) {
6718
7231
  switch(key){
6719
7232
  case RenderStateElementKey.BlendStateEnabled0:
@@ -9154,7 +9667,15 @@ var Camera = /*#__PURE__*/ function(Component) {
9154
9667
  */ _proto._getInvViewProjMat = function _getInvViewProjMat() {
9155
9668
  if (this._isInvViewProjDirty.flag) {
9156
9669
  this._isInvViewProjDirty.flag = false;
9157
- Matrix.multiply(this._entity.transform.worldMatrix, this._getInverseProjectionMatrix(), this._invViewProjMat);
9670
+ var matrix = this._invViewProjMat;
9671
+ if (this._isCustomViewMatrix) {
9672
+ Matrix.invert(this.viewMatrix, matrix);
9673
+ } else {
9674
+ // Ignore scale, consistent with viewMatrix getter
9675
+ var transform = this._entity.transform;
9676
+ Matrix.rotationTranslation(transform.worldRotationQuaternion, transform.worldPosition, matrix);
9677
+ }
9678
+ matrix.multiply(this._getInverseProjectionMatrix());
9158
9679
  }
9159
9680
  return this._invViewProjMat;
9160
9681
  };
@@ -22443,7 +22964,7 @@ __decorate([
22443
22964
  deepClone
22444
22965
  ], Skin.prototype, "inverseBindMatrices", void 0);
22445
22966
  __decorate([
22446
- ignoreClone
22967
+ deepClone
22447
22968
  ], Skin.prototype, "_skinMatrices", void 0);
22448
22969
  __decorate([
22449
22970
  ignoreClone
@@ -23443,7 +23964,10 @@ var ComponentCloner = /*#__PURE__*/ function() {
23443
23964
  _proto._setActiveComponents = function _setActiveComponents(isActive, activeChangeFlag) {
23444
23965
  var activeChangedComponents = this._activeChangedComponents;
23445
23966
  for(var i = 0, length = activeChangedComponents.length; i < length; ++i){
23446
- activeChangedComponents[i]._setActive(isActive, activeChangeFlag);
23967
+ var component = activeChangedComponents[i];
23968
+ // Skip components whose scene was already cleared by an earlier callback's removeChild
23969
+ if (!isActive && !component._entity._scene) continue;
23970
+ component._setActive(isActive, activeChangeFlag);
23447
23971
  }
23448
23972
  this._scene._componentsManager.putActiveChangedTempList(activeChangedComponents);
23449
23973
  this._activeChangedComponents = null;
@@ -23463,18 +23987,19 @@ var ComponentCloner = /*#__PURE__*/ function() {
23463
23987
  }
23464
23988
  };
23465
23989
  _proto._setInActiveInHierarchy = function _setInActiveInHierarchy(activeChangedComponents, activeChangeFlag) {
23990
+ // Children-first, reverse traversal for safe removeChild during callbacks
23991
+ var children = this._children;
23992
+ for(var i = children.length - 1; i >= 0; i--){
23993
+ var child = children[i];
23994
+ child.isActive && child._setInActiveInHierarchy(activeChangedComponents, activeChangeFlag);
23995
+ }
23466
23996
  activeChangeFlag & ActiveChangeFlag.Hierarchy && (this._isActiveInHierarchy = false);
23467
23997
  activeChangeFlag & ActiveChangeFlag.Scene && (this._isActiveInScene = false);
23468
23998
  var components = this._components;
23469
- for(var i = 0, n = components.length; i < n; i++){
23470
- var component = components[i];
23999
+ for(var i1 = 0, n = components.length; i1 < n; i1++){
24000
+ var component = components[i1];
23471
24001
  component.enabled && activeChangedComponents.push(component);
23472
24002
  }
23473
- var children = this._children;
23474
- for(var i1 = 0, n1 = children.length; i1 < n1; i1++){
23475
- var child = children[i1];
23476
- child.isActive && child._setInActiveInHierarchy(activeChangedComponents, activeChangeFlag);
23477
- }
23478
24003
  };
23479
24004
  _proto._setSiblingIndex = function _setSiblingIndex(sibling, target) {
23480
24005
  target = Math.min(target, sibling.length - 1);
@@ -24154,8 +24679,7 @@ PrimitiveChunk.subMeshPool = new ReturnableObjectPool(SubMesh, 10);
24154
24679
  /** Plain text. */ AssetType["Text"] = "Text";
24155
24680
  /** JSON. */ AssetType["JSON"] = "JSON";
24156
24681
  /** ArrayBuffer. */ AssetType["Buffer"] = "Buffer";
24157
- /** 2D Texture. */ AssetType["Texture2D"] = "Texture2D";
24158
- /** Cube Texture. */ AssetType["TextureCube"] = "TextureCube";
24682
+ /** Texture. */ AssetType["Texture"] = "Texture";
24159
24683
  /** Material. */ AssetType["Material"] = "Material";
24160
24684
  /** Shader. */ AssetType["Shader"] = "Shader";
24161
24685
  /** Mesh. */ AssetType["Mesh"] = "Mesh";
@@ -26387,7 +26911,7 @@ var depthOnlyVs = "#define MATERIAL_OMIT_NORMAL\n#include <common>\n#include <co
26387
26911
 
26388
26912
  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
26389
26913
 
26390
- 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
26914
+ 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
26391
26915
 
26392
26916
  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
26393
26917
 
@@ -26401,7 +26925,7 @@ var shadowMapVs = "#include <common>\n#include <common_vert>\n#include <blendSha
26401
26925
 
26402
26926
  var skyboxFs = "#include <common>\nuniform samplerCube material_CubeTexture;\n\nvarying vec3 v_cubeUV;\nuniform float material_Exposure;\nuniform vec4 material_TintColor;\n\nvoid main() {\n vec4 textureColor = textureCube( material_CubeTexture, v_cubeUV );\n\n #ifdef ENGINE_NO_SRGB\n textureColor = sRGBToLinear(textureColor);\n #endif\n\n textureColor.rgb *= material_Exposure * material_TintColor.rgb;\n \n gl_FragColor = textureColor;\n}\n"; // eslint-disable-line
26403
26927
 
26404
- var skyboxVs = "#include <common_vert>\n\nuniform mat4 camera_VPMat;\n\nvarying vec3 v_cubeUV;\nuniform float material_Rotation;\n\nvec4 rotateY(vec4 v, float angle) {\n\tconst float deg2rad = 3.1415926 / 180.0;\n\tfloat radian = angle * deg2rad;\n\tfloat sina = sin(radian);\n\tfloat cosa = cos(radian);\n\tmat2 m = mat2(cosa, -sina, sina, cosa);\n\treturn vec4(m * v.xz, v.yw).xzyw;\n}\n\nvoid main() {\n v_cubeUV = vec3( -POSITION.x, POSITION.yz ); // TextureCube is left-hand,so x need inverse\n gl_Position = camera_VPMat * rotateY(vec4(POSITION, 1.0), material_Rotation);\n}\n"; // eslint-disable-line
26928
+ var skyboxVs = "#include <common_vert>\n\nuniform mat4 camera_VPMat;\n\nvarying vec3 v_cubeUV;\nuniform float material_Rotation;\n\nvec4 rotateY(vec4 v, float angle) {\n\tconst float deg2rad = 3.1415926 / 180.0;\n\tfloat radian = angle * deg2rad;\n\tfloat sina = sin(radian);\n\tfloat cosa = cos(radian);\n\tmat2 m = mat2(cosa, -sina, sina, cosa);\n\treturn vec4(m * v.xz, v.yw).xzyw;\n}\n\nvoid main() {\n v_cubeUV = POSITION;\n gl_Position = camera_VPMat * rotateY(vec4(POSITION, 1.0), material_Rotation);\n}\n"; // eslint-disable-line
26405
26929
 
26406
26930
  var spriteMaskFs = "uniform sampler2D renderer_MaskTexture;\nuniform float renderer_MaskAlphaCutoff;\nvarying vec2 v_uv;\n\nvoid main()\n{\n vec4 color = texture2D(renderer_MaskTexture, v_uv);\n if (color.a < renderer_MaskAlphaCutoff) {\n discard;\n }\n\n gl_FragColor = color;\n}\n"; // eslint-disable-line
26407
26931
 
@@ -28857,45 +29381,6 @@ Scene._fogColorProperty = ShaderProperty.getByName("scene_FogColor");
28857
29381
  Scene._fogParamsProperty = ShaderProperty.getByName("scene_FogParams");
28858
29382
  Scene._prefilterdDFGProperty = ShaderProperty.getByName("scene_PrefilteredDFG");
28859
29383
 
28860
- function _array_like_to_array(arr, len) {
28861
- if (len == null || len > arr.length) len = arr.length;
28862
-
28863
- for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
28864
-
28865
- return arr2;
28866
- }
28867
-
28868
- function _unsupported_iterable_to_array(o, minLen) {
28869
- if (!o) return;
28870
- if (typeof o === "string") return _array_like_to_array(o, minLen);
28871
-
28872
- var n = Object.prototype.toString.call(o).slice(8, -1);
28873
-
28874
- if (n === "Object" && o.constructor) n = o.constructor.name;
28875
- if (n === "Map" || n === "Set") return Array.from(n);
28876
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
28877
- }
28878
-
28879
- function _create_for_of_iterator_helper_loose(o, allowArrayLike) {
28880
- var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
28881
-
28882
- if (it) return (it = it.call(o)).next.bind(it);
28883
- // Fallback for engines without symbol support
28884
- if (Array.isArray(o) || (it = _unsupported_iterable_to_array(o)) || allowArrayLike && o && typeof o.length === "number") {
28885
- if (it) o = it;
28886
-
28887
- var i = 0;
28888
-
28889
- return function() {
28890
- if (i >= o.length) return { done: true };
28891
-
28892
- return { done: false, value: o[i++] };
28893
- };
28894
- }
28895
-
28896
- throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
28897
- }
28898
-
28899
29384
  /**
28900
29385
  * Script class, used for logic writing.
28901
29386
  */ var Script = /*#__PURE__*/ function(Component) {
@@ -33290,7 +33775,7 @@ var ParticleStopMode = /*#__PURE__*/ function(ParticleStopMode) {
33290
33775
  _inherits(ParticleRenderer, Renderer);
33291
33776
  function ParticleRenderer(entity) {
33292
33777
  var _this;
33293
- _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 Vector3(), /** @internal */ _this._generatorBounds = new BoundingBox(), /** @internal */ _this._transformedBounds = new BoundingBox();
33778
+ _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 Vector3(), /** @internal */ _this._generatorBounds = new BoundingBox(), /** @internal */ _this._transformedBounds = new BoundingBox(), _this._renderMode = ParticleRenderMode.Billboard;
33294
33779
  _this._onGeneratorParamsChanged = _this._onGeneratorParamsChanged.bind(_this);
33295
33780
  _this.generator = new ParticleGenerator(_this);
33296
33781
  _this._currentRenderModeMacro = ParticleRenderer._billboardModeMacro;
@@ -33896,6 +34381,7 @@ ParticleTransformFeedbackSimulator._deltaTimeProperty = ShaderProperty.getByName
33896
34381
  ParticleRandomSubSeeds[ParticleRandomSubSeeds["GravityModifier"] = 2759560269] = "GravityModifier";
33897
34382
  ParticleRandomSubSeeds[ParticleRandomSubSeeds["ForceOverLifetime"] = 3875246972] = "ForceOverLifetime";
33898
34383
  ParticleRandomSubSeeds[ParticleRandomSubSeeds["LimitVelocityOverLifetime"] = 3047300990] = "LimitVelocityOverLifetime";
34384
+ ParticleRandomSubSeeds[ParticleRandomSubSeeds["Noise"] = 4105357473] = "Noise";
33899
34385
  return ParticleRandomSubSeeds;
33900
34386
  }({});
33901
34387
 
@@ -35279,7 +35765,7 @@ __decorate([
35279
35765
  return;
35280
35766
  }
35281
35767
  this._enabled = value;
35282
- this._generator._setTransformFeedback(value);
35768
+ this._generator._setTransformFeedback();
35283
35769
  this._generator._renderer._onGeneratorParamsChanged();
35284
35770
  }
35285
35771
  }
@@ -36225,6 +36711,298 @@ __decorate([
36225
36711
  ignoreClone
36226
36712
  ], TextureSheetAnimationModule.prototype, "_onTilingChanged", null);
36227
36713
 
36714
+ /**
36715
+ * Noise module for particle system.
36716
+ * Adds simplex noise-based turbulence displacement to particles.
36717
+ */ var NoiseModule = /*#__PURE__*/ function(ParticleGeneratorModule) {
36718
+ _inherits(NoiseModule, ParticleGeneratorModule);
36719
+ function NoiseModule(generator) {
36720
+ var _this;
36721
+ _this = ParticleGeneratorModule.call(this, generator) || this, /** @internal */ _this._noiseRand = new Rand(0, ParticleRandomSubSeeds.Noise), _this._noiseParams = new Vector4(), _this._noiseOctaveParams = new Vector4(), _this._strengthMinConst = new Vector3(), _this._scrollSpeed = 0, _this._separateAxes = false, _this._frequency = 0.5, _this._octaveCount = 1, _this._octaveIntensityMultiplier = 0.5, _this._octaveFrequencyMultiplier = 2.0;
36722
+ _this.strengthX = new ParticleCompositeCurve(1);
36723
+ _this.strengthY = new ParticleCompositeCurve(1);
36724
+ _this.strengthZ = new ParticleCompositeCurve(1);
36725
+ return _this;
36726
+ }
36727
+ var _proto = NoiseModule.prototype;
36728
+ /**
36729
+ * @internal
36730
+ */ _proto._updateShaderData = function _updateShaderData(shaderData) {
36731
+ var enabledMacro = null;
36732
+ var strengthCurveMacro = null;
36733
+ var strengthIsRandomTwoMacro = null;
36734
+ var separateAxesMacro = null;
36735
+ if (this.enabled) {
36736
+ enabledMacro = NoiseModule._enabledMacro;
36737
+ var strengthX = this._strengthX;
36738
+ var strengthY = this._strengthY;
36739
+ var strengthZ = this._strengthZ;
36740
+ var separateAxes = this._separateAxes;
36741
+ // Determine strength curve mode (following SOL pattern)
36742
+ var isRandomCurveMode = separateAxes ? strengthX.mode === ParticleCurveMode.TwoCurves && strengthY.mode === ParticleCurveMode.TwoCurves && strengthZ.mode === ParticleCurveMode.TwoCurves : strengthX.mode === ParticleCurveMode.TwoCurves;
36743
+ var isCurveMode = isRandomCurveMode || (separateAxes ? strengthX.mode === ParticleCurveMode.Curve && strengthY.mode === ParticleCurveMode.Curve && strengthZ.mode === ParticleCurveMode.Curve : strengthX.mode === ParticleCurveMode.Curve);
36744
+ var isRandomConstMode = separateAxes ? strengthX.mode === ParticleCurveMode.TwoConstants && strengthY.mode === ParticleCurveMode.TwoConstants && strengthZ.mode === ParticleCurveMode.TwoConstants : strengthX.mode === ParticleCurveMode.TwoConstants;
36745
+ // noiseParams.w = frequency (always needed)
36746
+ var noiseParams = this._noiseParams;
36747
+ if (isCurveMode) {
36748
+ // Curve/TwoCurves: encode curve data as float arrays
36749
+ shaderData.setFloatArray(NoiseModule._strengthMaxCurveXProperty, strengthX.curveMax._getTypeArray());
36750
+ if (separateAxes) {
36751
+ shaderData.setFloatArray(NoiseModule._strengthMaxCurveYProperty, strengthY.curveMax._getTypeArray());
36752
+ shaderData.setFloatArray(NoiseModule._strengthMaxCurveZProperty, strengthZ.curveMax._getTypeArray());
36753
+ }
36754
+ if (isRandomCurveMode) {
36755
+ shaderData.setFloatArray(NoiseModule._strengthMinCurveXProperty, strengthX.curveMin._getTypeArray());
36756
+ if (separateAxes) {
36757
+ shaderData.setFloatArray(NoiseModule._strengthMinCurveYProperty, strengthY.curveMin._getTypeArray());
36758
+ shaderData.setFloatArray(NoiseModule._strengthMinCurveZProperty, strengthZ.curveMin._getTypeArray());
36759
+ }
36760
+ strengthIsRandomTwoMacro = NoiseModule._strengthIsRandomTwoMacro;
36761
+ }
36762
+ strengthCurveMacro = NoiseModule._strengthCurveMacro;
36763
+ // xyz unused in curve mode, just set frequency
36764
+ noiseParams.set(0, 0, 0, this._frequency);
36765
+ } else {
36766
+ // Constant/TwoConstants: pack strength into noiseParams.xyz
36767
+ if (separateAxes) {
36768
+ noiseParams.set(strengthX.constantMax, strengthY.constantMax, strengthZ.constantMax, this._frequency);
36769
+ } else {
36770
+ var s = strengthX.constantMax;
36771
+ noiseParams.set(s, s, s, this._frequency);
36772
+ }
36773
+ if (isRandomConstMode) {
36774
+ var minConst = this._strengthMinConst;
36775
+ if (separateAxes) {
36776
+ minConst.set(strengthX.constantMin, strengthY.constantMin, strengthZ.constantMin);
36777
+ } else {
36778
+ var sMin = strengthX.constantMin;
36779
+ minConst.set(sMin, sMin, sMin);
36780
+ }
36781
+ shaderData.setVector3(NoiseModule._strengthMinConstProperty, minConst);
36782
+ strengthIsRandomTwoMacro = NoiseModule._strengthIsRandomTwoMacro;
36783
+ }
36784
+ }
36785
+ shaderData.setVector4(NoiseModule._noiseProperty, noiseParams);
36786
+ if (separateAxes) {
36787
+ separateAxesMacro = NoiseModule._separateAxesMacro;
36788
+ }
36789
+ var noiseOctaveParams = this._noiseOctaveParams;
36790
+ noiseOctaveParams.set(this._scrollSpeed, this._octaveCount, this._octaveIntensityMultiplier, this._octaveFrequencyMultiplier);
36791
+ shaderData.setVector4(NoiseModule._noiseOctaveProperty, noiseOctaveParams);
36792
+ }
36793
+ this._enabledModuleMacro = this._enableMacro(shaderData, this._enabledModuleMacro, enabledMacro);
36794
+ this._strengthCurveModeMacro = this._enableMacro(shaderData, this._strengthCurveModeMacro, strengthCurveMacro);
36795
+ this._strengthIsRandomTwoModeMacro = this._enableMacro(shaderData, this._strengthIsRandomTwoModeMacro, strengthIsRandomTwoMacro);
36796
+ this._separateAxesModeMacro = this._enableMacro(shaderData, this._separateAxesModeMacro, separateAxesMacro);
36797
+ };
36798
+ /**
36799
+ * @internal
36800
+ */ _proto._resetRandomSeed = function _resetRandomSeed(seed) {
36801
+ this._noiseRand.reset(seed, ParticleRandomSubSeeds.Noise);
36802
+ };
36803
+ _create_class(NoiseModule, [
36804
+ {
36805
+ key: "separateAxes",
36806
+ get: /**
36807
+ * Specifies whether the strength is separate on each axis, when disabled, only `strength` is used.
36808
+ */ function get() {
36809
+ return this._separateAxes;
36810
+ },
36811
+ set: function set(value) {
36812
+ if (value !== this._separateAxes) {
36813
+ this._separateAxes = value;
36814
+ this._generator._renderer._onGeneratorParamsChanged();
36815
+ }
36816
+ }
36817
+ },
36818
+ {
36819
+ key: "strengthX",
36820
+ get: /**
36821
+ * Noise strength. When `separateAxes` is disabled, applies to all axes.
36822
+ * When `separateAxes` is enabled, applies only to x axis.
36823
+ */ function get() {
36824
+ return this._strengthX;
36825
+ },
36826
+ set: function set(value) {
36827
+ var lastValue = this._strengthX;
36828
+ if (value !== lastValue) {
36829
+ this._strengthX = value;
36830
+ this._onCompositeCurveChange(lastValue, value);
36831
+ }
36832
+ }
36833
+ },
36834
+ {
36835
+ key: "strengthY",
36836
+ get: /**
36837
+ * Noise strength for y axis, used when `separateAxes` is enabled.
36838
+ */ function get() {
36839
+ return this._strengthY;
36840
+ },
36841
+ set: function set(value) {
36842
+ var lastValue = this._strengthY;
36843
+ if (value !== lastValue) {
36844
+ this._strengthY = value;
36845
+ this._onCompositeCurveChange(lastValue, value);
36846
+ }
36847
+ }
36848
+ },
36849
+ {
36850
+ key: "strengthZ",
36851
+ get: /**
36852
+ * Noise strength for z axis, used when `separateAxes` is enabled.
36853
+ */ function get() {
36854
+ return this._strengthZ;
36855
+ },
36856
+ set: function set(value) {
36857
+ var lastValue = this._strengthZ;
36858
+ if (value !== lastValue) {
36859
+ this._strengthZ = value;
36860
+ this._onCompositeCurveChange(lastValue, value);
36861
+ }
36862
+ }
36863
+ },
36864
+ {
36865
+ key: "frequency",
36866
+ get: /**
36867
+ * Noise spatial frequency.
36868
+ */ function get() {
36869
+ return this._frequency;
36870
+ },
36871
+ set: function set(value) {
36872
+ value = Math.max(1e-6, value);
36873
+ if (value !== this._frequency) {
36874
+ this._frequency = value;
36875
+ this._generator._renderer._onGeneratorParamsChanged();
36876
+ }
36877
+ }
36878
+ },
36879
+ {
36880
+ key: "scrollSpeed",
36881
+ get: /**
36882
+ * Noise field scroll speed over time.
36883
+ */ function get() {
36884
+ return this._scrollSpeed;
36885
+ },
36886
+ set: function set(value) {
36887
+ if (value !== this._scrollSpeed) {
36888
+ this._scrollSpeed = value;
36889
+ this._generator._renderer._onGeneratorParamsChanged();
36890
+ }
36891
+ }
36892
+ },
36893
+ {
36894
+ key: "octaveCount",
36895
+ get: /**
36896
+ * Number of noise octave layers (1-3).
36897
+ */ function get() {
36898
+ return this._octaveCount;
36899
+ },
36900
+ set: function set(value) {
36901
+ value = Math.max(1, Math.min(3, Math.floor(value)));
36902
+ if (value !== this._octaveCount) {
36903
+ this._octaveCount = value;
36904
+ this._generator._renderer._onGeneratorParamsChanged();
36905
+ }
36906
+ }
36907
+ },
36908
+ {
36909
+ key: "octaveIntensityMultiplier",
36910
+ get: /**
36911
+ * Intensity multiplier for each successive octave, only effective when `octaveCount` > 1.
36912
+ * Each layer's contribution is scaled by this factor relative to the previous layer, range [0, 1].
36913
+ */ function get() {
36914
+ return this._octaveIntensityMultiplier;
36915
+ },
36916
+ set: function set(value) {
36917
+ value = Math.max(0, Math.min(1, value));
36918
+ if (value !== this._octaveIntensityMultiplier) {
36919
+ this._octaveIntensityMultiplier = value;
36920
+ this._generator._renderer._onGeneratorParamsChanged();
36921
+ }
36922
+ }
36923
+ },
36924
+ {
36925
+ key: "octaveFrequencyMultiplier",
36926
+ get: /**
36927
+ * Frequency multiplier for each successive octave, only effective when `octaveCount` > 1.
36928
+ * Each layer samples at this multiple of the previous layer's frequency, range [1, 4].
36929
+ */ function get() {
36930
+ return this._octaveFrequencyMultiplier;
36931
+ },
36932
+ set: function set(value) {
36933
+ value = Math.max(1, Math.min(4, value));
36934
+ if (value !== this._octaveFrequencyMultiplier) {
36935
+ this._octaveFrequencyMultiplier = value;
36936
+ this._generator._renderer._onGeneratorParamsChanged();
36937
+ }
36938
+ }
36939
+ },
36940
+ {
36941
+ key: "enabled",
36942
+ get: function get() {
36943
+ return this._enabled;
36944
+ },
36945
+ set: function set(value) {
36946
+ if (value !== this._enabled) {
36947
+ if (value && !this._generator._renderer.engine._hardwareRenderer.isWebGL2) {
36948
+ return;
36949
+ }
36950
+ this._enabled = value;
36951
+ this._generator._setTransformFeedback();
36952
+ this._generator._renderer._onGeneratorParamsChanged();
36953
+ }
36954
+ }
36955
+ }
36956
+ ]);
36957
+ return NoiseModule;
36958
+ }(ParticleGeneratorModule);
36959
+ NoiseModule._enabledMacro = ShaderMacro.getByName("RENDERER_NOISE_MODULE_ENABLED");
36960
+ NoiseModule._strengthCurveMacro = ShaderMacro.getByName("RENDERER_NOISE_STRENGTH_CURVE");
36961
+ NoiseModule._strengthIsRandomTwoMacro = ShaderMacro.getByName("RENDERER_NOISE_STRENGTH_IS_RANDOM_TWO");
36962
+ NoiseModule._separateAxesMacro = ShaderMacro.getByName("RENDERER_NOISE_IS_SEPARATE");
36963
+ NoiseModule._noiseProperty = ShaderProperty.getByName("renderer_NoiseParams");
36964
+ NoiseModule._noiseOctaveProperty = ShaderProperty.getByName("renderer_NoiseOctaveParams");
36965
+ NoiseModule._strengthMinConstProperty = ShaderProperty.getByName("renderer_NoiseStrengthMinConst");
36966
+ NoiseModule._strengthMaxCurveXProperty = ShaderProperty.getByName("renderer_NoiseStrengthMaxCurveX");
36967
+ NoiseModule._strengthMaxCurveYProperty = ShaderProperty.getByName("renderer_NoiseStrengthMaxCurveY");
36968
+ NoiseModule._strengthMaxCurveZProperty = ShaderProperty.getByName("renderer_NoiseStrengthMaxCurveZ");
36969
+ NoiseModule._strengthMinCurveXProperty = ShaderProperty.getByName("renderer_NoiseStrengthMinCurveX");
36970
+ NoiseModule._strengthMinCurveYProperty = ShaderProperty.getByName("renderer_NoiseStrengthMinCurveY");
36971
+ NoiseModule._strengthMinCurveZProperty = ShaderProperty.getByName("renderer_NoiseStrengthMinCurveZ");
36972
+ __decorate([
36973
+ ignoreClone
36974
+ ], NoiseModule.prototype, "_enabledModuleMacro", void 0);
36975
+ __decorate([
36976
+ ignoreClone
36977
+ ], NoiseModule.prototype, "_strengthCurveModeMacro", void 0);
36978
+ __decorate([
36979
+ ignoreClone
36980
+ ], NoiseModule.prototype, "_strengthIsRandomTwoModeMacro", void 0);
36981
+ __decorate([
36982
+ ignoreClone
36983
+ ], NoiseModule.prototype, "_separateAxesModeMacro", void 0);
36984
+ __decorate([
36985
+ ignoreClone
36986
+ ], NoiseModule.prototype, "_noiseRand", void 0);
36987
+ __decorate([
36988
+ ignoreClone
36989
+ ], NoiseModule.prototype, "_noiseParams", void 0);
36990
+ __decorate([
36991
+ ignoreClone
36992
+ ], NoiseModule.prototype, "_noiseOctaveParams", void 0);
36993
+ __decorate([
36994
+ ignoreClone
36995
+ ], NoiseModule.prototype, "_strengthMinConst", void 0);
36996
+ __decorate([
36997
+ deepClone
36998
+ ], NoiseModule.prototype, "_strengthX", void 0);
36999
+ __decorate([
37000
+ deepClone
37001
+ ], NoiseModule.prototype, "_strengthY", void 0);
37002
+ __decorate([
37003
+ deepClone
37004
+ ], NoiseModule.prototype, "_strengthZ", void 0);
37005
+
36228
37006
  /**
36229
37007
  * Velocity over lifetime module.
36230
37008
  */ var VelocityOverLifetimeModule = /*#__PURE__*/ function(ParticleGeneratorModule) {
@@ -36431,6 +37209,7 @@ __decorate([
36431
37209
  this.forceOverLifetime = new ForceOverLifetimeModule(this);
36432
37210
  this.sizeOverLifetime = new SizeOverLifetimeModule(this);
36433
37211
  this.limitVelocityOverLifetime = new LimitVelocityOverLifetimeModule(this);
37212
+ this.noise = new NoiseModule(this);
36434
37213
  this.emission.enabled = true;
36435
37214
  }
36436
37215
  var _proto = ParticleGenerator.prototype;
@@ -36738,6 +37517,7 @@ __decorate([
36738
37517
  this.sizeOverLifetime._updateShaderData(shaderData);
36739
37518
  this.rotationOverLifetime._updateShaderData(shaderData);
36740
37519
  this.colorOverLifetime._updateShaderData(shaderData);
37520
+ this.noise._updateShaderData(shaderData);
36741
37521
  };
36742
37522
  /**
36743
37523
  * @internal
@@ -36751,16 +37531,19 @@ __decorate([
36751
37531
  this.limitVelocityOverLifetime._resetRandomSeed(seed);
36752
37532
  this.rotationOverLifetime._resetRandomSeed(seed);
36753
37533
  this.colorOverLifetime._resetRandomSeed(seed);
37534
+ this.noise._resetRandomSeed(seed);
36754
37535
  };
36755
37536
  /**
36756
37537
  * @internal
36757
- */ _proto._setTransformFeedback = function _setTransformFeedback(enabled) {
36758
- this._useTransformFeedback = enabled;
37538
+ */ _proto._setTransformFeedback = function _setTransformFeedback() {
37539
+ var needed = this.limitVelocityOverLifetime.enabled || this.noise.enabled;
37540
+ if (needed === this._useTransformFeedback) return;
37541
+ this._useTransformFeedback = needed;
36759
37542
  // Switching TF mode invalidates all active particle state: feedback buffers and instance
36760
37543
  // buffer layout are incompatible between the two paths. Clear rather than show a one-frame
36761
37544
  // jump; new particles will fill in naturally from the next emit cycle.
36762
37545
  this._clearActiveParticles();
36763
- if (enabled) {
37546
+ if (needed) {
36764
37547
  if (!this._feedbackSimulator) {
36765
37548
  this._feedbackSimulator = new ParticleTransformFeedbackSimulator(this._renderer.engine);
36766
37549
  }
@@ -36810,9 +37593,7 @@ __decorate([
36810
37593
  /**
36811
37594
  * @internal
36812
37595
  */ _proto._cloneTo = function _cloneTo(target) {
36813
- if (target.limitVelocityOverLifetime.enabled) {
36814
- target._setTransformFeedback(true);
36815
- }
37596
+ target._setTransformFeedback();
36816
37597
  };
36817
37598
  /**
36818
37599
  * @internal
@@ -36974,10 +37755,6 @@ __decorate([
36974
37755
  // Start rotation
36975
37756
  var startRotationRand = main._startRotationRand, flipRotation = main.flipRotation;
36976
37757
  var isFlip = flipRotation > startRotationRand.random();
36977
- // @todo:None-Mesh mode should inverse the rotation, maybe should unify it
36978
- if (this._renderer.renderMode !== ParticleRenderMode.Mesh) {
36979
- isFlip = !isFlip;
36980
- }
36981
37758
  var rotationZ = main.startRotationZ.evaluate(undefined, startRotationRand.random());
36982
37759
  if (main.startRotation3D) {
36983
37760
  var rotationX = main.startRotationX.evaluate(undefined, startRotationRand.random());
@@ -37003,7 +37780,9 @@ __decorate([
37003
37780
  if (colorOverLifetime.enabled && colorOverLifetime.color.mode === ParticleGradientMode.TwoGradients) {
37004
37781
  instanceVertices[offset + 20] = colorOverLifetime._colorGradientRand.random();
37005
37782
  }
37006
- // instanceVertices[offset + 21] = rand.random();
37783
+ if (this.noise.enabled) {
37784
+ instanceVertices[offset + 21] = this.noise._noiseRand.random();
37785
+ }
37007
37786
  var rotationOverLifetime = this.rotationOverLifetime;
37008
37787
  if (rotationOverLifetime.enabled && rotationOverLifetime.rotationZ.mode === ParticleCurveMode.TwoConstants) {
37009
37788
  instanceVertices[offset + 22] = rotationOverLifetime._rotationRand.random();
@@ -37291,6 +38070,21 @@ __decorate([
37291
38070
  out.transform(rotateMat);
37292
38071
  min.add(worldOffsetMin);
37293
38072
  max.add(worldOffsetMax);
38073
+ // Noise module impact: noise output is normalized to [-1, 1],
38074
+ // max displacement = |strength_max|
38075
+ var noise = this.noise;
38076
+ if (noise.enabled) {
38077
+ var noiseMaxX, noiseMaxY, noiseMaxZ;
38078
+ if (noise.separateAxes) {
38079
+ noiseMaxX = Math.abs(noise.strengthX._getMax());
38080
+ noiseMaxY = Math.abs(noise.strengthY._getMax());
38081
+ noiseMaxZ = Math.abs(noise.strengthZ._getMax());
38082
+ } else {
38083
+ noiseMaxX = noiseMaxY = noiseMaxZ = Math.abs(noise.strengthX._getMax());
38084
+ }
38085
+ min.set(min.x - noiseMaxX, min.y - noiseMaxY, min.z - noiseMaxZ);
38086
+ max.set(max.x + noiseMaxX, max.y + noiseMaxY, max.z + noiseMaxZ);
38087
+ }
37294
38088
  min.add(worldPosition);
37295
38089
  max.add(worldPosition);
37296
38090
  };
@@ -37388,6 +38182,9 @@ __decorate([
37388
38182
  __decorate([
37389
38183
  deepClone
37390
38184
  ], ParticleGenerator.prototype, "textureSheetAnimation", void 0);
38185
+ __decorate([
38186
+ deepClone
38187
+ ], ParticleGenerator.prototype, "noise", void 0);
37391
38188
  __decorate([
37392
38189
  ignoreClone
37393
38190
  ], ParticleGenerator.prototype, "_playTime", void 0);
@@ -39460,5 +40257,5 @@ __decorate([
39460
40257
 
39461
40258
  Polyfill.registerPolyfill();
39462
40259
 
39463
- export { AmbientLight, AmbientOcclusion, AmbientOcclusionQuality, AnimationArrayCurve, AnimationBoolCurve, AnimationClip, AnimationClipCurveBinding, AnimationColorCurve, AnimationCurve, AnimationEvent, AnimationFloatArrayCurve, AnimationFloatCurve, AnimationQuaternionCurve, AnimationRectCurve, AnimationRefCurve, AnimationStringCurve, AnimationVector2Curve, AnimationVector3Curve, AnimationVector4Curve, Animator, AnimatorCondition, AnimatorConditionMode, AnimatorController, AnimatorControllerLayer, AnimatorControllerParameter, AnimatorCullingMode, AnimatorLayerBlendingMode, AnimatorLayerMask, AnimatorState, AnimatorStateMachine, AnimatorStateTransition, AntiAliasing, AssetPromise, AssetType, AudioClip, AudioManager, AudioSource, Background, BackgroundMode, BackgroundTextureFillMode, BaseMaterial, BasicRenderPipeline, BatchUtils, BlendFactor, BlendMode, BlendOperation, BlendShape, BlendShapeFrame, BlendState, BlinnPhongMaterial, Blitter, BloomDownScaleMode, BloomEffect, BoolUpdateFlag, BoxColliderShape, BoxShape, Buffer, BufferAsset, BufferBindFlag, BufferMesh, BufferUsage, BufferUtil, Burst, Camera, CameraClearFlags, CameraModifyFlags, CameraType, Canvas, CapsuleColliderShape, CharRenderInfo, CharacterController, CircleShape, ClearableObjectPool, CloneManager, CloneUtils, Collider, ColliderShape, ColliderShapeUpAxis, Collision, CollisionDetectionMode, ColorOverLifetimeModule, ColorWriteMask, CompareFunction, Component, ConeEmitType, ConeShape, ContactPoint, ContentRestorer, ControllerCollisionFlag, ControllerNonWalkableMode, CubeProbe, CullMode, CurveKey, DataType, DependentMode, DepthState, DepthTextureMode, DiffuseMode, DirectLight, DisorderedArray, Downsampling, DynamicCollider, DynamicColliderConstraints, EmissionModule, Engine, EngineObject, Entity, EntityModifyFlags, EventDispatcher, FinalPass, FixedJoint, FogMode, Font, FontStyle, GLCapabilityType, GradientAlphaKey, GradientColorKey, HemisphereShape, HingeJoint, HitResult, IndexBufferBinding, IndexFormat, InputManager, InterpolationType, JSONAsset, Joint, JointLimits, JointMotor, Keyframe, Keys, Layer, LayerPathMask, Light, LimitVelocityOverLifetimeModule, Loader, Logger, MSAASamples, MainModule, Material, Mesh, MeshColliderShape, MeshColliderShapeCookingFlag, MeshRenderer, MeshShape, MeshTopology, ModelMesh, OverflowMode, PBRMaterial, ParticleCompositeCurve, ParticleCompositeGradient, ParticleCurve, ParticleCurveMode, ParticleGenerator, ParticleGradient, ParticleGradientMode, ParticleMaterial, ParticleRenderMode, ParticleRenderer, ParticleScaleMode, ParticleShapeArcMode, ParticleShapeType, ParticleSimulationSpace, ParticleStopMode, PhysicsMaterial, PhysicsMaterialCombineMode, PhysicsScene, PipelineStage, PlaneColliderShape, Platform, PointLight, Pointer, PointerButton, PointerEventData, PointerEventEmitter, PointerPhase, PostProcess, PostProcessEffect, PostProcessEffectBoolParameter, PostProcessEffectColorParameter, PostProcessEffectEnumParameter, PostProcessEffectFloatParameter, PostProcessEffectParameter, PostProcessEffectTextureParameter, PostProcessEffectVector2Parameter, PostProcessEffectVector3Parameter, PostProcessEffectVector4Parameter, PostProcessManager, PostProcessPass, PostProcessPassEvent, PostProcessUberPass, Primitive, PrimitiveMesh, Probe, RasterState, ReferResource, RefractionMode, RenderBufferDepthFormat, RenderFace, RenderQueue, RenderQueueFlags, RenderQueueType, RenderState, RenderStateElementKey, RenderTarget, RenderTargetBlendState, Renderer, RendererUpdateFlags, RenderingStatistics, ReplacementFailureStrategy, ResourceManager, ReturnableObjectPool, RotationOverLifetimeModule, SafeLoopArray, Scene, SceneManager, Script, SetDataOptions, Shader, ShaderData, ShaderDataGroup, ShaderFactory, ShaderLanguage, ShaderLib, ShaderMacro, ShaderMacroCollection, ShaderPass, ShaderProperty, ShaderPropertyType, ShaderTagKey, ShadowCascadesMode, ShadowResolution, ShadowType, Signal, SimpleSpriteAssembler, SizeOverLifetimeModule, Skin, SkinnedMeshRenderer, Sky, SkyBoxMaterial, SkyProceduralMaterial, SlicedSpriteAssembler, SphereColliderShape, SphereShape, SpotLight, SpringJoint, Sprite, SpriteAtlas, SpriteDrawMode, SpriteMask, SpriteMaskInteraction, SpriteMaskLayer, SpriteModifyFlags, SpriteRenderer, SpriteTileMode, StateMachineScript, StaticCollider, StencilOperation, StencilState, SubFont, SubMesh, SubPrimitive, SubShader, SunMode, SystemInfo, TextAsset, TextHorizontalAlignment, TextRenderer, TextUtils, TextVerticalAlignment, Texture, Texture2D, Texture2DArray, TextureCoordinate, TextureCube, TextureCubeFace, TextureDepthCompareFunction, TextureFilterMode, TextureFormat, TextureSheetAnimationModule, TextureUsage, TextureUtils, TextureWrapMode, TiledSpriteAssembler, Time, TonemappingEffect, TonemappingMode, TrailMaterial, TrailRenderer, TrailTextureMode, Transform, TransformModifyFlags, UnlitMaterial, Utils, VelocityOverLifetimeModule, VertexAttribute, VertexBufferBinding, VertexElement, VertexElementFormat, WrapMode, XRManager, assignmentClone, deepClone, dependentComponents, ignoreClone, registerPointerEventEmitter, request, resourceLoader, shallowClone };
40260
+ export { AmbientLight, AmbientOcclusion, AmbientOcclusionQuality, AnimationArrayCurve, AnimationBoolCurve, AnimationClip, AnimationClipCurveBinding, AnimationColorCurve, AnimationCurve, AnimationEvent, AnimationFloatArrayCurve, AnimationFloatCurve, AnimationQuaternionCurve, AnimationRectCurve, AnimationRefCurve, AnimationStringCurve, AnimationVector2Curve, AnimationVector3Curve, AnimationVector4Curve, Animator, AnimatorCondition, AnimatorConditionMode, AnimatorController, AnimatorControllerLayer, AnimatorControllerParameter, AnimatorCullingMode, AnimatorLayerBlendingMode, AnimatorLayerMask, AnimatorState, AnimatorStateMachine, AnimatorStateTransition, AntiAliasing, AssetPromise, AssetType, AudioClip, AudioManager, AudioSource, Background, BackgroundMode, BackgroundTextureFillMode, BaseMaterial, BasicRenderPipeline, BatchUtils, BlendFactor, BlendMode, BlendOperation, BlendShape, BlendShapeFrame, BlendState, BlinnPhongMaterial, Blitter, BloomDownScaleMode, BloomEffect, BoolUpdateFlag, BoxColliderShape, BoxShape, Buffer, BufferAsset, BufferBindFlag, BufferMesh, BufferUsage, BufferUtil, Burst, Camera, CameraClearFlags, CameraModifyFlags, CameraType, Canvas, CapsuleColliderShape, CharRenderInfo, CharacterController, CircleShape, ClearableObjectPool, CloneManager, CloneUtils, Collider, ColliderShape, ColliderShapeUpAxis, Collision, CollisionDetectionMode, ColorOverLifetimeModule, ColorWriteMask, CompareFunction, Component, ConeEmitType, ConeShape, ContactPoint, ContentRestorer, ControllerCollisionFlag, ControllerNonWalkableMode, CubeProbe, CullMode, CurveKey, DataType, DependentMode, DepthState, DepthTextureMode, DiffuseMode, DirectLight, DisorderedArray, Downsampling, DynamicCollider, DynamicColliderConstraints, EmissionModule, Engine, EngineObject, Entity, EntityModifyFlags, EventDispatcher, FinalPass, FixedJoint, FogMode, Font, FontStyle, GLCapabilityType, GradientAlphaKey, GradientColorKey, HemisphereShape, HingeJoint, HitResult, IndexBufferBinding, IndexFormat, InputManager, InterpolationType, JSONAsset, Joint, JointLimits, JointMotor, Keyframe, Keys, Layer, LayerPathMask, Light, LimitVelocityOverLifetimeModule, Loader, Logger, MSAASamples, MainModule, Material, Mesh, MeshColliderShape, MeshColliderShapeCookingFlag, MeshRenderer, MeshShape, MeshTopology, ModelMesh, NoiseModule, OverflowMode, PBRMaterial, ParticleCompositeCurve, ParticleCompositeGradient, ParticleCurve, ParticleCurveMode, ParticleGenerator, ParticleGradient, ParticleGradientMode, ParticleMaterial, ParticleRenderMode, ParticleRenderer, ParticleScaleMode, ParticleShapeArcMode, ParticleShapeType, ParticleSimulationSpace, ParticleStopMode, PhysicsMaterial, PhysicsMaterialCombineMode, PhysicsScene, PipelineStage, PlaneColliderShape, Platform, PointLight, Pointer, PointerButton, PointerEventData, PointerEventEmitter, PointerPhase, PostProcess, PostProcessEffect, PostProcessEffectBoolParameter, PostProcessEffectColorParameter, PostProcessEffectEnumParameter, PostProcessEffectFloatParameter, PostProcessEffectParameter, PostProcessEffectTextureParameter, PostProcessEffectVector2Parameter, PostProcessEffectVector3Parameter, PostProcessEffectVector4Parameter, PostProcessManager, PostProcessPass, PostProcessPassEvent, PostProcessUberPass, Primitive, PrimitiveMesh, Probe, RasterState, ReferResource, RefractionMode, RenderBufferDepthFormat, RenderFace, RenderQueue, RenderQueueFlags, RenderQueueType, RenderState, RenderStateElementKey, RenderTarget, RenderTargetBlendState, Renderer, RendererUpdateFlags, RenderingStatistics, ReplacementFailureStrategy, ResourceManager, ReturnableObjectPool, RotationOverLifetimeModule, SafeLoopArray, Scene, SceneManager, Script, SetDataOptions, Shader, ShaderData, ShaderDataGroup, ShaderFactory, ShaderLanguage, ShaderLib, ShaderMacro, ShaderMacroCollection, ShaderPass, ShaderProperty, ShaderPropertyType, ShaderTagKey, ShadowCascadesMode, ShadowResolution, ShadowType, Signal, SimpleSpriteAssembler, SizeOverLifetimeModule, Skin, SkinnedMeshRenderer, Sky, SkyBoxMaterial, SkyProceduralMaterial, SlicedSpriteAssembler, SphereColliderShape, SphereShape, SpotLight, SpringJoint, Sprite, SpriteAtlas, SpriteDrawMode, SpriteMask, SpriteMaskInteraction, SpriteMaskLayer, SpriteModifyFlags, SpriteRenderer, SpriteTileMode, StateMachineScript, StaticCollider, StencilOperation, StencilState, SubFont, SubMesh, SubPrimitive, SubShader, SunMode, SystemInfo, TextAsset, TextHorizontalAlignment, TextRenderer, TextUtils, TextVerticalAlignment, Texture, Texture2D, Texture2DArray, TextureCoordinate, TextureCube, TextureCubeFace, TextureDepthCompareFunction, TextureFilterMode, TextureFormat, TextureSheetAnimationModule, TextureUsage, TextureUtils, TextureWrapMode, TiledSpriteAssembler, Time, TonemappingEffect, TonemappingMode, TrailMaterial, TrailRenderer, TrailTextureMode, Transform, TransformModifyFlags, UnlitMaterial, Utils, VelocityOverLifetimeModule, VertexAttribute, VertexBufferBinding, VertexElement, VertexElementFormat, WrapMode, XRManager, assignmentClone, deepClone, dependentComponents, ignoreClone, registerPointerEventEmitter, request, resourceLoader, shallowClone };
39464
40261
  //# sourceMappingURL=module.js.map