bvle-voxels/shaders/voxelPS.hlsl

84 lines
2.8 KiB
HLSL
Raw Normal View History

// 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);
}