bvle-voxels/shaders/voxelAOApplyCS.hlsl

55 lines
1.7 KiB
HLSL
Raw Normal View History

// BVLE Voxels - AO Apply + Tone Mapping Compute Shader (Phase 6.3 + 7)
// Final post-process pass: applies AO, saturation boost, and tone mapping.
#include "voxelCommon.hlsli"
Texture2D<float> aoBlurred : register(t0);
RWTexture2D<float4> colorOutput : register(u0);
struct ApplyPush {
uint width;
uint height;
uint debugMode; // 0=normal, 2=debug AO (show AO as grayscale)
uint pad[9];
};
[[vk::push_constant]] ConstantBuffer<ApplyPush> push : register(b999);
// Soft clamp tone mapping: linear up to shoulder, gentle roll-off to prevent harsh clipping
float3 softClampToneMap(float3 color, float exposure) {
color *= exposure;
// Soft exponential curve: gentler than Reinhard, preserves bright midtones
return 1.0 - exp(-color); // natural 1-e^-x curve
}
// Saturation adjustment in linear space
float3 adjustSaturation(float3 color, float saturation) {
float luma = dot(color, float3(0.2126, 0.7152, 0.0722));
return lerp(float3(luma, luma, luma), color, saturation);
}
[RootSignature(VOXEL_ROOTSIG)]
[numthreads(8, 8, 1)]
void main(uint3 DTid : SV_DispatchThreadID) {
if (DTid.x >= push.width || DTid.y >= push.height) return;
float ao = aoBlurred[DTid.xy];
if (push.debugMode == 2) {
// Debug AO: grayscale visualization of blurred AO
colorOutput[DTid.xy] = float4(ao, ao, ao, 1);
} else {
float4 color = colorOutput[DTid.xy];
// Apply AO
color.rgb *= ao;
// Saturation boost (toneMapParams.x)
color.rgb = adjustSaturation(color.rgb, toneMapParams.x);
// Tone mapping (toneMapParams.y = exposure)
color.rgb = softClampToneMap(color.rgb, toneMapParams.y);
colorOutput[DTid.xy] = color;
}
}