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