@aura3d/rendering 2.0.4 → 3.0.0
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/AtmosphereWetness.d.ts +61 -0
- package/dist/AtmosphereWetness.d.ts.map +1 -0
- package/dist/AtmosphereWetness.js +99 -0
- package/dist/AtmosphereWetness.js.map +1 -0
- package/dist/ClusteredForwardLighting.d.ts +25 -1
- package/dist/ClusteredForwardLighting.d.ts.map +1 -1
- package/dist/ClusteredForwardLighting.js +80 -3
- package/dist/ClusteredForwardLighting.js.map +1 -1
- package/dist/DayNightSky.d.ts +63 -0
- package/dist/DayNightSky.d.ts.map +1 -0
- package/dist/DayNightSky.js +156 -0
- package/dist/DayNightSky.js.map +1 -0
- package/dist/EnvironmentPresetPack.d.ts +30 -0
- package/dist/EnvironmentPresetPack.d.ts.map +1 -0
- package/dist/EnvironmentPresetPack.js +49 -0
- package/dist/EnvironmentPresetPack.js.map +1 -0
- package/dist/ForwardPass.d.ts +65 -0
- package/dist/ForwardPass.d.ts.map +1 -1
- package/dist/ForwardPass.js +196 -2
- package/dist/ForwardPass.js.map +1 -1
- package/dist/InstancedPBRMaterial.d.ts +1 -0
- package/dist/InstancedPBRMaterial.d.ts.map +1 -1
- package/dist/InstancedPBRMaterial.js +3 -0
- package/dist/InstancedPBRMaterial.js.map +1 -1
- package/dist/InstancingDiagnostics.d.ts +69 -0
- package/dist/InstancingDiagnostics.d.ts.map +1 -0
- package/dist/InstancingDiagnostics.js +98 -0
- package/dist/InstancingDiagnostics.js.map +1 -0
- package/dist/LightingRig.d.ts +19 -1
- package/dist/LightingRig.d.ts.map +1 -1
- package/dist/LightingRig.js +61 -1
- package/dist/LightingRig.js.map +1 -1
- package/dist/MeshConsolidation.d.ts +12 -0
- package/dist/MeshConsolidation.d.ts.map +1 -1
- package/dist/MeshConsolidation.js +28 -0
- package/dist/MeshConsolidation.js.map +1 -1
- package/dist/MorphTargetPlan.d.ts +29 -2
- package/dist/MorphTargetPlan.d.ts.map +1 -1
- package/dist/MorphTargetPlan.js +23 -4
- package/dist/MorphTargetPlan.js.map +1 -1
- package/dist/NormalMappedPBRMaterial.d.ts.map +1 -1
- package/dist/NormalMappedPBRMaterial.js +22 -2
- package/dist/NormalMappedPBRMaterial.js.map +1 -1
- package/dist/OceanSurface.d.ts +75 -0
- package/dist/OceanSurface.d.ts.map +1 -1
- package/dist/OceanSurface.js +211 -0
- package/dist/OceanSurface.js.map +1 -1
- package/dist/PBRMaterial.d.ts +1 -0
- package/dist/PBRMaterial.d.ts.map +1 -1
- package/dist/PBRMaterial.js +23 -2
- package/dist/PBRMaterial.js.map +1 -1
- package/dist/PbrReference.d.ts +48 -0
- package/dist/PbrReference.d.ts.map +1 -1
- package/dist/PbrReference.js +126 -0
- package/dist/PbrReference.js.map +1 -1
- package/dist/PlanarReflection.d.ts +221 -0
- package/dist/PlanarReflection.d.ts.map +1 -0
- package/dist/PlanarReflection.js +541 -0
- package/dist/PlanarReflection.js.map +1 -0
- package/dist/PostProcessPass.d.ts +13 -0
- package/dist/PostProcessPass.d.ts.map +1 -1
- package/dist/PostProcessPass.js +15 -4
- package/dist/PostProcessPass.js.map +1 -1
- package/dist/ReflectionSurfaces.d.ts +14 -0
- package/dist/ReflectionSurfaces.d.ts.map +1 -1
- package/dist/ReflectionSurfaces.js +93 -0
- package/dist/ReflectionSurfaces.js.map +1 -1
- package/dist/RenderDevice.d.ts +87 -0
- package/dist/RenderDevice.d.ts.map +1 -1
- package/dist/RenderDevice.js +85 -0
- package/dist/RenderDevice.js.map +1 -1
- package/dist/Renderer.js +3 -1
- package/dist/Renderer.js.map +1 -1
- package/dist/RendererPostprocessPlan.d.ts +48 -0
- package/dist/RendererPostprocessPlan.d.ts.map +1 -1
- package/dist/RendererPostprocessPlan.js +101 -11
- package/dist/RendererPostprocessPlan.js.map +1 -1
- package/dist/RendererVisualPipelineReport.d.ts.map +1 -1
- package/dist/RendererVisualPipelineReport.js +3 -1
- package/dist/RendererVisualPipelineReport.js.map +1 -1
- package/dist/Sampler.d.ts +29 -0
- package/dist/Sampler.d.ts.map +1 -1
- package/dist/Sampler.js +47 -0
- package/dist/Sampler.js.map +1 -1
- package/dist/SdfText.d.ts +250 -0
- package/dist/SdfText.d.ts.map +1 -0
- package/dist/SdfText.js +551 -0
- package/dist/SdfText.js.map +1 -0
- package/dist/ShaderChunks.d.ts.map +1 -1
- package/dist/ShaderChunks.js +30 -12
- package/dist/ShaderChunks.js.map +1 -1
- package/dist/ShaderLibrary.d.ts.map +1 -1
- package/dist/ShaderLibrary.js +478 -34
- package/dist/ShaderLibrary.js.map +1 -1
- package/dist/ShaderLibraryCore.d.ts.map +1 -1
- package/dist/ShaderLibraryCore.js +70 -12
- package/dist/ShaderLibraryCore.js.map +1 -1
- package/dist/ShadowMap.d.ts +24 -0
- package/dist/ShadowMap.d.ts.map +1 -1
- package/dist/ShadowMap.js +43 -0
- package/dist/ShadowMap.js.map +1 -1
- package/dist/SkinnedLitMaterial.d.ts.map +1 -1
- package/dist/SkinnedLitMaterial.js +2 -0
- package/dist/SkinnedLitMaterial.js.map +1 -1
- package/dist/SkinningBounds.d.ts +10 -0
- package/dist/SkinningBounds.d.ts.map +1 -1
- package/dist/SkinningBounds.js +27 -0
- package/dist/SkinningBounds.js.map +1 -1
- package/dist/SpriteFlipbook.d.ts +60 -0
- package/dist/SpriteFlipbook.d.ts.map +1 -0
- package/dist/SpriteFlipbook.js +128 -0
- package/dist/SpriteFlipbook.js.map +1 -0
- package/dist/TerrainTiles.d.ts +120 -0
- package/dist/TerrainTiles.d.ts.map +1 -0
- package/dist/TerrainTiles.js +221 -0
- package/dist/TerrainTiles.js.map +1 -0
- package/dist/TexturedPBRMaterial.d.ts +1 -0
- package/dist/TexturedPBRMaterial.d.ts.map +1 -1
- package/dist/TexturedPBRMaterial.js +23 -2
- package/dist/TexturedPBRMaterial.js.map +1 -1
- package/dist/TexturedUnlitMaterial.d.ts.map +1 -1
- package/dist/TexturedUnlitMaterial.js +20 -2
- package/dist/TexturedUnlitMaterial.js.map +1 -1
- package/dist/UnlitMaterial.d.ts.map +1 -1
- package/dist/UnlitMaterial.js +20 -2
- package/dist/UnlitMaterial.js.map +1 -1
- package/dist/VertexFormat.d.ts +6 -0
- package/dist/VertexFormat.d.ts.map +1 -1
- package/dist/VertexFormat.js +12 -0
- package/dist/VertexFormat.js.map +1 -1
- package/dist/VolumetricFog.d.ts +55 -0
- package/dist/VolumetricFog.d.ts.map +1 -0
- package/dist/VolumetricFog.js +91 -0
- package/dist/VolumetricFog.js.map +1 -0
- package/dist/WaterSurface.d.ts +77 -0
- package/dist/WaterSurface.d.ts.map +1 -0
- package/dist/WaterSurface.js +133 -0
- package/dist/WaterSurface.js.map +1 -0
- package/dist/WebGL2Device.d.ts +58 -0
- package/dist/WebGL2Device.d.ts.map +1 -1
- package/dist/WebGL2Device.js +536 -17
- package/dist/WebGL2Device.js.map +1 -1
- package/dist/WebGPUDevice.d.ts +50 -0
- package/dist/WebGPUDevice.d.ts.map +1 -1
- package/dist/WebGPUDevice.js +504 -10
- package/dist/WebGPUDevice.js.map +1 -1
- package/dist/WebGPUSkinningLimits.d.ts +40 -0
- package/dist/WebGPUSkinningLimits.d.ts.map +1 -1
- package/dist/WebGPUSkinningLimits.js +32 -0
- package/dist/WebGPUSkinningLimits.js.map +1 -1
- package/dist/effects/CollisionModule.d.ts +9 -0
- package/dist/effects/CollisionModule.d.ts.map +1 -1
- package/dist/effects/CollisionModule.js +10 -0
- package/dist/effects/CollisionModule.js.map +1 -1
- package/dist/effects/ColorModule.d.ts +7 -0
- package/dist/effects/ColorModule.d.ts.map +1 -1
- package/dist/effects/ColorModule.js +23 -0
- package/dist/effects/ColorModule.js.map +1 -1
- package/dist/effects/ForceModule.d.ts +35 -0
- package/dist/effects/ForceModule.d.ts.map +1 -1
- package/dist/effects/ForceModule.js +49 -0
- package/dist/effects/ForceModule.js.map +1 -1
- package/dist/effects/GPUParticleBackend.d.ts +186 -0
- package/dist/effects/GPUParticleBackend.d.ts.map +1 -1
- package/dist/effects/GPUParticleBackend.js +692 -1
- package/dist/effects/GPUParticleBackend.js.map +1 -1
- package/dist/effects/HeightfieldModule.d.ts +58 -0
- package/dist/effects/HeightfieldModule.d.ts.map +1 -0
- package/dist/effects/HeightfieldModule.js +129 -0
- package/dist/effects/HeightfieldModule.js.map +1 -0
- package/dist/effects/LightingModule.d.ts +34 -0
- package/dist/effects/LightingModule.d.ts.map +1 -0
- package/dist/effects/LightingModule.js +54 -0
- package/dist/effects/LightingModule.js.map +1 -0
- package/dist/effects/ParticleDiagnostics.d.ts +8 -0
- package/dist/effects/ParticleDiagnostics.d.ts.map +1 -1
- package/dist/effects/ParticleDiagnostics.js +3 -0
- package/dist/effects/ParticleDiagnostics.js.map +1 -1
- package/dist/effects/ParticleModule.d.ts +8 -0
- package/dist/effects/ParticleModule.d.ts.map +1 -1
- package/dist/effects/ParticleModule.js.map +1 -1
- package/dist/effects/ParticleRenderer.d.ts +20 -0
- package/dist/effects/ParticleRenderer.d.ts.map +1 -1
- package/dist/effects/ParticleRenderer.js +57 -7
- package/dist/effects/ParticleRenderer.js.map +1 -1
- package/dist/effects/ParticleSystem.d.ts +45 -1
- package/dist/effects/ParticleSystem.d.ts.map +1 -1
- package/dist/effects/ParticleSystem.js +373 -4
- package/dist/effects/ParticleSystem.js.map +1 -1
- package/dist/effects/SizeModule.d.ts +4 -0
- package/dist/effects/SizeModule.d.ts.map +1 -1
- package/dist/effects/SizeModule.js +16 -0
- package/dist/effects/SizeModule.js.map +1 -1
- package/dist/effects/SubEmitterModule.d.ts +61 -0
- package/dist/effects/SubEmitterModule.d.ts.map +1 -0
- package/dist/effects/SubEmitterModule.js +119 -0
- package/dist/effects/SubEmitterModule.js.map +1 -0
- package/dist/effects/TrailModule.d.ts +38 -0
- package/dist/effects/TrailModule.d.ts.map +1 -1
- package/dist/effects/TrailModule.js +95 -2
- package/dist/effects/TrailModule.js.map +1 -1
- package/dist/effects/TurbulenceModule.d.ts +43 -0
- package/dist/effects/TurbulenceModule.d.ts.map +1 -0
- package/dist/effects/TurbulenceModule.js +130 -0
- package/dist/effects/TurbulenceModule.js.map +1 -0
- package/dist/effects/index.d.ts +4 -0
- package/dist/effects/index.d.ts.map +1 -1
- package/dist/effects/index.js +4 -0
- package/dist/effects/index.js.map +1 -1
- package/dist/index.d.ts +57 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -10
- package/dist/index.js.map +1 -1
- package/dist/materials/MaterialExtensions.js +3 -3
- package/dist/materials/MaterialExtensions.js.map +1 -1
- package/dist/postprocess/NativeBloomPyramid.d.ts +28 -0
- package/dist/postprocess/NativeBloomPyramid.d.ts.map +1 -0
- package/dist/postprocess/NativeBloomPyramid.js +54 -0
- package/dist/postprocess/NativeBloomPyramid.js.map +1 -0
- package/dist/postprocess/NativeLdrEffectLuts.d.ts +10 -1
- package/dist/postprocess/NativeLdrEffectLuts.d.ts.map +1 -1
- package/dist/postprocess/NativeLdrEffectLuts.js +19 -2
- package/dist/postprocess/NativeLdrEffectLuts.js.map +1 -1
- package/dist/postprocess/index.d.ts +2 -0
- package/dist/postprocess/index.d.ts.map +1 -1
- package/dist/postprocess/index.js +1 -0
- package/dist/postprocess/index.js.map +1 -1
- package/dist/production-runtime/PBRHDRPipeline.d.ts +22 -0
- package/dist/production-runtime/PBRHDRPipeline.d.ts.map +1 -1
- package/dist/production-runtime/PBRHDRPipeline.js +125 -0
- package/dist/production-runtime/PBRHDRPipeline.js.map +1 -1
- package/dist/production-runtime/ProductionWebGPURenderer.d.ts +52 -0
- package/dist/production-runtime/ProductionWebGPURenderer.d.ts.map +1 -1
- package/dist/production-runtime/ProductionWebGPURenderer.js +101 -0
- package/dist/production-runtime/ProductionWebGPURenderer.js.map +1 -1
- package/dist/production-runtime/index.d.ts +5 -4
- package/dist/production-runtime/index.d.ts.map +1 -1
- package/dist/production-runtime/index.js +3 -2
- package/dist/production-runtime/index.js.map +1 -1
- package/dist/production-runtime/passes/DepthPrepass.d.ts +26 -1
- package/dist/production-runtime/passes/DepthPrepass.d.ts.map +1 -1
- package/dist/production-runtime/passes/DepthPrepass.js +49 -2
- package/dist/production-runtime/passes/DepthPrepass.js.map +1 -1
- package/dist/production-runtime/passes/FramegraphTopology.d.ts +13 -0
- package/dist/production-runtime/passes/FramegraphTopology.d.ts.map +1 -0
- package/dist/production-runtime/passes/FramegraphTopology.js +59 -0
- package/dist/production-runtime/passes/FramegraphTopology.js.map +1 -0
- package/dist/production-runtime/passes/OpaquePass.d.ts +24 -1
- package/dist/production-runtime/passes/OpaquePass.d.ts.map +1 -1
- package/dist/production-runtime/passes/OpaquePass.js +41 -2
- package/dist/production-runtime/passes/OpaquePass.js.map +1 -1
- package/dist/production-runtime/passes/ShadowPass.d.ts +24 -1
- package/dist/production-runtime/passes/ShadowPass.d.ts.map +1 -1
- package/dist/production-runtime/passes/ShadowPass.js +43 -2
- package/dist/production-runtime/passes/ShadowPass.js.map +1 -1
- package/dist/production-runtime/passes/SkyboxPass.d.ts +21 -1
- package/dist/production-runtime/passes/SkyboxPass.d.ts.map +1 -1
- package/dist/production-runtime/passes/SkyboxPass.js +39 -2
- package/dist/production-runtime/passes/SkyboxPass.js.map +1 -1
- package/dist/production-runtime/passes/ToneMappingPass.d.ts +29 -1
- package/dist/production-runtime/passes/ToneMappingPass.d.ts.map +1 -1
- package/dist/production-runtime/passes/ToneMappingPass.js +53 -2
- package/dist/production-runtime/passes/ToneMappingPass.js.map +1 -1
- package/dist/production-runtime/passes/TransparentPass.d.ts +24 -1
- package/dist/production-runtime/passes/TransparentPass.d.ts.map +1 -1
- package/dist/production-runtime/passes/TransparentPass.js +42 -2
- package/dist/production-runtime/passes/TransparentPass.js.map +1 -1
- package/dist/shadows/CascadeHysteresis.d.ts +67 -0
- package/dist/shadows/CascadeHysteresis.d.ts.map +1 -0
- package/dist/shadows/CascadeHysteresis.js +104 -0
- package/dist/shadows/CascadeHysteresis.js.map +1 -0
- package/dist/shadows/ContactShadows.d.ts +52 -0
- package/dist/shadows/ContactShadows.d.ts.map +1 -1
- package/dist/shadows/ContactShadows.js +122 -0
- package/dist/shadows/ContactShadows.js.map +1 -1
- package/dist/shadows/SpotShadowMaps.d.ts +77 -0
- package/dist/shadows/SpotShadowMaps.d.ts.map +1 -0
- package/dist/shadows/SpotShadowMaps.js +106 -0
- package/dist/shadows/SpotShadowMaps.js.map +1 -0
- package/dist/webgpu/WebGPUPostProcess.d.ts +2 -0
- package/dist/webgpu/WebGPUPostProcess.d.ts.map +1 -1
- package/dist/webgpu/WebGPUPostProcess.js +1 -0
- package/dist/webgpu/WebGPUPostProcess.js.map +1 -1
- package/dist/webgpu/WebGPUPostShaders.d.ts +78 -0
- package/dist/webgpu/WebGPUPostShaders.d.ts.map +1 -0
- package/dist/webgpu/WebGPUPostShaders.js +262 -0
- package/dist/webgpu/WebGPUPostShaders.js.map +1 -0
- package/package.json +3 -3
package/dist/ShaderLibrary.js
CHANGED
|
@@ -94,6 +94,7 @@ uniform float u_metallic;
|
|
|
94
94
|
uniform float u_roughness;
|
|
95
95
|
uniform vec3 u_environmentColor;
|
|
96
96
|
uniform float u_environmentIntensity;
|
|
97
|
+
uniform float u_materialEnvironmentIntensity;
|
|
97
98
|
uniform vec3 u_environmentSkyColor;
|
|
98
99
|
uniform vec3 u_environmentHorizonColor;
|
|
99
100
|
uniform vec3 u_environmentGroundColor;
|
|
@@ -141,6 +142,19 @@ uniform float u_pointShadowSlopeBias;
|
|
|
141
142
|
uniform vec2 u_pointShadowTexelSize;
|
|
142
143
|
uniform float u_pointShadowPcfSampleCount;
|
|
143
144
|
uniform vec4 u_pointShadowPcfSamples[32];
|
|
145
|
+
uniform sampler2D u_spotShadowMapTexture;
|
|
146
|
+
uniform float u_spotShadowMapEnabled;
|
|
147
|
+
uniform vec3 u_spotShadowLightPosition;
|
|
148
|
+
uniform vec3 u_spotShadowLightDirection;
|
|
149
|
+
uniform mat4 u_spotShadowMatrix;
|
|
150
|
+
uniform vec2 u_spotShadowCone;
|
|
151
|
+
uniform float u_spotShadowRange;
|
|
152
|
+
uniform float u_spotShadowStrength;
|
|
153
|
+
uniform float u_spotShadowBias;
|
|
154
|
+
uniform float u_spotShadowSlopeBias;
|
|
155
|
+
uniform vec2 u_spotShadowTexelSize;
|
|
156
|
+
uniform float u_spotShadowPcfSampleCount;
|
|
157
|
+
uniform vec4 u_spotShadowPcfSamples[32];
|
|
144
158
|
uniform float u_outputColorSpace;
|
|
145
159
|
uniform vec3 u_cameraPosition;
|
|
146
160
|
uniform float u_environmentFogEnabled;
|
|
@@ -150,6 +164,9 @@ uniform float u_environmentFogNear;
|
|
|
150
164
|
uniform float u_environmentFogFar;
|
|
151
165
|
uniform float u_environmentFogDensity;
|
|
152
166
|
uniform float u_environmentFogHeightFalloff;
|
|
167
|
+
uniform float u_volumetricIntensity;
|
|
168
|
+
uniform vec3 u_volumetricLightDirection;
|
|
169
|
+
uniform vec3 u_volumetricLightColor;
|
|
153
170
|
uniform float u_environmentFogHeightReference;
|
|
154
171
|
uniform float u_environmentFogMaxOpacity;
|
|
155
172
|
in vec3 v_normal;
|
|
@@ -228,6 +245,50 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
228
245
|
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
229
246
|
return mix(1.0, 1.0 - occlusion, clamp(u_pointShadowStrength, 0.0, 1.0));
|
|
230
247
|
}
|
|
248
|
+
float a3dSpotShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
249
|
+
if (u_spotShadowMapEnabled < 0.5) return 1.0;
|
|
250
|
+
vec3 toFragment = worldPosition - u_spotShadowLightPosition;
|
|
251
|
+
float distanceToLight = max(length(toFragment), 0.0001);
|
|
252
|
+
if (distanceToLight > u_spotShadowRange) return 1.0;
|
|
253
|
+
vec3 coneAxis = u_spotShadowLightDirection / max(length(u_spotShadowLightDirection), 0.0001);
|
|
254
|
+
if (dot(toFragment / distanceToLight, coneAxis) < cos(u_spotShadowCone.x)) return 1.0;
|
|
255
|
+
vec4 lightPosition = u_spotShadowMatrix * vec4(worldPosition, 1.0);
|
|
256
|
+
vec3 projected = lightPosition.xyz / max(lightPosition.w, 0.0001);
|
|
257
|
+
vec2 uv = projected.xy * 0.5 + 0.5;
|
|
258
|
+
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 1.0;
|
|
259
|
+
vec3 receiverNormal = normalize(normal);
|
|
260
|
+
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
261
|
+
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
262
|
+
// Shared bias-table policy: the same per-sample, tangent-scaled slope bias as the
|
|
263
|
+
// directional and point-cube paths. A centre-only bias under-compensates outer PCF
|
|
264
|
+
// taps on sloped receivers, so each tap scales by its own texel distance.
|
|
265
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
266
|
+
float slopeTexelBias = slopeTangent * u_spotShadowSlopeBias * max(u_spotShadowTexelSize.x, u_spotShadowTexelSize.y);
|
|
267
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
268
|
+
float shadowed = 0.0;
|
|
269
|
+
float totalWeight = 0.0;
|
|
270
|
+
int sampleCount = clamp(int(u_spotShadowPcfSampleCount), 1, 32);
|
|
271
|
+
for (int i = 0; i < 32; ++i) {
|
|
272
|
+
if (i >= sampleCount) break;
|
|
273
|
+
vec4 sampleData = u_spotShadowPcfSamples[i];
|
|
274
|
+
float weight = max(sampleData.z, 0.0);
|
|
275
|
+
vec2 offset = sampleData.xy * u_spotShadowTexelSize;
|
|
276
|
+
float storedDepth = texture(u_spotShadowMapTexture, uv + offset).r;
|
|
277
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
278
|
+
float receiverDepth = projectedDepth - u_spotShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
279
|
+
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
280
|
+
totalWeight += weight;
|
|
281
|
+
}
|
|
282
|
+
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
283
|
+
return mix(1.0, 1.0 - occlusion, clamp(u_spotShadowStrength, 0.0, 1.0));
|
|
284
|
+
}
|
|
285
|
+
float a3dResolveSpotShadowOverride(float baseFactor, float kind, float shadowFlag, vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
286
|
+
// Spot-kind lights (kind == 2) sample the perspective spot map only when it is
|
|
287
|
+
// bound. Every gate term is 0 when no spot map is present, so mix() returns
|
|
288
|
+
// baseFactor exactly and scenes without spot lights render unchanged.
|
|
289
|
+
float spotGate = step(1.5, kind) * (1.0 - step(2.5, kind)) * step(0.5, u_spotShadowMapEnabled) * step(0.5, shadowFlag);
|
|
290
|
+
return mix(baseFactor, a3dSpotShadowFactor(worldPosition, normal, lightDirection), spotGate);
|
|
291
|
+
}
|
|
231
292
|
vec2 a3dEnvironmentEquirectUv(vec3 direction, float rotation) {
|
|
232
293
|
vec3 d = normalize(direction);
|
|
233
294
|
float u = atan(d.z, d.x) / 6.28318530718 + 0.5 + rotation;
|
|
@@ -282,7 +343,7 @@ vec3 a3dPbrEnvironmentDiffuseInput(vec3 normal) {
|
|
|
282
343
|
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureIntensity);
|
|
283
344
|
float diffuseEnvironmentLod = max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
284
345
|
vec3 sampledDiffuse = a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(normal, diffuseEnvironmentLod));
|
|
285
|
-
return mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight);
|
|
346
|
+
return mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity * u_materialEnvironmentIntensity, sampledEnvironmentWeight);
|
|
286
347
|
}
|
|
287
348
|
vec3 a3dPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, float roughness) {
|
|
288
349
|
float proceduralEnvironmentWeight = step(0.0001, u_environmentMapIntensity);
|
|
@@ -304,7 +365,7 @@ vec3 a3dPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, float rough
|
|
|
304
365
|
vec3 sampledSpecular = a3dPbrBoundHdrSpecularRadiance(a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(reflectionDirection, environmentLod)));
|
|
305
366
|
float nDotV = clamp(dot(normal, viewDirection), 0.0, 1.0);
|
|
306
367
|
sampledSpecular = a3dPbrClampSampledSpecularEdgeEnergy(sampledSpecular, nDotV, clampedRoughness);
|
|
307
|
-
sampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(0.84, 0.58, clampedRoughness);
|
|
368
|
+
sampledSpecular *= u_environmentMapTextureSpecularIntensity * u_materialEnvironmentIntensity * sampledEnvironmentWeight * mix(0.84, 0.58, clampedRoughness);
|
|
308
369
|
return proceduralSpecular + sampledSpecular;
|
|
309
370
|
}
|
|
310
371
|
vec2 a3dPbrEnvironmentBrdfInput(vec3 normal, vec3 viewDirection, float roughness) {
|
|
@@ -312,10 +373,16 @@ vec2 a3dPbrEnvironmentBrdfInput(vec3 normal, vec3 viewDirection, float roughness
|
|
|
312
373
|
vec2 lut = texture(u_environmentBrdfLutTexture, vec2(nDotV, clamp(roughness, 0.0, 1.0))).rg;
|
|
313
374
|
return mix(vec2(1.0, 0.0), lut, step(0.0001, u_environmentBrdfLutEnabled));
|
|
314
375
|
}
|
|
376
|
+
vec3 a3dLinearToSrgb(vec3 linear) {
|
|
377
|
+
vec3 clamped = max(linear, vec3(0.0));
|
|
378
|
+
vec3 low = clamped * 12.92;
|
|
379
|
+
vec3 high = 1.055 * pow(clamped, vec3(1.0 / 2.4)) - 0.055;
|
|
380
|
+
return mix(low, high, step(vec3(0.0031308), clamped));
|
|
381
|
+
}
|
|
315
382
|
vec3 a3dPbrEncodeOutput(vec3 linearColor) {
|
|
316
383
|
vec3 color = max(linearColor, vec3(0.0));
|
|
317
384
|
vec3 filmic = clamp((color * (2.51 * color + 0.03)) / (color * (2.43 * color + 0.59) + 0.14), vec3(0.0), vec3(1.0));
|
|
318
|
-
vec3 srgb =
|
|
385
|
+
vec3 srgb = a3dLinearToSrgb(filmic);
|
|
319
386
|
return mix(color, srgb, step(0.5, u_outputColorSpace));
|
|
320
387
|
}
|
|
321
388
|
void main() {
|
|
@@ -376,7 +443,7 @@ void main() {
|
|
|
376
443
|
float inner = cos(spotShadowLayer.x * max(1.0 - spotShadowLayer.y, 0.001));
|
|
377
444
|
attenuation *= smoothstep(outer, inner, cone);
|
|
378
445
|
}
|
|
379
|
-
float shadowFactor = mix(1.0, kind > 0.5 && kind < 1.5 ? a3dPointShadowFactor(v_worldPosition, normal, lightDirection) : a3dForwardShadowFactor(v_worldPosition, normal, lightDirection), step(0.5, spotShadowLayer.z));
|
|
446
|
+
float shadowFactor = a3dResolveSpotShadowOverride(mix(1.0, kind > 0.5 && kind < 1.5 ? a3dPointShadowFactor(v_worldPosition, normal, lightDirection) : a3dForwardShadowFactor(v_worldPosition, normal, lightDirection), step(0.5, spotShadowLayer.z)), kind, spotShadowLayer.z, v_worldPosition, normal, lightDirection);
|
|
380
447
|
shaded += a3dPbrDirectLight(normal, viewDirection, lightDirection, colorIntensity.rgb, colorIntensity.a * attenuation * shadowFactor, base, u_metallic, u_roughness, 1.0, vec3(1.0));
|
|
381
448
|
}
|
|
382
449
|
float alpha = u_baseColor.a * v_instanceColor.a;
|
|
@@ -395,10 +462,18 @@ precision highp float;
|
|
|
395
462
|
layout(location = 0) in vec3 a_position;
|
|
396
463
|
layout(location = 2) in vec2 a_uv;
|
|
397
464
|
layout(location = 4) in vec4 a_color;
|
|
465
|
+
layout(location = 8) in vec4 a_instanceMatrix0;
|
|
466
|
+
layout(location = 9) in vec4 a_instanceMatrix1;
|
|
467
|
+
layout(location = 10) in vec4 a_instanceMatrix2;
|
|
468
|
+
layout(location = 11) in vec4 a_instanceMatrix3;
|
|
469
|
+
layout(location = 12) in vec4 a_instanceColor;
|
|
398
470
|
uniform mat4 u_modelViewProjection;
|
|
399
471
|
uniform vec2 u_baseColorTextureOffset;
|
|
400
472
|
uniform vec2 u_baseColorTextureScale;
|
|
401
473
|
uniform float u_baseColorTextureRotation;
|
|
474
|
+
uniform mat4 u_instanceMatrices[64];
|
|
475
|
+
uniform float u_instanceCount;
|
|
476
|
+
uniform float u_instanceAttributeMode;
|
|
402
477
|
out vec2 v_uv;
|
|
403
478
|
out vec4 v_vertexColor;
|
|
404
479
|
void main() {
|
|
@@ -406,8 +481,19 @@ void main() {
|
|
|
406
481
|
float c = cos(u_baseColorTextureRotation);
|
|
407
482
|
float s = sin(u_baseColorTextureRotation);
|
|
408
483
|
v_uv = vec2(scaledUv.x * c - scaledUv.y * s, scaledUv.x * s + scaledUv.y * c) + u_baseColorTextureOffset;
|
|
409
|
-
|
|
410
|
-
|
|
484
|
+
// P2 instanced-GLB path (muse3jsparity-PRD): the u_instanceCount branch is
|
|
485
|
+
// taken only for items carrying instanceTransforms; every other draw keeps
|
|
486
|
+
// the legacy math bit-exact.
|
|
487
|
+
if (u_instanceCount > 0.5) {
|
|
488
|
+
int instanceIndex = clamp(gl_InstanceID, 0, max(int(u_instanceCount) - 1, 0));
|
|
489
|
+
mat4 attributeMatrix = mat4(a_instanceMatrix0, a_instanceMatrix1, a_instanceMatrix2, a_instanceMatrix3);
|
|
490
|
+
mat4 instanceMatrix = u_instanceAttributeMode > 0.5 ? attributeMatrix : u_instanceMatrices[instanceIndex];
|
|
491
|
+
v_vertexColor = a_color * a_instanceColor;
|
|
492
|
+
gl_Position = u_modelViewProjection * instanceMatrix * vec4(a_position, 1.0);
|
|
493
|
+
} else {
|
|
494
|
+
v_vertexColor = a_color;
|
|
495
|
+
gl_Position = u_modelViewProjection * vec4(a_position, 1.0);
|
|
496
|
+
}
|
|
411
497
|
}
|
|
412
498
|
`,
|
|
413
499
|
fragment: `#version 300 es
|
|
@@ -508,6 +594,7 @@ uniform float u_baseColorTextureEnabled;
|
|
|
508
594
|
uniform sampler2D u_normalTexture;
|
|
509
595
|
uniform float u_normalTextureEnabled;
|
|
510
596
|
uniform float u_normalScale;
|
|
597
|
+
uniform float u_wrinkleStrength;
|
|
511
598
|
uniform sampler2D u_metallicRoughnessTexture;
|
|
512
599
|
uniform float u_metallicRoughnessTextureEnabled;
|
|
513
600
|
uniform sampler2D u_occlusionTexture;
|
|
@@ -520,6 +607,7 @@ uniform float u_metallic;
|
|
|
520
607
|
uniform float u_roughness;
|
|
521
608
|
uniform vec3 u_environmentColor;
|
|
522
609
|
uniform float u_environmentIntensity;
|
|
610
|
+
uniform float u_materialEnvironmentIntensity;
|
|
523
611
|
uniform vec3 u_environmentSkyColor;
|
|
524
612
|
uniform vec3 u_environmentHorizonColor;
|
|
525
613
|
uniform vec3 u_environmentGroundColor;
|
|
@@ -593,6 +681,19 @@ uniform float u_pointShadowSlopeBias;
|
|
|
593
681
|
uniform vec2 u_pointShadowTexelSize;
|
|
594
682
|
uniform float u_pointShadowPcfSampleCount;
|
|
595
683
|
uniform vec4 u_pointShadowPcfSamples[32];
|
|
684
|
+
uniform sampler2D u_spotShadowMapTexture;
|
|
685
|
+
uniform float u_spotShadowMapEnabled;
|
|
686
|
+
uniform vec3 u_spotShadowLightPosition;
|
|
687
|
+
uniform vec3 u_spotShadowLightDirection;
|
|
688
|
+
uniform mat4 u_spotShadowMatrix;
|
|
689
|
+
uniform vec2 u_spotShadowCone;
|
|
690
|
+
uniform float u_spotShadowRange;
|
|
691
|
+
uniform float u_spotShadowStrength;
|
|
692
|
+
uniform float u_spotShadowBias;
|
|
693
|
+
uniform float u_spotShadowSlopeBias;
|
|
694
|
+
uniform vec2 u_spotShadowTexelSize;
|
|
695
|
+
uniform float u_spotShadowPcfSampleCount;
|
|
696
|
+
uniform vec4 u_spotShadowPcfSamples[32];
|
|
596
697
|
uniform float u_outputColorSpace;
|
|
597
698
|
uniform vec3 u_cameraPosition;
|
|
598
699
|
uniform float u_environmentFogEnabled;
|
|
@@ -602,6 +703,9 @@ uniform float u_environmentFogNear;
|
|
|
602
703
|
uniform float u_environmentFogFar;
|
|
603
704
|
uniform float u_environmentFogDensity;
|
|
604
705
|
uniform float u_environmentFogHeightFalloff;
|
|
706
|
+
uniform float u_volumetricIntensity;
|
|
707
|
+
uniform vec3 u_volumetricLightDirection;
|
|
708
|
+
uniform vec3 u_volumetricLightColor;
|
|
605
709
|
uniform float u_environmentFogHeightReference;
|
|
606
710
|
uniform float u_environmentFogMaxOpacity;
|
|
607
711
|
in vec3 v_normal;
|
|
@@ -649,6 +753,17 @@ vec4 a3dPbrEnvironmentSampleRaw(vec3 direction, float lod) {
|
|
|
649
753
|
vec4 cubeSample = textureLod(u_environmentCubeMapTexture, a3dEnvironmentCubeDirection(direction, u_environmentMapTextureRotation), lod);
|
|
650
754
|
return mix(equirectSample, cubeSample, step(0.5, u_environmentCubeMapTextureEnabled));
|
|
651
755
|
}
|
|
756
|
+
/**
|
|
757
|
+
* Procedural wrinkle detail (E1 face-rig demo): high-frequency normal perturbation driven
|
|
758
|
+
* by u_wrinkleStrength, which the engine resolves per frame from live morph weights
|
|
759
|
+
* (resolveWrinkleMapStrength). Stable in world space (no time input); strength 0 uploads
|
|
760
|
+
* 0 and the guarded call site below leaves the normal bit-identical.
|
|
761
|
+
*/
|
|
762
|
+
vec3 a3dWrinkleDetail(vec3 p) {
|
|
763
|
+
float f = sin(p.x * 230.0) * sin(p.y * 197.0 + 1.7) * sin(p.z * 211.0 + 0.6);
|
|
764
|
+
float g = sin(p.x * 97.0 + 0.4) * sin(p.y * 113.0 + 2.1) * sin(p.z * 103.0 + 1.2);
|
|
765
|
+
return vec3(f, g, f * g) * 0.35;
|
|
766
|
+
}
|
|
652
767
|
vec3 a3dSkinnedPbrNormal(vec3 baseNormal, vec4 tangentFrame, vec2 uv) {
|
|
653
768
|
vec3 sampled = texture(u_normalTexture, uv).xyz * 2.0 - 1.0;
|
|
654
769
|
vec3 n = normalize(baseNormal);
|
|
@@ -744,15 +859,68 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
744
859
|
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
745
860
|
return mix(1.0, 1.0 - occlusion, clamp(u_pointShadowStrength, 0.0, 1.0));
|
|
746
861
|
}
|
|
862
|
+
float a3dSpotShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
863
|
+
if (u_spotShadowMapEnabled < 0.5) return 1.0;
|
|
864
|
+
vec3 toFragment = worldPosition - u_spotShadowLightPosition;
|
|
865
|
+
float distanceToLight = max(length(toFragment), 0.0001);
|
|
866
|
+
if (distanceToLight > u_spotShadowRange) return 1.0;
|
|
867
|
+
vec3 coneAxis = u_spotShadowLightDirection / max(length(u_spotShadowLightDirection), 0.0001);
|
|
868
|
+
if (dot(toFragment / distanceToLight, coneAxis) < cos(u_spotShadowCone.x)) return 1.0;
|
|
869
|
+
vec4 lightPosition = u_spotShadowMatrix * vec4(worldPosition, 1.0);
|
|
870
|
+
vec3 projected = lightPosition.xyz / max(lightPosition.w, 0.0001);
|
|
871
|
+
vec2 uv = projected.xy * 0.5 + 0.5;
|
|
872
|
+
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 1.0;
|
|
873
|
+
vec3 receiverNormal = normalize(normal);
|
|
874
|
+
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
875
|
+
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
876
|
+
// Shared bias-table policy: the same per-sample, tangent-scaled slope bias as the
|
|
877
|
+
// directional and point-cube paths. A centre-only bias under-compensates outer PCF
|
|
878
|
+
// taps on sloped receivers, so each tap scales by its own texel distance.
|
|
879
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
880
|
+
float slopeTexelBias = slopeTangent * u_spotShadowSlopeBias * max(u_spotShadowTexelSize.x, u_spotShadowTexelSize.y);
|
|
881
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
882
|
+
float shadowed = 0.0;
|
|
883
|
+
float totalWeight = 0.0;
|
|
884
|
+
int sampleCount = clamp(int(u_spotShadowPcfSampleCount), 1, 32);
|
|
885
|
+
for (int i = 0; i < 32; ++i) {
|
|
886
|
+
if (i >= sampleCount) break;
|
|
887
|
+
vec4 sampleData = u_spotShadowPcfSamples[i];
|
|
888
|
+
float weight = max(sampleData.z, 0.0);
|
|
889
|
+
vec2 offset = sampleData.xy * u_spotShadowTexelSize;
|
|
890
|
+
float storedDepth = texture(u_spotShadowMapTexture, uv + offset).r;
|
|
891
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
892
|
+
float receiverDepth = projectedDepth - u_spotShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
893
|
+
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
894
|
+
totalWeight += weight;
|
|
895
|
+
}
|
|
896
|
+
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
897
|
+
return mix(1.0, 1.0 - occlusion, clamp(u_spotShadowStrength, 0.0, 1.0));
|
|
898
|
+
}
|
|
899
|
+
float a3dResolveSpotShadowOverride(float baseFactor, float kind, float shadowFlag, vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
900
|
+
// Spot-kind lights (kind == 2) sample the perspective spot map only when it is
|
|
901
|
+
// bound. Every gate term is 0 when no spot map is present, so mix() returns
|
|
902
|
+
// baseFactor exactly and scenes without spot lights render unchanged.
|
|
903
|
+
float spotGate = step(1.5, kind) * (1.0 - step(2.5, kind)) * step(0.5, u_spotShadowMapEnabled) * step(0.5, shadowFlag);
|
|
904
|
+
return mix(baseFactor, a3dSpotShadowFactor(worldPosition, normal, lightDirection), spotGate);
|
|
905
|
+
}
|
|
906
|
+
vec3 a3dLinearToSrgb(vec3 linear) {
|
|
907
|
+
vec3 clamped = max(linear, vec3(0.0));
|
|
908
|
+
vec3 low = clamped * 12.92;
|
|
909
|
+
vec3 high = 1.055 * pow(clamped, vec3(1.0 / 2.4)) - 0.055;
|
|
910
|
+
return mix(low, high, step(vec3(0.0031308), clamped));
|
|
911
|
+
}
|
|
747
912
|
vec3 a3dPbrEncodeOutput(vec3 linearColor) {
|
|
748
913
|
vec3 color = max(linearColor, vec3(0.0));
|
|
749
914
|
vec3 filmic = clamp((color * (2.51 * color + 0.03)) / (color * (2.43 * color + 0.59) + 0.14), vec3(0.0), vec3(1.0));
|
|
750
|
-
vec3 srgb =
|
|
915
|
+
vec3 srgb = a3dLinearToSrgb(filmic);
|
|
751
916
|
return mix(color, srgb, step(0.5, u_outputColorSpace));
|
|
752
917
|
}
|
|
753
918
|
void main() {
|
|
754
919
|
vec3 normal = normalize(v_normal);
|
|
755
920
|
normal = mix(normal, a3dSkinnedPbrNormal(v_normal, v_tangent, v_uv), step(0.5, u_normalTextureEnabled));
|
|
921
|
+
if (u_wrinkleStrength > 0.0) {
|
|
922
|
+
normal = normalize(normal + u_wrinkleStrength * a3dWrinkleDetail(v_worldPosition));
|
|
923
|
+
}
|
|
756
924
|
if (!gl_FrontFacing) normal = -normal;
|
|
757
925
|
vec3 viewDirection = normalize(u_cameraPosition - v_worldPosition);
|
|
758
926
|
vec4 sampledBaseColor = texture(u_baseColorTexture, v_uv);
|
|
@@ -822,11 +990,11 @@ void main() {
|
|
|
822
990
|
float nDotV = clamp(dot(normal, viewDirection), 0.0, 1.0);
|
|
823
991
|
vec2 brdfLut = texture(u_environmentBrdfLutTexture, vec2(nDotV, clampedRoughness)).rg;
|
|
824
992
|
sampledSpecular = a3dPbrClampSampledSpecularEdgeEnergy(sampledSpecular, nDotV, clampedRoughness);
|
|
825
|
-
sampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(1.1, 0.65, roughness);
|
|
993
|
+
sampledSpecular *= u_environmentMapTextureSpecularIntensity * u_materialEnvironmentIntensity * sampledEnvironmentWeight * mix(1.1, 0.65, roughness);
|
|
826
994
|
vec3 shaded = a3dPbrEnvironmentLightSplitSum(
|
|
827
995
|
normal,
|
|
828
996
|
viewDirection,
|
|
829
|
-
mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight),
|
|
997
|
+
mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity * u_materialEnvironmentIntensity, sampledEnvironmentWeight),
|
|
830
998
|
proceduralSpecular + sampledSpecular,
|
|
831
999
|
mix(vec2(1.0, 0.0), brdfLut, step(0.0001, u_environmentBrdfLutEnabled)),
|
|
832
1000
|
materialBase,
|
|
@@ -881,7 +1049,7 @@ void main() {
|
|
|
881
1049
|
viewDirection,
|
|
882
1050
|
lightDirection,
|
|
883
1051
|
colorIntensity.rgb,
|
|
884
|
-
colorIntensity.a * attenuation * mix(1.0, kind > 0.5 && kind < 1.5 ? a3dPointShadowFactor(v_worldPosition, normal, lightDirection) : a3dForwardShadowFactor(v_worldPosition, normal, lightDirection), step(0.5, spotShadowLayer.z)),
|
|
1052
|
+
colorIntensity.a * attenuation * a3dResolveSpotShadowOverride(mix(1.0, kind > 0.5 && kind < 1.5 ? a3dPointShadowFactor(v_worldPosition, normal, lightDirection) : a3dForwardShadowFactor(v_worldPosition, normal, lightDirection), step(0.5, spotShadowLayer.z)), kind, spotShadowLayer.z, v_worldPosition, normal, lightDirection),
|
|
885
1053
|
materialBase,
|
|
886
1054
|
metallic,
|
|
887
1055
|
roughness,
|
|
@@ -987,6 +1155,7 @@ uniform float u_baseColorTextureEnabled;
|
|
|
987
1155
|
uniform sampler2D u_normalTexture;
|
|
988
1156
|
uniform float u_normalTextureEnabled;
|
|
989
1157
|
uniform float u_normalScale;
|
|
1158
|
+
uniform float u_wrinkleStrength;
|
|
990
1159
|
uniform sampler2D u_metallicRoughnessTexture;
|
|
991
1160
|
uniform float u_metallicRoughnessTextureEnabled;
|
|
992
1161
|
uniform sampler2D u_occlusionTexture;
|
|
@@ -999,6 +1168,7 @@ uniform float u_metallic;
|
|
|
999
1168
|
uniform float u_roughness;
|
|
1000
1169
|
uniform vec3 u_environmentColor;
|
|
1001
1170
|
uniform float u_environmentIntensity;
|
|
1171
|
+
uniform float u_materialEnvironmentIntensity;
|
|
1002
1172
|
uniform vec3 u_environmentSkyColor;
|
|
1003
1173
|
uniform vec3 u_environmentHorizonColor;
|
|
1004
1174
|
uniform vec3 u_environmentGroundColor;
|
|
@@ -1072,6 +1242,19 @@ uniform float u_pointShadowSlopeBias;
|
|
|
1072
1242
|
uniform vec2 u_pointShadowTexelSize;
|
|
1073
1243
|
uniform float u_pointShadowPcfSampleCount;
|
|
1074
1244
|
uniform vec4 u_pointShadowPcfSamples[32];
|
|
1245
|
+
uniform sampler2D u_spotShadowMapTexture;
|
|
1246
|
+
uniform float u_spotShadowMapEnabled;
|
|
1247
|
+
uniform vec3 u_spotShadowLightPosition;
|
|
1248
|
+
uniform vec3 u_spotShadowLightDirection;
|
|
1249
|
+
uniform mat4 u_spotShadowMatrix;
|
|
1250
|
+
uniform vec2 u_spotShadowCone;
|
|
1251
|
+
uniform float u_spotShadowRange;
|
|
1252
|
+
uniform float u_spotShadowStrength;
|
|
1253
|
+
uniform float u_spotShadowBias;
|
|
1254
|
+
uniform float u_spotShadowSlopeBias;
|
|
1255
|
+
uniform vec2 u_spotShadowTexelSize;
|
|
1256
|
+
uniform float u_spotShadowPcfSampleCount;
|
|
1257
|
+
uniform vec4 u_spotShadowPcfSamples[32];
|
|
1075
1258
|
uniform float u_outputColorSpace;
|
|
1076
1259
|
uniform vec3 u_cameraPosition;
|
|
1077
1260
|
uniform float u_environmentFogEnabled;
|
|
@@ -1081,6 +1264,9 @@ uniform float u_environmentFogNear;
|
|
|
1081
1264
|
uniform float u_environmentFogFar;
|
|
1082
1265
|
uniform float u_environmentFogDensity;
|
|
1083
1266
|
uniform float u_environmentFogHeightFalloff;
|
|
1267
|
+
uniform float u_volumetricIntensity;
|
|
1268
|
+
uniform vec3 u_volumetricLightDirection;
|
|
1269
|
+
uniform vec3 u_volumetricLightColor;
|
|
1084
1270
|
uniform float u_environmentFogHeightReference;
|
|
1085
1271
|
uniform float u_environmentFogMaxOpacity;
|
|
1086
1272
|
in vec3 v_normal;
|
|
@@ -1128,6 +1314,17 @@ vec4 a3dPbrEnvironmentSampleRaw(vec3 direction, float lod) {
|
|
|
1128
1314
|
vec4 cubeSample = textureLod(u_environmentCubeMapTexture, a3dEnvironmentCubeDirection(direction, u_environmentMapTextureRotation), lod);
|
|
1129
1315
|
return mix(equirectSample, cubeSample, step(0.5, u_environmentCubeMapTextureEnabled));
|
|
1130
1316
|
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Procedural wrinkle detail (E1 face-rig demo): high-frequency normal perturbation driven
|
|
1319
|
+
* by u_wrinkleStrength, which the engine resolves per frame from live morph weights
|
|
1320
|
+
* (resolveWrinkleMapStrength). Stable in world space (no time input); strength 0 uploads
|
|
1321
|
+
* 0 and the guarded call site below leaves the normal bit-identical.
|
|
1322
|
+
*/
|
|
1323
|
+
vec3 a3dWrinkleDetail(vec3 p) {
|
|
1324
|
+
float f = sin(p.x * 230.0) * sin(p.y * 197.0 + 1.7) * sin(p.z * 211.0 + 0.6);
|
|
1325
|
+
float g = sin(p.x * 97.0 + 0.4) * sin(p.y * 113.0 + 2.1) * sin(p.z * 103.0 + 1.2);
|
|
1326
|
+
return vec3(f, g, f * g) * 0.35;
|
|
1327
|
+
}
|
|
1131
1328
|
vec3 a3dSkinnedPbrNormal(vec3 baseNormal, vec4 tangentFrame, vec2 uv) {
|
|
1132
1329
|
vec3 sampled = texture(u_normalTexture, uv).xyz * 2.0 - 1.0;
|
|
1133
1330
|
vec3 n = normalize(baseNormal);
|
|
@@ -1223,15 +1420,68 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
1223
1420
|
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
1224
1421
|
return mix(1.0, 1.0 - occlusion, clamp(u_pointShadowStrength, 0.0, 1.0));
|
|
1225
1422
|
}
|
|
1423
|
+
float a3dSpotShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
1424
|
+
if (u_spotShadowMapEnabled < 0.5) return 1.0;
|
|
1425
|
+
vec3 toFragment = worldPosition - u_spotShadowLightPosition;
|
|
1426
|
+
float distanceToLight = max(length(toFragment), 0.0001);
|
|
1427
|
+
if (distanceToLight > u_spotShadowRange) return 1.0;
|
|
1428
|
+
vec3 coneAxis = u_spotShadowLightDirection / max(length(u_spotShadowLightDirection), 0.0001);
|
|
1429
|
+
if (dot(toFragment / distanceToLight, coneAxis) < cos(u_spotShadowCone.x)) return 1.0;
|
|
1430
|
+
vec4 lightPosition = u_spotShadowMatrix * vec4(worldPosition, 1.0);
|
|
1431
|
+
vec3 projected = lightPosition.xyz / max(lightPosition.w, 0.0001);
|
|
1432
|
+
vec2 uv = projected.xy * 0.5 + 0.5;
|
|
1433
|
+
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 1.0;
|
|
1434
|
+
vec3 receiverNormal = normalize(normal);
|
|
1435
|
+
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
1436
|
+
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
1437
|
+
// Shared bias-table policy: the same per-sample, tangent-scaled slope bias as the
|
|
1438
|
+
// directional and point-cube paths. A centre-only bias under-compensates outer PCF
|
|
1439
|
+
// taps on sloped receivers, so each tap scales by its own texel distance.
|
|
1440
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
1441
|
+
float slopeTexelBias = slopeTangent * u_spotShadowSlopeBias * max(u_spotShadowTexelSize.x, u_spotShadowTexelSize.y);
|
|
1442
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
1443
|
+
float shadowed = 0.0;
|
|
1444
|
+
float totalWeight = 0.0;
|
|
1445
|
+
int sampleCount = clamp(int(u_spotShadowPcfSampleCount), 1, 32);
|
|
1446
|
+
for (int i = 0; i < 32; ++i) {
|
|
1447
|
+
if (i >= sampleCount) break;
|
|
1448
|
+
vec4 sampleData = u_spotShadowPcfSamples[i];
|
|
1449
|
+
float weight = max(sampleData.z, 0.0);
|
|
1450
|
+
vec2 offset = sampleData.xy * u_spotShadowTexelSize;
|
|
1451
|
+
float storedDepth = texture(u_spotShadowMapTexture, uv + offset).r;
|
|
1452
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
1453
|
+
float receiverDepth = projectedDepth - u_spotShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
1454
|
+
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
1455
|
+
totalWeight += weight;
|
|
1456
|
+
}
|
|
1457
|
+
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
1458
|
+
return mix(1.0, 1.0 - occlusion, clamp(u_spotShadowStrength, 0.0, 1.0));
|
|
1459
|
+
}
|
|
1460
|
+
float a3dResolveSpotShadowOverride(float baseFactor, float kind, float shadowFlag, vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
1461
|
+
// Spot-kind lights (kind == 2) sample the perspective spot map only when it is
|
|
1462
|
+
// bound. Every gate term is 0 when no spot map is present, so mix() returns
|
|
1463
|
+
// baseFactor exactly and scenes without spot lights render unchanged.
|
|
1464
|
+
float spotGate = step(1.5, kind) * (1.0 - step(2.5, kind)) * step(0.5, u_spotShadowMapEnabled) * step(0.5, shadowFlag);
|
|
1465
|
+
return mix(baseFactor, a3dSpotShadowFactor(worldPosition, normal, lightDirection), spotGate);
|
|
1466
|
+
}
|
|
1467
|
+
vec3 a3dLinearToSrgb(vec3 linear) {
|
|
1468
|
+
vec3 clamped = max(linear, vec3(0.0));
|
|
1469
|
+
vec3 low = clamped * 12.92;
|
|
1470
|
+
vec3 high = 1.055 * pow(clamped, vec3(1.0 / 2.4)) - 0.055;
|
|
1471
|
+
return mix(low, high, step(vec3(0.0031308), clamped));
|
|
1472
|
+
}
|
|
1226
1473
|
vec3 a3dPbrEncodeOutput(vec3 linearColor) {
|
|
1227
1474
|
vec3 color = max(linearColor, vec3(0.0));
|
|
1228
1475
|
vec3 filmic = clamp((color * (2.51 * color + 0.03)) / (color * (2.43 * color + 0.59) + 0.14), vec3(0.0), vec3(1.0));
|
|
1229
|
-
vec3 srgb =
|
|
1476
|
+
vec3 srgb = a3dLinearToSrgb(filmic);
|
|
1230
1477
|
return mix(color, srgb, step(0.5, u_outputColorSpace));
|
|
1231
1478
|
}
|
|
1232
1479
|
void main() {
|
|
1233
1480
|
vec3 normal = normalize(v_normal);
|
|
1234
1481
|
normal = mix(normal, a3dSkinnedPbrNormal(v_normal, v_tangent, v_uv), step(0.5, u_normalTextureEnabled));
|
|
1482
|
+
if (u_wrinkleStrength > 0.0) {
|
|
1483
|
+
normal = normalize(normal + u_wrinkleStrength * a3dWrinkleDetail(v_worldPosition));
|
|
1484
|
+
}
|
|
1235
1485
|
if (!gl_FrontFacing) normal = -normal;
|
|
1236
1486
|
vec3 viewDirection = normalize(u_cameraPosition - v_worldPosition);
|
|
1237
1487
|
vec4 sampledBaseColor = texture(u_baseColorTexture, v_uv);
|
|
@@ -1301,11 +1551,11 @@ void main() {
|
|
|
1301
1551
|
float nDotV = clamp(dot(normal, viewDirection), 0.0, 1.0);
|
|
1302
1552
|
vec2 brdfLut = texture(u_environmentBrdfLutTexture, vec2(nDotV, clampedRoughness)).rg;
|
|
1303
1553
|
sampledSpecular = a3dPbrClampSampledSpecularEdgeEnergy(sampledSpecular, nDotV, clampedRoughness);
|
|
1304
|
-
sampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(1.1, 0.65, roughness);
|
|
1554
|
+
sampledSpecular *= u_environmentMapTextureSpecularIntensity * u_materialEnvironmentIntensity * sampledEnvironmentWeight * mix(1.1, 0.65, roughness);
|
|
1305
1555
|
vec3 shaded = a3dPbrEnvironmentLightSplitSum(
|
|
1306
1556
|
normal,
|
|
1307
1557
|
viewDirection,
|
|
1308
|
-
mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight),
|
|
1558
|
+
mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity * u_materialEnvironmentIntensity, sampledEnvironmentWeight),
|
|
1309
1559
|
proceduralSpecular + sampledSpecular,
|
|
1310
1560
|
mix(vec2(1.0, 0.0), brdfLut, step(0.0001, u_environmentBrdfLutEnabled)),
|
|
1311
1561
|
materialBase,
|
|
@@ -1360,7 +1610,7 @@ void main() {
|
|
|
1360
1610
|
viewDirection,
|
|
1361
1611
|
lightDirection,
|
|
1362
1612
|
colorIntensity.rgb,
|
|
1363
|
-
colorIntensity.a * attenuation * mix(1.0, kind > 0.5 && kind < 1.5 ? a3dPointShadowFactor(v_worldPosition, normal, lightDirection) : a3dForwardShadowFactor(v_worldPosition, normal, lightDirection), step(0.5, spotShadowLayer.z)),
|
|
1613
|
+
colorIntensity.a * attenuation * a3dResolveSpotShadowOverride(mix(1.0, kind > 0.5 && kind < 1.5 ? a3dPointShadowFactor(v_worldPosition, normal, lightDirection) : a3dForwardShadowFactor(v_worldPosition, normal, lightDirection), step(0.5, spotShadowLayer.z)), kind, spotShadowLayer.z, v_worldPosition, normal, lightDirection),
|
|
1364
1614
|
materialBase,
|
|
1365
1615
|
metallic,
|
|
1366
1616
|
roughness,
|
|
@@ -1443,21 +1693,45 @@ layout(location = 2) in vec2 a_uv;
|
|
|
1443
1693
|
layout(location = 3) in vec4 a_tangent;
|
|
1444
1694
|
layout(location = 4) in vec4 a_color;
|
|
1445
1695
|
layout(location = 7) in vec2 a_uv1;
|
|
1696
|
+
layout(location = 8) in vec4 a_instanceMatrix0;
|
|
1697
|
+
layout(location = 9) in vec4 a_instanceMatrix1;
|
|
1698
|
+
layout(location = 10) in vec4 a_instanceMatrix2;
|
|
1699
|
+
layout(location = 11) in vec4 a_instanceMatrix3;
|
|
1700
|
+
layout(location = 12) in vec4 a_instanceColor;
|
|
1446
1701
|
uniform mat4 u_modelViewProjection;
|
|
1447
1702
|
uniform mat4 u_modelMatrix;
|
|
1448
1703
|
uniform mat4 u_normalMatrix;
|
|
1704
|
+
uniform mat4 u_instanceMatrices[64];
|
|
1705
|
+
uniform float u_instanceCount;
|
|
1706
|
+
uniform float u_instanceAttributeMode;
|
|
1449
1707
|
out vec3 v_normal;
|
|
1450
1708
|
out vec4 v_tangent;
|
|
1451
1709
|
out vec3 v_worldPosition;
|
|
1452
1710
|
out vec2 v_uv;
|
|
1453
1711
|
out vec4 v_vertexColor;
|
|
1454
1712
|
void main() {
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1713
|
+
// P2 instanced-GLB path (muse3jsparity-PRD): the u_instanceCount branch is
|
|
1714
|
+
// taken only for items carrying instanceTransforms; every other draw keeps
|
|
1715
|
+
// the legacy math bit-exact. Mirrors the instanced-PBR vertex convention.
|
|
1716
|
+
if (u_instanceCount > 0.5) {
|
|
1717
|
+
int instanceIndex = clamp(gl_InstanceID, 0, max(int(u_instanceCount) - 1, 0));
|
|
1718
|
+
mat4 attributeMatrix = mat4(a_instanceMatrix0, a_instanceMatrix1, a_instanceMatrix2, a_instanceMatrix3);
|
|
1719
|
+
mat4 instanceMatrix = u_instanceAttributeMode > 0.5 ? attributeMatrix : u_instanceMatrices[instanceIndex];
|
|
1720
|
+
vec4 worldPosition = u_modelMatrix * instanceMatrix * vec4(a_position, 1.0);
|
|
1721
|
+
v_normal = mat3(u_normalMatrix) * transpose(inverse(mat3(instanceMatrix))) * a_normal;
|
|
1722
|
+
v_tangent = vec4(mat3(u_normalMatrix) * (mat3(instanceMatrix) * a_tangent.xyz), a_tangent.w);
|
|
1723
|
+
v_worldPosition = worldPosition.xyz;
|
|
1724
|
+
v_uv = a_uv;
|
|
1725
|
+
v_vertexColor = a_color * a_instanceColor;
|
|
1726
|
+
gl_Position = u_modelViewProjection * instanceMatrix * vec4(a_position, 1.0);
|
|
1727
|
+
} else {
|
|
1728
|
+
v_normal = mat3(u_normalMatrix) * a_normal;
|
|
1729
|
+
v_tangent = vec4(mat3(u_normalMatrix) * a_tangent.xyz, a_tangent.w);
|
|
1730
|
+
v_worldPosition = (u_modelMatrix * vec4(a_position, 1.0)).xyz;
|
|
1731
|
+
v_uv = a_uv;
|
|
1732
|
+
v_vertexColor = a_color;
|
|
1733
|
+
gl_Position = u_modelViewProjection * vec4(a_position, 1.0);
|
|
1734
|
+
}
|
|
1461
1735
|
}
|
|
1462
1736
|
`,
|
|
1463
1737
|
fragment: `#version 300 es
|
|
@@ -1471,6 +1745,7 @@ uniform float u_metallic;
|
|
|
1471
1745
|
uniform float u_roughness;
|
|
1472
1746
|
uniform vec3 u_environmentColor;
|
|
1473
1747
|
uniform float u_environmentIntensity;
|
|
1748
|
+
uniform float u_materialEnvironmentIntensity;
|
|
1474
1749
|
uniform vec3 u_environmentSkyColor;
|
|
1475
1750
|
uniform vec3 u_environmentHorizonColor;
|
|
1476
1751
|
uniform vec3 u_environmentGroundColor;
|
|
@@ -1539,6 +1814,19 @@ uniform float u_pointShadowSlopeBias;
|
|
|
1539
1814
|
uniform vec2 u_pointShadowTexelSize;
|
|
1540
1815
|
uniform float u_pointShadowPcfSampleCount;
|
|
1541
1816
|
uniform vec4 u_pointShadowPcfSamples[32];
|
|
1817
|
+
uniform sampler2D u_spotShadowMapTexture;
|
|
1818
|
+
uniform float u_spotShadowMapEnabled;
|
|
1819
|
+
uniform vec3 u_spotShadowLightPosition;
|
|
1820
|
+
uniform vec3 u_spotShadowLightDirection;
|
|
1821
|
+
uniform mat4 u_spotShadowMatrix;
|
|
1822
|
+
uniform vec2 u_spotShadowCone;
|
|
1823
|
+
uniform float u_spotShadowRange;
|
|
1824
|
+
uniform float u_spotShadowStrength;
|
|
1825
|
+
uniform float u_spotShadowBias;
|
|
1826
|
+
uniform float u_spotShadowSlopeBias;
|
|
1827
|
+
uniform vec2 u_spotShadowTexelSize;
|
|
1828
|
+
uniform float u_spotShadowPcfSampleCount;
|
|
1829
|
+
uniform vec4 u_spotShadowPcfSamples[32];
|
|
1542
1830
|
uniform float u_outputColorSpace;
|
|
1543
1831
|
uniform vec3 u_cameraPosition;
|
|
1544
1832
|
uniform float u_environmentFogEnabled;
|
|
@@ -1548,6 +1836,9 @@ uniform float u_environmentFogNear;
|
|
|
1548
1836
|
uniform float u_environmentFogFar;
|
|
1549
1837
|
uniform float u_environmentFogDensity;
|
|
1550
1838
|
uniform float u_environmentFogHeightFalloff;
|
|
1839
|
+
uniform float u_volumetricIntensity;
|
|
1840
|
+
uniform vec3 u_volumetricLightDirection;
|
|
1841
|
+
uniform vec3 u_volumetricLightColor;
|
|
1551
1842
|
uniform float u_environmentFogHeightReference;
|
|
1552
1843
|
uniform float u_environmentFogMaxOpacity;
|
|
1553
1844
|
in vec3 v_normal;
|
|
@@ -1635,6 +1926,50 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
1635
1926
|
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
1636
1927
|
return mix(1.0, 1.0 - occlusion, clamp(u_pointShadowStrength, 0.0, 1.0));
|
|
1637
1928
|
}
|
|
1929
|
+
float a3dSpotShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
1930
|
+
if (u_spotShadowMapEnabled < 0.5) return 1.0;
|
|
1931
|
+
vec3 toFragment = worldPosition - u_spotShadowLightPosition;
|
|
1932
|
+
float distanceToLight = max(length(toFragment), 0.0001);
|
|
1933
|
+
if (distanceToLight > u_spotShadowRange) return 1.0;
|
|
1934
|
+
vec3 coneAxis = u_spotShadowLightDirection / max(length(u_spotShadowLightDirection), 0.0001);
|
|
1935
|
+
if (dot(toFragment / distanceToLight, coneAxis) < cos(u_spotShadowCone.x)) return 1.0;
|
|
1936
|
+
vec4 lightPosition = u_spotShadowMatrix * vec4(worldPosition, 1.0);
|
|
1937
|
+
vec3 projected = lightPosition.xyz / max(lightPosition.w, 0.0001);
|
|
1938
|
+
vec2 uv = projected.xy * 0.5 + 0.5;
|
|
1939
|
+
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 1.0;
|
|
1940
|
+
vec3 receiverNormal = normalize(normal);
|
|
1941
|
+
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
1942
|
+
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
1943
|
+
// Shared bias-table policy: the same per-sample, tangent-scaled slope bias as the
|
|
1944
|
+
// directional and point-cube paths. A centre-only bias under-compensates outer PCF
|
|
1945
|
+
// taps on sloped receivers, so each tap scales by its own texel distance.
|
|
1946
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
1947
|
+
float slopeTexelBias = slopeTangent * u_spotShadowSlopeBias * max(u_spotShadowTexelSize.x, u_spotShadowTexelSize.y);
|
|
1948
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
1949
|
+
float shadowed = 0.0;
|
|
1950
|
+
float totalWeight = 0.0;
|
|
1951
|
+
int sampleCount = clamp(int(u_spotShadowPcfSampleCount), 1, 32);
|
|
1952
|
+
for (int i = 0; i < 32; ++i) {
|
|
1953
|
+
if (i >= sampleCount) break;
|
|
1954
|
+
vec4 sampleData = u_spotShadowPcfSamples[i];
|
|
1955
|
+
float weight = max(sampleData.z, 0.0);
|
|
1956
|
+
vec2 offset = sampleData.xy * u_spotShadowTexelSize;
|
|
1957
|
+
float storedDepth = texture(u_spotShadowMapTexture, uv + offset).r;
|
|
1958
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
1959
|
+
float receiverDepth = projectedDepth - u_spotShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
1960
|
+
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
1961
|
+
totalWeight += weight;
|
|
1962
|
+
}
|
|
1963
|
+
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
1964
|
+
return mix(1.0, 1.0 - occlusion, clamp(u_spotShadowStrength, 0.0, 1.0));
|
|
1965
|
+
}
|
|
1966
|
+
float a3dResolveSpotShadowOverride(float baseFactor, float kind, float shadowFlag, vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
1967
|
+
// Spot-kind lights (kind == 2) sample the perspective spot map only when it is
|
|
1968
|
+
// bound. Every gate term is 0 when no spot map is present, so mix() returns
|
|
1969
|
+
// baseFactor exactly and scenes without spot lights render unchanged.
|
|
1970
|
+
float spotGate = step(1.5, kind) * (1.0 - step(2.5, kind)) * step(0.5, u_spotShadowMapEnabled) * step(0.5, shadowFlag);
|
|
1971
|
+
return mix(baseFactor, a3dSpotShadowFactor(worldPosition, normal, lightDirection), spotGate);
|
|
1972
|
+
}
|
|
1638
1973
|
vec2 a3dEnvironmentEquirectUv(vec3 direction, float rotation) {
|
|
1639
1974
|
vec3 d = normalize(direction);
|
|
1640
1975
|
float u = atan(d.z, d.x) / 6.28318530718 + 0.5 + rotation;
|
|
@@ -1689,7 +2024,7 @@ vec3 a3dPbrEnvironmentDiffuseInput(vec3 normal) {
|
|
|
1689
2024
|
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureIntensity);
|
|
1690
2025
|
float diffuseEnvironmentLod = max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
1691
2026
|
vec3 sampledDiffuse = a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(normal, diffuseEnvironmentLod));
|
|
1692
|
-
return mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight);
|
|
2027
|
+
return mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity * u_materialEnvironmentIntensity, sampledEnvironmentWeight);
|
|
1693
2028
|
}
|
|
1694
2029
|
vec3 a3dPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, float roughness) {
|
|
1695
2030
|
float proceduralEnvironmentWeight = step(0.0001, u_environmentMapIntensity);
|
|
@@ -1704,7 +2039,7 @@ vec3 a3dPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, float rough
|
|
|
1704
2039
|
vec3 sampledSpecular = a3dPbrBoundHdrSpecularRadiance(a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(reflectionDirection, environmentLod)));
|
|
1705
2040
|
float nDotV = clamp(dot(normal, viewDirection), 0.0, 1.0);
|
|
1706
2041
|
sampledSpecular = a3dPbrClampSampledSpecularEdgeEnergy(sampledSpecular, nDotV, clampedRoughness);
|
|
1707
|
-
sampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(0.84, 0.58, clampedRoughness);
|
|
2042
|
+
sampledSpecular *= u_environmentMapTextureSpecularIntensity * u_materialEnvironmentIntensity * sampledEnvironmentWeight * mix(0.84, 0.58, clampedRoughness);
|
|
1708
2043
|
return proceduralSpecular + sampledSpecular;
|
|
1709
2044
|
}
|
|
1710
2045
|
vec2 a3dPbrEnvironmentBrdfInput(vec3 normal, vec3 viewDirection, float roughness) {
|
|
@@ -1712,10 +2047,16 @@ vec2 a3dPbrEnvironmentBrdfInput(vec3 normal, vec3 viewDirection, float roughness
|
|
|
1712
2047
|
vec2 lut = texture(u_environmentBrdfLutTexture, vec2(nDotV, clamp(roughness, 0.0, 1.0))).rg;
|
|
1713
2048
|
return mix(vec2(1.0, 0.0), lut, step(0.0001, u_environmentBrdfLutEnabled));
|
|
1714
2049
|
}
|
|
2050
|
+
vec3 a3dLinearToSrgb(vec3 linear) {
|
|
2051
|
+
vec3 clamped = max(linear, vec3(0.0));
|
|
2052
|
+
vec3 low = clamped * 12.92;
|
|
2053
|
+
vec3 high = 1.055 * pow(clamped, vec3(1.0 / 2.4)) - 0.055;
|
|
2054
|
+
return mix(low, high, step(vec3(0.0031308), clamped));
|
|
2055
|
+
}
|
|
1715
2056
|
vec3 a3dPbrEncodeOutput(vec3 linearColor) {
|
|
1716
2057
|
vec3 color = max(linearColor, vec3(0.0));
|
|
1717
2058
|
vec3 filmic = clamp((color * (2.51 * color + 0.03)) / (color * (2.43 * color + 0.59) + 0.14), vec3(0.0), vec3(1.0));
|
|
1718
|
-
vec3 srgb =
|
|
2059
|
+
vec3 srgb = a3dLinearToSrgb(filmic);
|
|
1719
2060
|
return mix(color, srgb, step(0.5, u_outputColorSpace));
|
|
1720
2061
|
}
|
|
1721
2062
|
void main() {
|
|
@@ -1776,7 +2117,7 @@ void main() {
|
|
|
1776
2117
|
float inner = cos(spotShadowLayer.x * max(1.0 - spotShadowLayer.y, 0.001));
|
|
1777
2118
|
attenuation *= smoothstep(outer, inner, cone);
|
|
1778
2119
|
}
|
|
1779
|
-
float shadowFactor = mix(1.0, kind > 0.5 && kind < 1.5 ? a3dPointShadowFactor(v_worldPosition, mappedNormal, lightDirection) : a3dForwardShadowFactor(v_worldPosition, mappedNormal, lightDirection), step(0.5, spotShadowLayer.z));
|
|
2120
|
+
float shadowFactor = a3dResolveSpotShadowOverride(mix(1.0, kind > 0.5 && kind < 1.5 ? a3dPointShadowFactor(v_worldPosition, mappedNormal, lightDirection) : a3dForwardShadowFactor(v_worldPosition, mappedNormal, lightDirection), step(0.5, spotShadowLayer.z)), kind, spotShadowLayer.z, v_worldPosition, mappedNormal, lightDirection);
|
|
1780
2121
|
shaded += a3dPbrDirectLight(mappedNormal, viewDirection, lightDirection, colorIntensity.rgb, colorIntensity.a * attenuation * shadowFactor, materialBase, u_metallic, u_roughness, u_specularFactor, u_specularColorFactor);
|
|
1781
2122
|
}
|
|
1782
2123
|
float alpha = u_baseColor.a * v_vertexColor.a;
|
|
@@ -1794,9 +2135,9 @@ void main() {
|
|
|
1794
2135
|
{ name: DEFAULT_TEXTURED_PBR_TRANSMISSION_VOLUME_TEXTURES_VARIANT, defines: { A3D_PBR_TRANSMISSION_VOLUME_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
1795
2136
|
{ name: DEFAULT_TEXTURED_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES_VARIANT, defines: { A3D_PBR_SPECULAR_TEXTURES: true, A3D_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
1796
2137
|
{ name: DEFAULT_TEXTURED_PBR_IRIDESCENCE_TEXTURES_VARIANT, defines: { A3D_PBR_IRIDESCENCE_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
1797
|
-
{ name: DEFAULT_TEXTURED_PBR_CLEARCOAT_TRANSMISSION_VOLUME_TEXTURES_VARIANT, defines: { A3D_PBR_CLEARCOAT_TEXTURES: true, A3D_PBR_TRANSMISSION_VOLUME_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
2138
|
+
{ name: DEFAULT_TEXTURED_PBR_CLEARCOAT_TRANSMISSION_VOLUME_TEXTURES_VARIANT, defines: { A3D_PBR_CLEARCOAT_TEXTURES: true, A3D_PBR_TRANSMISSION_VOLUME_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true, A3D_PBR_NO_SPOT_SHADOW: true } },
|
|
1798
2139
|
{ name: DEFAULT_TEXTURED_PBR_CLEARCOAT_SPECULAR_TEXTURES_VARIANT, defines: { A3D_PBR_CLEARCOAT_TEXTURES: true, A3D_PBR_SPECULAR_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
1799
|
-
{ name: DEFAULT_TEXTURED_PBR_SPECULAR_SHEEN_ANISOTROPY_IRIDESCENCE_TEXTURES_VARIANT, defines: { A3D_PBR_SPECULAR_TEXTURES: true, A3D_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES: true, A3D_PBR_IRIDESCENCE_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } }
|
|
2140
|
+
{ name: DEFAULT_TEXTURED_PBR_SPECULAR_SHEEN_ANISOTROPY_IRIDESCENCE_TEXTURES_VARIANT, defines: { A3D_PBR_SPECULAR_TEXTURES: true, A3D_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES: true, A3D_PBR_IRIDESCENCE_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true, A3D_PBR_NO_SPOT_SHADOW: true } },
|
|
1800
2141
|
],
|
|
1801
2142
|
vertex: `#version 300 es
|
|
1802
2143
|
// ${DEFAULT_TEXTURED_PBR_SHADER_MARKER}
|
|
@@ -1807,9 +2148,17 @@ layout(location = 2) in vec2 a_uv;
|
|
|
1807
2148
|
layout(location = 3) in vec4 a_tangent;
|
|
1808
2149
|
layout(location = 4) in vec4 a_color;
|
|
1809
2150
|
layout(location = 7) in vec2 a_uv1;
|
|
2151
|
+
layout(location = 8) in vec4 a_instanceMatrix0;
|
|
2152
|
+
layout(location = 9) in vec4 a_instanceMatrix1;
|
|
2153
|
+
layout(location = 10) in vec4 a_instanceMatrix2;
|
|
2154
|
+
layout(location = 11) in vec4 a_instanceMatrix3;
|
|
2155
|
+
layout(location = 12) in vec4 a_instanceColor;
|
|
1810
2156
|
uniform mat4 u_modelViewProjection;
|
|
1811
2157
|
uniform mat4 u_modelMatrix;
|
|
1812
2158
|
uniform mat4 u_normalMatrix;
|
|
2159
|
+
uniform mat4 u_instanceMatrices[64];
|
|
2160
|
+
uniform float u_instanceCount;
|
|
2161
|
+
uniform float u_instanceAttributeMode;
|
|
1813
2162
|
out vec3 v_normal;
|
|
1814
2163
|
out vec4 v_tangent;
|
|
1815
2164
|
out vec3 v_worldPosition;
|
|
@@ -1819,11 +2168,27 @@ out vec4 v_vertexColor;
|
|
|
1819
2168
|
void main() {
|
|
1820
2169
|
v_uv = a_uv;
|
|
1821
2170
|
v_uv1 = a_uv1;
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
2171
|
+
// P2 instanced-GLB path (muse3jsparity-PRD): the u_instanceCount branch is
|
|
2172
|
+
// taken only for items carrying instanceTransforms (applyInstanceBinding
|
|
2173
|
+
// stamps a count >= 1); every other draw keeps the legacy math bit-exact.
|
|
2174
|
+
// Mirrors the instanced-PBR vertex convention (MVP carries the base model).
|
|
2175
|
+
if (u_instanceCount > 0.5) {
|
|
2176
|
+
int instanceIndex = clamp(gl_InstanceID, 0, max(int(u_instanceCount) - 1, 0));
|
|
2177
|
+
mat4 attributeMatrix = mat4(a_instanceMatrix0, a_instanceMatrix1, a_instanceMatrix2, a_instanceMatrix3);
|
|
2178
|
+
mat4 instanceMatrix = u_instanceAttributeMode > 0.5 ? attributeMatrix : u_instanceMatrices[instanceIndex];
|
|
2179
|
+
vec4 worldPosition = u_modelMatrix * instanceMatrix * vec4(a_position, 1.0);
|
|
2180
|
+
v_normal = mat3(u_normalMatrix) * transpose(inverse(mat3(instanceMatrix))) * a_normal;
|
|
2181
|
+
v_tangent = vec4(mat3(u_normalMatrix) * (mat3(instanceMatrix) * a_tangent.xyz), a_tangent.w);
|
|
2182
|
+
v_worldPosition = worldPosition.xyz;
|
|
2183
|
+
v_vertexColor = a_color * a_instanceColor;
|
|
2184
|
+
gl_Position = u_modelViewProjection * instanceMatrix * vec4(a_position, 1.0);
|
|
2185
|
+
} else {
|
|
2186
|
+
v_normal = mat3(u_normalMatrix) * a_normal;
|
|
2187
|
+
v_tangent = vec4(mat3(u_normalMatrix) * a_tangent.xyz, a_tangent.w);
|
|
2188
|
+
v_worldPosition = (u_modelMatrix * vec4(a_position, 1.0)).xyz;
|
|
2189
|
+
v_vertexColor = a_color;
|
|
2190
|
+
gl_Position = u_modelViewProjection * vec4(a_position, 1.0);
|
|
2191
|
+
}
|
|
1827
2192
|
}
|
|
1828
2193
|
`,
|
|
1829
2194
|
fragment: `#version 300 es
|
|
@@ -1837,6 +2202,7 @@ uniform float u_metallic;
|
|
|
1837
2202
|
uniform float u_roughness;
|
|
1838
2203
|
uniform vec3 u_environmentColor;
|
|
1839
2204
|
uniform float u_environmentIntensity;
|
|
2205
|
+
uniform float u_materialEnvironmentIntensity;
|
|
1840
2206
|
uniform vec3 u_environmentSkyColor;
|
|
1841
2207
|
uniform vec3 u_environmentHorizonColor;
|
|
1842
2208
|
uniform vec3 u_environmentGroundColor;
|
|
@@ -1921,6 +2287,26 @@ uniform float u_pointShadowSlopeBias;
|
|
|
1921
2287
|
uniform vec2 u_pointShadowTexelSize;
|
|
1922
2288
|
uniform float u_pointShadowPcfSampleCount;
|
|
1923
2289
|
uniform vec4 u_pointShadowPcfSamples[32];
|
|
2290
|
+
// B1 spot path (muse3jsparity-PRD): the two A3D_PBR_NO_SPOT_SHADOW variants
|
|
2291
|
+
// (clearcoat-transmission-volume, specular-sheen-anisotropy-iridescence) sit at
|
|
2292
|
+
// the 16-sampler WebGL2 minimum without it, so they sample spot lights through
|
|
2293
|
+
// the legacy directional factor while every other lit program takes the spot
|
|
2294
|
+
// override. ForwardPass binds spot uniforms only when reflection declares them.
|
|
2295
|
+
#ifndef A3D_PBR_NO_SPOT_SHADOW
|
|
2296
|
+
uniform sampler2D u_spotShadowMapTexture;
|
|
2297
|
+
uniform float u_spotShadowMapEnabled;
|
|
2298
|
+
uniform vec3 u_spotShadowLightPosition;
|
|
2299
|
+
uniform vec3 u_spotShadowLightDirection;
|
|
2300
|
+
uniform mat4 u_spotShadowMatrix;
|
|
2301
|
+
uniform vec2 u_spotShadowCone;
|
|
2302
|
+
uniform float u_spotShadowRange;
|
|
2303
|
+
uniform float u_spotShadowStrength;
|
|
2304
|
+
uniform float u_spotShadowBias;
|
|
2305
|
+
uniform float u_spotShadowSlopeBias;
|
|
2306
|
+
uniform vec2 u_spotShadowTexelSize;
|
|
2307
|
+
uniform float u_spotShadowPcfSampleCount;
|
|
2308
|
+
uniform vec4 u_spotShadowPcfSamples[32];
|
|
2309
|
+
#endif
|
|
1924
2310
|
uniform sampler2D u_baseColorTexture;
|
|
1925
2311
|
uniform float u_baseColorTextureEnabled;
|
|
1926
2312
|
uniform vec2 u_baseColorTextureOffset;
|
|
@@ -2076,6 +2462,9 @@ uniform float u_environmentFogNear;
|
|
|
2076
2462
|
uniform float u_environmentFogFar;
|
|
2077
2463
|
uniform float u_environmentFogDensity;
|
|
2078
2464
|
uniform float u_environmentFogHeightFalloff;
|
|
2465
|
+
uniform float u_volumetricIntensity;
|
|
2466
|
+
uniform vec3 u_volumetricLightDirection;
|
|
2467
|
+
uniform vec3 u_volumetricLightColor;
|
|
2079
2468
|
uniform float u_environmentFogHeightReference;
|
|
2080
2469
|
uniform float u_environmentFogMaxOpacity;
|
|
2081
2470
|
in vec3 v_normal;
|
|
@@ -2110,10 +2499,16 @@ vec2 a3dTexturedPbrWrapUv(vec2 uv, vec2 wrapMode) {
|
|
|
2110
2499
|
a3dTexturedPbrWrapCoordinate(uv.y, wrapMode.y)
|
|
2111
2500
|
);
|
|
2112
2501
|
}
|
|
2502
|
+
vec3 a3dTexturedPbrEncodeLinearToSrgb(vec3 linear) {
|
|
2503
|
+
vec3 clamped = max(linear, vec3(0.0));
|
|
2504
|
+
vec3 low = clamped * 12.92;
|
|
2505
|
+
vec3 high = 1.055 * pow(clamped, vec3(1.0 / 2.4)) - 0.055;
|
|
2506
|
+
return mix(low, high, step(vec3(0.0031308), clamped));
|
|
2507
|
+
}
|
|
2113
2508
|
vec3 a3dTexturedPbrEncodeOutput(vec3 linearColor) {
|
|
2114
2509
|
vec3 color = max(linearColor, vec3(0.0));
|
|
2115
2510
|
vec3 filmic = clamp((color * (2.51 * color + 0.03)) / (color * (2.43 * color + 0.59) + 0.14), vec3(0.0), vec3(1.0));
|
|
2116
|
-
vec3 srgb =
|
|
2511
|
+
vec3 srgb = a3dTexturedPbrEncodeLinearToSrgb(filmic);
|
|
2117
2512
|
return mix(color, srgb, step(0.5, u_outputColorSpace));
|
|
2118
2513
|
}
|
|
2119
2514
|
vec3 a3dTexturedPbrDecodeSrgb(vec3 encodedColor) {
|
|
@@ -2220,6 +2615,52 @@ float a3dTexturedPbrPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 ligh
|
|
|
2220
2615
|
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
2221
2616
|
return mix(1.0, 1.0 - occlusion, clamp(u_pointShadowStrength, 0.0, 1.0));
|
|
2222
2617
|
}
|
|
2618
|
+
#ifndef A3D_PBR_NO_SPOT_SHADOW
|
|
2619
|
+
float a3dTexturedPbrSpotShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
2620
|
+
if (u_spotShadowMapEnabled < 0.5) return 1.0;
|
|
2621
|
+
vec3 toFragment = worldPosition - u_spotShadowLightPosition;
|
|
2622
|
+
float distanceToLight = max(length(toFragment), 0.0001);
|
|
2623
|
+
if (distanceToLight > u_spotShadowRange) return 1.0;
|
|
2624
|
+
vec3 coneAxis = u_spotShadowLightDirection / max(length(u_spotShadowLightDirection), 0.0001);
|
|
2625
|
+
if (dot(toFragment / distanceToLight, coneAxis) < cos(u_spotShadowCone.x)) return 1.0;
|
|
2626
|
+
vec4 lightPosition = u_spotShadowMatrix * vec4(worldPosition, 1.0);
|
|
2627
|
+
vec3 projected = lightPosition.xyz / max(lightPosition.w, 0.0001);
|
|
2628
|
+
vec2 uv = projected.xy * 0.5 + 0.5;
|
|
2629
|
+
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 1.0;
|
|
2630
|
+
vec3 receiverNormal = normalize(normal);
|
|
2631
|
+
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
2632
|
+
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
2633
|
+
// Shared bias-table policy: the same per-sample, tangent-scaled slope bias as the
|
|
2634
|
+
// directional and point-cube paths. A centre-only bias under-compensates outer PCF
|
|
2635
|
+
// taps on sloped receivers, so each tap scales by its own texel distance.
|
|
2636
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
2637
|
+
float slopeTexelBias = slopeTangent * u_spotShadowSlopeBias * max(u_spotShadowTexelSize.x, u_spotShadowTexelSize.y);
|
|
2638
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
2639
|
+
float shadowed = 0.0;
|
|
2640
|
+
float totalWeight = 0.0;
|
|
2641
|
+
int sampleCount = clamp(int(u_spotShadowPcfSampleCount), 1, 32);
|
|
2642
|
+
for (int i = 0; i < 32; ++i) {
|
|
2643
|
+
if (i >= sampleCount) break;
|
|
2644
|
+
vec4 sampleData = u_spotShadowPcfSamples[i];
|
|
2645
|
+
float weight = max(sampleData.z, 0.0);
|
|
2646
|
+
vec2 offset = sampleData.xy * u_spotShadowTexelSize;
|
|
2647
|
+
float storedDepth = texture(u_spotShadowMapTexture, uv + offset).r;
|
|
2648
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
2649
|
+
float receiverDepth = projectedDepth - u_spotShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
2650
|
+
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
2651
|
+
totalWeight += weight;
|
|
2652
|
+
}
|
|
2653
|
+
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
2654
|
+
return mix(1.0, 1.0 - occlusion, clamp(u_spotShadowStrength, 0.0, 1.0));
|
|
2655
|
+
}
|
|
2656
|
+
float a3dTexturedPbrResolveSpotShadowOverride(float baseFactor, float kind, float shadowFlag, vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
2657
|
+
// Spot-kind lights (kind == 2) sample the perspective spot map only when it is
|
|
2658
|
+
// bound. Every gate term is 0 when no spot map is present, so mix() returns
|
|
2659
|
+
// baseFactor exactly and scenes without spot lights render unchanged.
|
|
2660
|
+
float spotGate = step(1.5, kind) * (1.0 - step(2.5, kind)) * step(0.5, u_spotShadowMapEnabled) * step(0.5, shadowFlag);
|
|
2661
|
+
return mix(baseFactor, a3dTexturedPbrSpotShadowFactor(worldPosition, normal, lightDirection), spotGate);
|
|
2662
|
+
}
|
|
2663
|
+
#endif
|
|
2223
2664
|
vec2 a3dTexturedPbrEnvironmentUv(vec3 direction, float rotation) {
|
|
2224
2665
|
vec3 d = normalize(direction);
|
|
2225
2666
|
float u = atan(d.z, d.x) / 6.28318530718 + 0.5 + rotation;
|
|
@@ -2268,7 +2709,7 @@ vec3 a3dTexturedPbrEnvironmentDiffuseInput(vec3 normal) {
|
|
|
2268
2709
|
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureIntensity);
|
|
2269
2710
|
float diffuseEnvironmentLod = max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
2270
2711
|
vec3 sampledDiffuse = a3dTexturedPbrDecodeEnvironmentSample(a3dTexturedPbrEnvironmentSampleRaw(normal, diffuseEnvironmentLod));
|
|
2271
|
-
return mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight);
|
|
2712
|
+
return mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity * u_materialEnvironmentIntensity, sampledEnvironmentWeight);
|
|
2272
2713
|
}
|
|
2273
2714
|
vec3 a3dTexturedPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, float roughness) {
|
|
2274
2715
|
float materialEnvironmentSpecularScale = clamp(u_materialEnvironmentSpecularScale, 0.0, 1.0);
|
|
@@ -2297,7 +2738,7 @@ vec3 a3dTexturedPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, flo
|
|
|
2297
2738
|
float environmentLod = clampedRoughness * max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
2298
2739
|
vec3 sampledSpecular = a3dTexturedPbrBoundHdrSpecularRadiance(a3dTexturedPbrDecodeEnvironmentSample(a3dTexturedPbrEnvironmentSampleRaw(reflectionDirection, environmentLod)));
|
|
2299
2740
|
sampledSpecular = a3dTexturedPbrClampSampledSpecularEdgeEnergy(sampledSpecular, nDotV, clampedRoughness);
|
|
2300
|
-
sampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(1.1, 0.65, clampedRoughness);
|
|
2741
|
+
sampledSpecular *= u_environmentMapTextureSpecularIntensity * u_materialEnvironmentIntensity * sampledEnvironmentWeight * mix(1.1, 0.65, clampedRoughness);
|
|
2301
2742
|
float proceduralSpecularScale = materialFiniteSpecularScale;
|
|
2302
2743
|
float sampledSpecularScale = materialEnvironmentSpecularScale;
|
|
2303
2744
|
return proceduralSpecular * proceduralSpecularScale + sampledSpecular * sampledSpecularScale;
|
|
@@ -2720,6 +3161,9 @@ void main() {
|
|
|
2720
3161
|
attenuation *= smoothstep(outer, inner, cone);
|
|
2721
3162
|
}
|
|
2722
3163
|
float shadowFactor = mix(1.0, kind > 0.5 && kind < 1.5 ? a3dTexturedPbrPointShadowFactor(v_worldPosition, mappedNormal, lightDirection) : a3dTexturedPbrShadowFactor(v_worldPosition, mappedNormal, lightDirection), step(0.5, spotShadowLayer.z));
|
|
3164
|
+
#ifndef A3D_PBR_NO_SPOT_SHADOW
|
|
3165
|
+
shadowFactor = a3dTexturedPbrResolveSpotShadowOverride(shadowFactor, kind, spotShadowLayer.z, v_worldPosition, mappedNormal, lightDirection);
|
|
3166
|
+
#endif
|
|
2723
3167
|
float directLightIntensity = colorIntensity.a
|
|
2724
3168
|
* attenuation
|
|
2725
3169
|
* shadowFactor
|