#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