64 lines
2.0 KiB
GLSL
64 lines
2.0 KiB
GLSL
// 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);
|
|
}
|