Initial commit: Minecraft 光追着色器包(从零实现的 path tracing)
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
// 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);
|
||||
}
|
||||
Reference in New Issue
Block a user