playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
3 lines (2 loc) • 4.67 kB
TypeScript
declare const _default: "\n #include \"screenDepthPS\"\n\n varying vec2 uv0;\n\n uniform vec3 uFogCameraPos;\n uniform vec3 uFogCameraFwd;\n uniform mat4 uFogInvView;\n uniform vec2 uFogProjScale;\n uniform vec3 uFogTint;\n uniform vec3 uFogLightColor;\n uniform vec3 uFogLightDir; // world space direction towards the light\n uniform vec3 uFogAmbient;\n uniform vec4 uFogParams; // x: density, y: height base, z: height falloff, w: max distance\n uniform vec4 uFogScatterParams; // x: anisotropy, y: step count, z: temporal noise offset, w: shadow intensity\n\n #ifdef FOG_SHADOWS\n uniform mat4 uFogShadowMatrixPalette[4];\n uniform vec4 uFogShadowCascadeDistances;\n uniform vec4 uFogShadowParams; // x: cascade count, y: bias, z: unused, w: max shadow distance\n #ifdef FOG_SHADOW_PCF\n uniform sampler2DShadow uFogShadowMap;\n #else\n uniform sampler2D uFogShadowMap;\n #endif\n\n float sampleFogShadow(vec3 worldPos, float viewDepth) {\n\n // no shadow past the shadow distance\n if (viewDepth >= uFogShadowParams.w) return 1.0;\n\n // cascade index based on the view depth\n vec4 comparisons = step(uFogShadowCascadeDistances, vec4(viewDepth));\n int cascadeIndex = int(min(dot(comparisons, vec4(1.0)), uFogShadowParams.x - 1.0));\n\n vec3 shadowCoord = (uFogShadowMatrixPalette[cascadeIndex] * vec4(worldPos, 1.0)).xyz;\n float z = shadowCoord.z - uFogShadowParams.y;\n\n #ifdef FOG_SHADOW_PCF\n // hardware comparison on the depth format shadow map\n return textureShadow(uFogShadowMap, vec3(shadowCoord.xy, z));\n #else\n // manual comparison on the color format shadow map storing depth (PCSS / VSM)\n return step(z, texture2D(uFogShadowMap, shadowCoord.xy).r);\n #endif\n }\n #endif\n\n // interleaved gradient noise\n float fogNoise(vec2 fragCoord) {\n const vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189);\n return fract(magic.z * fract(dot(fragCoord, magic.xy)));\n }\n\n // normalized Henyey-Greenstein phase function\n float fogPhase(float cosTheta, float g) {\n float g2 = g * g;\n float denom = 1.0 + g2 - 2.0 * g * cosTheta;\n return (1.0 - g2) / (12.56637 * denom * sqrt(denom));\n }\n\n void main() {\n\n // world space ray for this pixel (perspective projection). Note that uv0 addresses\n // textures (getImageEffectUV flips it on WebGPU), so undo the flip to get NDC\n vec2 ndcUV = uv0;\n #ifdef WEBGPU\n ndcUV.y = 1.0 - ndcUV.y;\n #endif\n vec2 ndc = ndcUV * 2.0 - 1.0;\n vec3 rayDir = normalize((uFogInvView * vec4(ndc * uFogProjScale, -1.0, 0.0)).xyz);\n\n // distance along the ray to the scene surface\n float rayDot = max(dot(rayDir, uFogCameraFwd), 0.001);\n float rayLength = min(getLinearScreenDepth(uv0) / rayDot, uFogParams.w);\n\n float stepCount = uFogScatterParams.y;\n float dt = rayLength / stepCount;\n\n // per-pixel noise offsets the samples along the ray to hide banding, and cycles over\n // frames when TAA is used to temporally accumulate to a smooth result\n float noise = fract(fogNoise(gl_FragCoord.xy) + uFogScatterParams.z);\n\n // single phase function evaluation, as the light direction is constant along the ray\n vec3 sunLight = uFogLightColor * fogPhase(dot(rayDir, uFogLightDir), uFogScatterParams.x);\n\n vec3 inscatter = vec3(0.0);\n float transmittance = 1.0;\n\n for (float i = 0.0; i < stepCount; i += 1.0) {\n float t = (i + noise) * dt;\n vec3 pos = uFogCameraPos + rayDir * t;\n\n // exponential height fog density, constant below the base height\n float density = uFogParams.x * exp(-uFogParams.z * max(pos.y - uFogParams.y, 0.0));\n\n float shadow = 1.0;\n #ifdef FOG_SHADOWS\n shadow = mix(1.0, sampleFogShadow(pos, t * rayDot), uFogScatterParams.w);\n #endif\n\n // accumulate in-scattered light and update transmittance (Beer-Lambert)\n vec3 radiance = sunLight * shadow + uFogAmbient;\n inscatter += transmittance * uFogTint * radiance * (density * dt);\n transmittance *= exp(-density * dt);\n\n if (transmittance < 0.005) break;\n }\n\n gl_FragColor = vec4(inscatter, transmittance);\n }\n";
export default _default;