Files

114 lines
3.7 KiB
GLSL

// MinecraftPT — Soild_FS (Main Lighting Composite)
// Combines GBuffer data with path-traced diffuse + specular, direct sun,
// held light, emission, and ambient to produce the final HDR scene.
#include "/Lib/Settings.glsl"
#include "/Lib/Utilities.glsl"
#include "/Lib/BasicFunctions/LightingConstants.glsl"
#include "/Lib/GbufferData.glsl"
#include "/Lib/BasicFunctions/Blocklight.glsl"
#include "/Lib/BasicFunctions/HeldLight.glsl"
#include "/Lib/BasicFunctions/Sunlight_Shadow.glsl"
#include "/Lib/BasicFunctions/NetherColor.glsl"
#include "/Lib/PathTracing/Tracer/SampleIRC.glsl"
uniform sampler2D colortex7; // diffuse PT (denoised)
uniform sampler2D colortex11; // specular PT (denoised)
uniform sampler2D colortex8; // previous diffuse (for blending)
uniform sampler2D colortex12; // combined HDR (for historical blend)
layout(location = 0) out vec4 colorOut; // colortex12
void main(){
ivec2 texelCoord = ivec2(gl_FragCoord.xy);
// Skip sky — sky was written by composite20 (Sky_Overworld_FS) into colortex12
float depth = texelFetch(depthtex0, texelCoord, 0).r;
if (depth >= 1.0){
discard;
}
// Read GBuffer
GbufferData gbuffer = GetGbufferDataSoild(texelCoord);
MaterialMask mask = CalculateMasks(gbuffer.materialID);
vec3 worldNormal = gbuffer.worldNormal;
vec3 vertexNormal = gbuffer.vertexNormal;
vec3 albedo = gbuffer.albedo;
vec2 lightmap = gbuffer.lightmap;
// Reconstruct world position
vec4 viewPos = gbufferProjectionInverse * vec4(vec2(texelCoord) / screenSize * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
viewPos.xyz /= viewPos.w;
vec3 worldPos = gbufferModelViewInverse[3].xyz + viewPos.xyz;
// Path-traced diffuse (from half-res colortex6, sampled at full res)
vec2 halfCoord = vec2(texelCoord) * 0.5;
vec3 diffusePT = textureLod(colortex7, halfCoord / (screenSize * 0.5), 0.0).rgb;
// Path-traced specular
vec3 specularPT = textureLod(colortex11, halfCoord / (screenSize * 0.5), 0.0).rgb;
// Direct sunlight
vec3 sunLight = GetSunlight(viewPos.xyz, worldPos, vertexNormal, worldNormal, lightmap.x);
// Block light
vec3 blockLight = Blocklight(lightmap) * gbuffer.material.emissiveness;
// Emission from GBuffer
vec3 emission = vec3(0.0);
emission = texelFetch(colortex0, texelCoord, 0).a * 2.0;
// Held light
float heldShadow = 1.0;
vec3 heldLight = GetHeldLight(worldPos, worldNormal, heldShadow);
// IRC ambient
vec3 irc = SampleIRC(worldPos) * 0.3;
// Combine:
// diffuse = albedo * (sun + block + irc + held) + diffusePT
// specular = specularPT
// emission = emission
// HDR output
vec3 color = vec3(0.0);
// Diffuse
color += albedo * (sunLight + blockLight + irc) * (1.0 - gbuffer.material.metalness);
color += albedo * heldLight * heldShadow * gbuffer.material.roughness;
// Path-traced diffuse contribution (indirect GI)
color += diffusePT * albedo * 0.5;
// Specular
color += specularPT * gbuffer.material.reflectionStrength;
// Emission
color += emission;
// Fresnel-based specular from direct light
float NdotV = max(dot(worldNormal, normalize(-viewPos.xyz)), 0.0);
float F0 = gbuffer.material.metalness;
vec3 fresnel = FresnelSchlick(NdotV, vec3(F0));
// Direct specular (sun)
float NdotL = max(dot(worldNormal, GetSunDirWorld()), 0.0);
if (NdotL > 0.0){
float roughness = gbuffer.material.roughness;
vec3 halfVec = normalize(GetSunDirWorld() + normalize(-viewPos.xyz));
float NdotH = max(dot(worldNormal, halfVec), 0.0);
float D = GGX_D(NdotH, roughness);
float G = Smith_G(NdotV, NdotL, roughness);
vec3 specular = fresnel * D * G / (4.0 * NdotV * NdotL + 0.0001);
color += GetSunIrradiance() * specular * NdotL * 0.5;
}
// Apply parallax shadow
color *= gbuffer.parallaxShadow;
// Sky mask: if sky, output 0
if (mask.sky > 0.5) color = vec3(0.0);
colorOut = vec4(color, 1.0);
}