// MinecraftPT — SpecularTracing_FS // Specular reflection path tracing at half resolution. // Output: colortex9 = noisy specular, colortex11 = history (ping-pong) #include "/Lib/Settings.glsl" #include "/Lib/Utilities.glsl" #include "/Lib/BasicFunctions/LightingConstants.glsl" #include "/Lib/GbufferData.glsl" #include "/Lib/PathTracing/Tracer/TracingNoise.glsl" #include "/Lib/PathTracing/Tracer/TracingUtilities.glsl" #include "/Lib/PathTracing/Tracer/SpecularTracer.glsl" #include "/Lib/BasicFunctions/TemporalNoise.glsl" layout(location = 0) out vec4 specularOut; void main(){ ivec2 texelCoord = ivec2(gl_FragCoord.xy); ivec2 fullCoord = texelCoord * 2; float depth = texelFetch(depthtex0, fullCoord, 0).r; if (depth >= 1.0){ specularOut = vec4(0.0); return; } vec4 normalData = texelFetch(colortex1, fullCoord, 0); vec3 worldNormal = DecodeNormal(normalData.xy); vec4 materialData = texelFetch(colortex2, fullCoord, 0); float roughness = 1.0 - materialData.r; roughness = roughness * roughness; float metalness = materialData.g; // Skip rough non-metal surfaces when rough specular is disabled #if ENABLE_ROUGH_SPECULAR == 0 if (roughness > 0.5 && metalness < 0.04){ specularOut = vec4(0.0); return; } #endif // Reconstruct view position vec4 viewPos = gbufferProjectionInverse * vec4(vec2(fullCoord) / screenSize * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0); viewPos.xyz /= viewPos.w; vec3 worldPos = gbufferModelViewInverse[3].xyz + viewPos.xyz; vec3 viewDir = normalize(-viewPos.xyz); vec2 noise = GetTracingNoise2(vec2(texelCoord), frameCounter, 1); // Importance-sample GGX reflection direction vec3 reflDir = ImportanceSampleGGX(noise, worldNormal, roughness); // Or use pure reflection for smooth surfaces if (roughness < 0.05){ reflDir = reflect(-viewDir, worldNormal); } // Trace the specular ray vec3 result = SpecularTrace(WorldToVoxel(worldPos + worldNormal * 0.02), reflDir, PT_SPECULAR_TRACING_DISTANCE, noise); specularOut = vec4(result, 1.0); }