104 lines
5.3 KiB
HLSL
104 lines
5.3 KiB
HLSL
// 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
|
||
float windTime; // elapsed time for wind animation (seconds)
|
||
};
|
||
|
||
// ── 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
|