bvle-voxels/shaders/voxelSmoothPS.hlsl

58 lines
2.1 KiB
HLSL
Raw Normal View History

// BVLE Voxels - Smooth Surface Nets Pixel Shader (Phase 5.1)
// Triplanar texture sampling + material blending + same lighting as voxel PS.
#include "voxelCommon.hlsli"
Texture2DArray<float4> materialTextures : register(t1);
SamplerState texSampler : register(s0);
struct PSInput {
float4 position : SV_POSITION;
float3 worldPos : WORLDPOS;
float3 normal : NORMAL;
nointerpolation uint matPacked : MATERIALID;
};
// Sample triplanar texture for a given material index
float3 sampleTriplanar(float3 worldPos, float3 blend, float tiling, uint matIdx) {
uint texIdx = clamp(matIdx - 1u, 0u, 5u);
float4 xS = materialTextures.Sample(texSampler, float3(worldPos.yz * tiling, (float)texIdx));
float4 yS = materialTextures.Sample(texSampler, float3(worldPos.xz * tiling, (float)texIdx));
float4 zS = materialTextures.Sample(texSampler, float3(worldPos.xy * tiling, (float)texIdx));
return xS.rgb * blend.x + yS.rgb * blend.y + zS.rgb * blend.z;
}
[RootSignature(VOXEL_ROOTSIG)]
float4 main(PSInput input) : SV_TARGET0 {
float3 N = normalize(input.normal);
float tiling = textureTiling;
// Unpack materials: materialID(8) | secondaryMat(8) | blendWeight(8) | pad(8)
uint primaryMat = input.matPacked & 0xFF;
uint secondaryMat = (input.matPacked >> 8) & 0xFF;
float blendWeight = ((input.matPacked >> 16) & 0xFF) / 255.0;
// Triplanar blend weights
float3 blend = abs(N);
blend = blend / (blend.x + blend.y + blend.z + 0.001);
// Sample primary and secondary materials
float3 primaryColor = sampleTriplanar(input.worldPos, blend, tiling, primaryMat);
float3 texColor;
if (blendWeight > 0.01 && secondaryMat != primaryMat) {
float3 secondaryColor = sampleTriplanar(input.worldPos, blend, tiling, secondaryMat);
texColor = lerp(primaryColor, secondaryColor, blendWeight);
} else {
texColor = primaryColor;
}
// Lighting (same model as voxel PS)
float3 L = normalize(-sunDirection.xyz);
float NdotL = max(dot(N, L), 0.0);
float3 ambient = float3(0.15, 0.18, 0.25);
float3 lit = texColor * (sunColor.rgb * NdotL + ambient);
return float4(lit, 1.0);
}