bvle-voxels/shaders/voxelCommon.hlsli

105 lines
5.3 KiB
HLSL
Raw Normal View History

// BVLE Voxels - Shared shader definitions
// Root signature, common structures, and constant buffers for voxel shaders.
#ifndef VOXEL_COMMON_HLSLI
#define VOXEL_COMMON_HLSLI
// Wicked Engine DX12 root signature (HLSL 6.6+ bindless model)
// b999: push constants (12 x uint32 = 48 bytes)
// b0-b2: root CBV descriptors
// t0-t15, u0-u15: SRV/UAV descriptor table
// s0-s7: dynamic samplers
// s100+: static samplers
#define VOXEL_ROOTSIG \
"RootFlags(CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED | SAMPLER_HEAP_DIRECTLY_INDEXED), " \
"RootConstants(num32BitConstants=12, b999), " \
"CBV(b0), " \
"CBV(b1), " \
"CBV(b2), " \
"DescriptorTable( " \
"CBV(b3, numDescriptors = 11, flags = DATA_STATIC_WHILE_SET_AT_EXECUTE)," \
"SRV(t0, numDescriptors = 16, flags = DESCRIPTORS_VOLATILE | DATA_STATIC_WHILE_SET_AT_EXECUTE)," \
"UAV(u0, numDescriptors = 16, flags = DESCRIPTORS_VOLATILE | DATA_STATIC_WHILE_SET_AT_EXECUTE)" \
")," \
"DescriptorTable( " \
"Sampler(s0, offset = 0, numDescriptors = 8, flags = DESCRIPTORS_VOLATILE)" \
")," \
"StaticSampler(s100, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_MIN_MAG_MIP_LINEAR)," \
"StaticSampler(s101, addressU = TEXTURE_ADDRESS_WRAP, addressV = TEXTURE_ADDRESS_WRAP, addressW = TEXTURE_ADDRESS_WRAP, filter = FILTER_MIN_MAG_MIP_LINEAR)," \
"StaticSampler(s102, addressU = TEXTURE_ADDRESS_MIRROR, addressV = TEXTURE_ADDRESS_MIRROR, addressW = TEXTURE_ADDRESS_MIRROR, filter = FILTER_MIN_MAG_MIP_LINEAR)," \
"StaticSampler(s103, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_MIN_MAG_MIP_POINT)," \
"StaticSampler(s104, addressU = TEXTURE_ADDRESS_WRAP, addressV = TEXTURE_ADDRESS_WRAP, addressW = TEXTURE_ADDRESS_WRAP, filter = FILTER_MIN_MAG_MIP_POINT)," \
"StaticSampler(s105, addressU = TEXTURE_ADDRESS_MIRROR, addressV = TEXTURE_ADDRESS_MIRROR, addressW = TEXTURE_ADDRESS_MIRROR, filter = FILTER_MIN_MAG_MIP_POINT)," \
"StaticSampler(s106, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_ANISOTROPIC, maxAnisotropy = 16)," \
"StaticSampler(s107, addressU = TEXTURE_ADDRESS_WRAP, addressV = TEXTURE_ADDRESS_WRAP, addressW = TEXTURE_ADDRESS_WRAP, filter = FILTER_ANISOTROPIC, maxAnisotropy = 16)," \
"StaticSampler(s108, addressU = TEXTURE_ADDRESS_MIRROR, addressV = TEXTURE_ADDRESS_MIRROR, addressW = TEXTURE_ADDRESS_MIRROR, filter = FILTER_ANISOTROPIC, maxAnisotropy = 16)," \
"StaticSampler(s109, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT, comparisonFunc = COMPARISON_GREATER_EQUAL),"
// ── Per-frame constant buffer (b0) ──────────────────────────────
cbuffer VoxelCB : register(b0) {
float4x4 viewProjection;
float4 cameraPosition;
float4 sunDirection;
float4 sunColor;
float chunkSize;
float textureTiling;
float blendEnabled;
float debugBlend; // >0.5 = show blend zones as debug colors
// Frustum culling data (used by cull compute shader)
float4 frustumPlanes[6]; // ax+by+cz+d=0, xyz=normal, w=distance
uint chunkCount;
uint bleedMask; // bit N set = material N can bleed onto neighbors
uint resistBleedMask; // bit N set = material N resists bleed from neighbors
uint _cullPad2;
};
// ── Indirect draw args (must match C++ IndirectDrawArgs, 20 bytes) ──
// Wicked Engine's DrawInstancedIndirectCount command signature includes a push
// constant (1 × uint32 at b999[0]) BEFORE each D3D12_DRAW_ARGUMENTS.
// Total stride = 4 + 16 = 20 bytes per draw entry.
struct IndirectDrawArgsInstanced {
uint pushConstant; // written to b999[0] by ExecuteIndirect
uint vertexCountPerInstance;
uint instanceCount;
uint startVertexLocation;
uint startInstanceLocation;
};
// ── GPU chunk info (must match C++ GPUChunkInfo, 80 bytes) ──────
// NOTE: No arrays — scalar-only to guarantee C-style packing in StructuredBuffer.
struct GPUChunkInfo {
float4 worldPos; // xyz = chunk origin in world space, w = debug flag
uint quadOffset; // offset into mega quad buffer (in quads)
uint quadCount; // number of quads for this chunk
uint _pad0;
uint _pad1;
// Per-face data (6 faces: +X -X +Y -Y +Z -Z)
uint faceOff0, faceOff1, faceOff2, faceOff3, faceOff4, faceOff5;
uint faceCnt0, faceCnt1, faceCnt2, faceCnt3, faceCnt4, faceCnt5;
};
// Helper functions to access scalar face fields by index
uint getFaceOffset(GPUChunkInfo info, uint f) {
switch (f) {
case 0: return info.faceOff0;
case 1: return info.faceOff1;
case 2: return info.faceOff2;
case 3: return info.faceOff3;
case 4: return info.faceOff4;
default: return info.faceOff5;
}
}
uint getFaceCount(GPUChunkInfo info, uint f) {
switch (f) {
case 0: return info.faceCnt0;
case 1: return info.faceCnt1;
case 2: return info.faceCnt2;
case 3: return info.faceCnt3;
case 4: return info.faceCnt4;
default: return info.faceCnt5;
}
}
#endif // VOXEL_COMMON_HLSLI