Initial commit: Minecraft 光追着色器包(从零实现的 path tracing)

This commit is contained in:
WpyQwq
2026-09-19 12:06:22 +08:00
commit 59e30822f8
314 changed files with 9259 additions and 0 deletions
@@ -0,0 +1,130 @@
#include "/Lib/Settings.glsl"
#include "/Lib/Utilities.glsl"
// MinecraftPT — Shadow Tracing
// Direct sunlight shadow rays: march from surface toward the sun through the
// voxel grid. Soft penumbra via distance-weighted ray length.
#ifndef SHADOW_TRACING_GLSL
#define SHADOW_TRACING_GLSL
#include "/Lib/PathTracing/Tracer/TracingUtilities.glsl"
float ShadowTracing(vec3 viewPos, vec3 worldPos, vec3 vertexNormal, vec3 lightVector, float lightMap){
float shadow = 1.0;
vec3 voxelPos = WorldToVoxel(worldPos);
voxelPos += vertexNormal * (-viewPos.z * 0.0003);
if (clamp(voxelPos, vec3(0.0), vec3(voxelResolution)) == voxelPos){
lightMap = saturate(1.0 - lightMap * 2.0);
vec2 shadowWeight = vec2(
4.0 - 2.0 * saturate(lightMap - viewPos.z * 0.01),
0.2 + 0.5 * saturate(lightMap - viewPos.z * 0.01)
);
Ray ray = PackRay(voxelPos, lightVector);
vec3 voxelCoord = floor(ray.ori);
vec3 totalStep = (ray.sdir * (voxelCoord - ray.ori + 0.5) + 0.5) * abs(ray.rdir);
float rayLength = 0.0;
vec3 tracingNext;
bool hit = false;
for (int i = 0; i < 64; i++){
if (clamp(voxelCoord, vec3(0.0), vec3(voxelResolution - 0.5)) != voxelCoord) break;
vec4 voxelData = texelFetch(voxelData3D, ivec3(voxelCoord), 0);
float voxelID = DecodeVoxelID(voxelData.z);
// Full block or cutout shape
if (voxelID >= 999.0){
hit = rayLength > 0.0;
}else if (voxelID < 1000.0 && voxelID > 1.0){
float rawID = 1000.0 - voxelID;
rayLength = minVec3(totalStep);
hit = HitShape_Lite(ray, voxelCoord, rawID, rayLength);
}
if (hit){
shadow = saturate((rayLength - shadowWeight.y) * shadowWeight.x);
break;
}
// Sparse skip
float marker = voxelData.z;
if (marker > 0.60 && marker < 0.92){
float skipSize = marker > 0.90 ? 8.0 : (marker > 0.70 ? 4.0 : 2.0);
vec3 nextBoundary = floor((voxelCoord + 1.0) / skipSize) * skipSize;
vec3 distToBoundary = (nextBoundary - voxelCoord) * abs(ray.rdir);
float tSkip = minVec3(distToBoundary) + 1e-4;
rayLength += tSkip;
vec3 stepVec = ray.sdir * abs(ray.rdir) * tSkip;
ray.ori += stepVec;
voxelCoord = floor(ray.ori);
totalStep = (ray.sdir * (voxelCoord - ray.ori + 0.5) + 0.5) * abs(ray.rdir);
continue;
}
rayLength = minVec3(totalStep);
tracingNext = step(totalStep, vec3(rayLength));
voxelCoord += tracingNext * ray.sdir;
totalStep += tracingNext * abs(ray.rdir);
}
}
return shadow;
}
// Simplified version for IRC / light sampling (no soft penumbra)
float SimpleShadowTracing(vec3 voxelPos, vec3 lightVector){
Ray ray = PackRay(voxelPos, lightVector);
vec3 voxelCoord = floor(ray.ori);
vec3 totalStep = (ray.sdir * (voxelCoord - ray.ori + 0.5) + 0.5) * abs(ray.rdir);
float rayLength = 0.0;
vec3 tracingNext;
bool hit = false;
for (int i = 0; i < 64; i++){
if (clamp(voxelCoord, vec3(0.0), vec3(voxelResolution - 0.5)) != voxelCoord) break;
vec4 voxelData = texelFetch(voxelData3D, ivec3(voxelCoord), 0);
float voxelID = DecodeVoxelID(voxelData.z);
if (voxelID >= 999.0){
hit = rayLength > 0.0;
}else if (voxelID < 1000.0 && voxelID > 1.0){
float rawID = 1000.0 - voxelID;
rayLength = minVec3(totalStep);
hit = HitShape_Lite(ray, voxelCoord, rawID, rayLength);
}
if (hit) break;
// Sparse skip
float marker = voxelData.z;
if (marker > 0.60 && marker < 0.92){
float skipSize = marker > 0.90 ? 8.0 : (marker > 0.70 ? 4.0 : 2.0);
vec3 nextBoundary = floor((voxelCoord + 1.0) / skipSize) * skipSize;
vec3 distToBoundary = (nextBoundary - voxelCoord) * abs(ray.rdir);
float tSkip = minVec3(distToBoundary) + 1e-4;
rayLength += tSkip;
vec3 stepVec = ray.sdir * abs(ray.rdir) * tSkip;
ray.ori += stepVec;
voxelCoord = floor(ray.ori);
totalStep = (ray.sdir * (voxelCoord - ray.ori + 0.5) + 0.5) * abs(ray.rdir);
continue;
}
rayLength = minVec3(totalStep);
tracingNext = step(totalStep, vec3(rayLength));
voxelCoord += tracingNext * ray.sdir;
totalStep += tracingNext * abs(ray.rdir);
}
return float(!hit);
}
#endif