#include "/Lib/Settings.glsl" #include "/Lib/Utilities.glsl" // MinecraftPT — Voxel Profile // Voxel grid parameters derived from settings. // // The shadow framebuffer (shadowcolor0/1) is square, size S x S, and holds: // - the VOXEL ATLAS in the bottom-left region: texels [0, W) x [0, H) // where W = voxelWidth and H = ceil(N / W), N = Rx*Ry*Rz voxels. // Each voxel is one texel; linear packing: n = x + y*Rx + z*Rx*Ry. // - the SHADOW MAP in the right square region: texels [W, 2W) x [0, W). // The shadow camera NDC is shifted into this region (square -> square, // no aspect distortion). Effective shadow resolution = W. #ifndef VOXEL_PROFILE_GLSL #define VOXEL_PROFILE_GLSL // Shadow render distance -> shadow coverage #if SHADOW_RENDER_DISTANCE == 4 const float shadowDistance = 64.1; #elif SHADOW_RENDER_DISTANCE == 6 const float shadowDistance = 96.1; #elif SHADOW_RENDER_DISTANCE == 8 const float shadowDistance = 128.1; #elif SHADOW_RENDER_DISTANCE == 12 const float shadowDistance = 192.1; #elif SHADOW_RENDER_DISTANCE == 16 const float shadowDistance = 256.1; #elif SHADOW_RENDER_DISTANCE == 24 const float shadowDistance = 384.1; #elif SHADOW_RENDER_DISTANCE == 32 const float shadowDistance = 512.1; #elif SHADOW_RENDER_DISTANCE == 48 const float shadowDistance = 768.1; #elif SHADOW_RENDER_DISTANCE == 64 const float shadowDistance = 1024.1; #elif SHADOW_RENDER_DISTANCE == 96 const float shadowDistance = 1536.1; #elif SHADOW_RENDER_DISTANCE == 128 const float shadowDistance = 2048.1; #else const float shadowDistance = 256.1; #endif // Voxel grid resolution and coverage (blocks) #if PT_VOXEL_RESOLUTION == 4004 const ivec3 voxelResolutionInt = ivec3(128); const float voxelDistance = 64.0; const int voxelWidth = 2048; #elif PT_VOXEL_RESOLUTION == 6004 const ivec3 voxelResolutionInt = ivec3(192, 128, 192); const float voxelDistance = 96.0; const int voxelWidth = 2048; #elif PT_VOXEL_RESOLUTION == 8004 const ivec3 voxelResolutionInt = ivec3(256, 128, 256); const float voxelDistance = 128.0; const int voxelWidth = 2048; #elif PT_VOXEL_RESOLUTION == 8006 const ivec3 voxelResolutionInt = ivec3(256, 192, 256); const float voxelDistance = 128.0; const int voxelWidth = 4096; #elif PT_VOXEL_RESOLUTION == 8008 const ivec3 voxelResolutionInt = ivec3(256); const float voxelDistance = 128.0; const int voxelWidth = 4096; #elif PT_VOXEL_RESOLUTION == 12004 const ivec3 voxelResolutionInt = ivec3(384, 128, 384); const float voxelDistance = 192.0; const int voxelWidth = 4096; #elif PT_VOXEL_RESOLUTION == 12006 const ivec3 voxelResolutionInt = ivec3(384, 192, 384); const float voxelDistance = 192.0; const int voxelWidth = 4096; #elif PT_VOXEL_RESOLUTION == 12008 const ivec3 voxelResolutionInt = ivec3(384, 256, 384); const float voxelDistance = 192.0; const int voxelWidth = 6144; #elif PT_VOXEL_RESOLUTION == 16004 const ivec3 voxelResolutionInt = ivec3(512, 128, 512); const float voxelDistance = 256.0; const int voxelWidth = 6144; #elif PT_VOXEL_RESOLUTION == 16008 const ivec3 voxelResolutionInt = ivec3(512, 256, 512); const float voxelDistance = 256.0; const int voxelWidth = 6144; #elif PT_VOXEL_RESOLUTION == 16016 const ivec3 voxelResolutionInt = ivec3(512); const float voxelDistance = 256.0; const int voxelWidth = 8192; #else const ivec3 voxelResolutionInt = ivec3(256, 192, 256); const float voxelDistance = 128.0; const int voxelWidth = 4096; #endif const vec3 voxelResolution = vec3(voxelResolutionInt); // Irradiance cache resolution (clamped to voxel grid) const int ircResolution = min(PT_IRC_RESOLUTION, voxelResolutionInt.x); // Shadow framebuffer size (square) const int shadowMapResolution = voxelWidth * 2; const float shadowSize = float(shadowMapResolution); const float shadowPixelSize = 1.0 / shadowSize; const float shadowRatio = 0.5; // W / S // Map 3D voxel coordinate to 2D atlas texel (linear packing) vec2 VoxelTexel_From_VoxelCoord(vec3 voxelCoord){ float n = voxelCoord.x + voxelCoord.y * voxelResolution.x + voxelCoord.z * voxelResolution.x * voxelResolution.y; return vec2(mod(n, float(voxelWidth)), floor(n / float(voxelWidth))); } // Shift shadow map NDC into the right square region [W, 2W] x [0, W] void ShiftShadowNdcPos(inout vec2 coord){ coord = coord * shadowRatio + vec2(1.0 - shadowRatio, shadowRatio - 1.0); } // Shift shadow map screen uv into the right square region void ShiftShadowScreenPos(inout vec2 coord){ coord = coord * shadowRatio + vec2(1.0 - shadowRatio, 0.0); } // Shift back from shadow region uv to standard shadow uv vec2 UnshiftShadowScreenPos(vec2 coord){ return (coord - vec2(1.0 - shadowRatio, 0.0)) / shadowRatio; } // Block ID encoding (16-bit range) // Full block: voxelID + 1000 // Cutout shape: 1000 - voxelID // Empty markers: 0.91 (8^3), 0.71 (4^3), 0.61 (2^3) float EncodeVoxelID(float voxelID){ return saturate((voxelID + 1000.0) / 65535.0); } float DecodeVoxelID(float encoded){ return abs(floor(encoded * 65535.0 - 999.9)); } #endif