// BVLE Voxels - Pixel Shader (Triplanar textured with simple lighting) #include "voxelCommon.hlsli" Texture2DArray materialTextures : register(t1); SamplerState materialSampler : register(s0); struct PSInput { float4 position : SV_POSITION; float3 worldPos : WORLDPOS; float3 normal : NORMAL; float2 uv : TEXCOORD0; nointerpolation uint materialID : MATERIALID; nointerpolation uint faceID : FACEID; nointerpolation float debugFlag : DEBUGFLAG; float ao : AO; }; // Triplanar blend weights float3 triplanarWeights(float3 normal, float sharpness) { float3 w = abs(normal); w = pow(w, (float3)sharpness); return w / (w.x + w.y + w.z + 0.0001); } float3 sampleTriplanar(float3 worldPos, float3 normal, uint texIndex, float tiling) { float3 w = triplanarWeights(normal, 4.0); float3 colX = materialTextures.Sample(materialSampler, float3(worldPos.yz * tiling, (float)texIndex)).rgb; float3 colY = materialTextures.Sample(materialSampler, float3(worldPos.xz * tiling, (float)texIndex)).rgb; float3 colZ = materialTextures.Sample(materialSampler, float3(worldPos.xy * tiling, (float)texIndex)).rgb; return colX * w.x + colY * w.y + colZ * w.z; } // Debug face colors static const float3 faceDebugColors[6] = { float3(1.0, 0.2, 0.2), // 0: +X = RED float3(0.5, 0.0, 0.0), // 1: -X = DARK RED float3(0.2, 1.0, 0.2), // 2: +Y = GREEN float3(0.0, 0.5, 0.0), // 3: -Y = DARK GREEN float3(0.2, 0.2, 1.0), // 4: +Z = BLUE float3(0.0, 0.0, 0.5), // 5: -Z = DARK BLUE }; [RootSignature(VOXEL_ROOTSIG)] float4 main(PSInput input) : SV_TARGET0 { // ── DEBUG MODE: face direction colors ── if (input.debugFlag > 0.5) { uint fid = min(input.faceID, 5u); float3 faceColor = faceDebugColors[fid]; float2 checker = floor(input.worldPos.xz * 0.5); float check = frac((checker.x + checker.y) * 0.5) * 2.0; faceColor *= (0.85 + 0.15 * check); return float4(faceColor, 1.0); } // ── NORMAL MODE: triplanar textured ── float3 N = normalize(input.normal); float3 L = normalize(-sunDirection.xyz); float NdotL = max(dot(N, L), 0.0); float3 baseColor = N * 0.5 + 0.5; uint texIndex = clamp(input.materialID - 1u, 0u, 4u); float tiling = textureTiling; float3 texColor = sampleTriplanar(input.worldPos, N, texIndex, tiling); float3 albedo = (input.materialID > 0u) ? texColor : baseColor; float3 ambient = float3(0.15, 0.18, 0.25); float3 diffuse = sunColor.rgb * NdotL; float3 color = albedo * (ambient + diffuse) * input.ao; float dist = length(input.worldPos - cameraPosition.xyz); float fog = 1.0 - exp(-dist * 0.003); float3 fogColor = float3(0.55, 0.70, 0.90); color = lerp(color, fogColor, saturate(fog)); return float4(color, 1.0); }