I am having an issue with always passing the depth test and writing my skybox over existing geometry. I draw the skybox last, and it is all you see on screen. Turn it off, and my scene renders fine. Here is the setup, hope someone can tell me where I am wrong (pulling hair out) trying to setup DirectX 12 depth testing correctly:
Header:
using the Microsoft mini engine core as my renderer
SamplerDescriptor m_skySampler;
RootSignature m_skyRootSig;
GraphicsPSO m_skyPSO;
Initialization:
// root signature sky map
m_skyRootSig.Reset(2, 2);
m_skyRootSig.InitStaticSampler(0, SamplerAnisoWrapDesc, D3D12_SHADER_VISIBILITY_PIXEL);
SamplerDesc samplerSkyDesc;
samplerSkyDesc.Filter = D3D12_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
samplerSkyDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
samplerSkyDesc.SetTextureAddressMode(D3D12_TEXTURE_ADDRESS_MODE_CLAMP);
m_skySampler.Create(samplerSkyDesc);
m_skyRootSig.InitStaticSampler(1, samplerSkyDesc, D3D12_SHADER_VISIBILITY_PIXEL);
// parameters
m_skyRootSig[0].InitAsConstantBuffer(0, D3D12_SHADER_VISIBILITY_VERTEX); // vertex shader float4x4 modelToProjection;
m_skyRootSig[1].InitAsDescriptorRange(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0, 6, D3D12_SHADER_VISIBILITY_PIXEL);
m_skyRootSig.Finalize(L"SkyMap", D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
/* Sky box PSO */
m_skyPSO.SetRootSignature(m_skyRootSig);
D3D12_RASTERIZER_DESC rastDesc;
rastDesc.FillMode = D3D12_FILL_MODE_SOLID;
rastDesc.CullMode = D3D12_CULL_MODE_NONE;
rastDesc.DepthClipEnable = TRUE;
m_skyPSO.SetRasterizerState(rastDesc);
m_skyPSO.SetBlendState(BlendDisable);
D3D12_DEPTH_STENCILOP_DESC stencilOp;
stencilOp.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP;
stencilOp.StencilPassOp = D3D12_STENCIL_OP_KEEP;
stencilOp.StencilFailOp = D3D12_STENCIL_OP_KEEP;
stencilOp.StencilFunc = D3D12_COMPARISON_FUNC_NEVER;
D3D12_DEPTH_STENCIL_DESC skyBox = DepthStateDisabled;
skyBox.DepthEnable = TRUE; // depth testing enabled on pixel shader
skyBox.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO; // read only
skyBox.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
skyBox.StencilEnable = FALSE;
skyBox.StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK;
skyBox.StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK;
skyBox.FrontFace = stencilOp;
skyBox.BackFace = stencilOp;
m_skyPSO.SetDepthStencilState(skyBox);
D3D12_INPUT_ELEMENT_DESC vertElemSky[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
};
m_skyPSO.SetInputLayout(_countof(vertElemSky), vertElemSky);
m_skyPSO.SetSampleMask(0xFFFFFFFF);
m_skyPSO.SetPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
m_skyPSO.SetRenderTargetFormats(1, &ColorFormat, DepthFormat);
m_skyPSO.SetVertexShader(g_pSkyVS, sizeof(g_pSkyVS));
m_skyPSO.SetPixelShader(g_pSkyPS, sizeof(g_pSkyPS));
m_skyPSO.Finalize();
Shader parameter validation:
#define Sky_RootSig \
"RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \
"CBV(b0, visibility = SHADER_VISIBILITY_VERTEX), " \
"DescriptorTable(SRV(t0, numDescriptors = 6), visibility = SHADER_VISIBILITY_PIXEL)," \
"StaticSampler(s0, maxAnisotropy = 8, visibility = SHADER_VISIBILITY_PIXEL)," \
"StaticSampler(s1, visibility = SHADER_VISIBILITY_PIXEL," \
"addressU = TEXTURE_ADDRESS_WRAP," \
"addressV = TEXTURE_ADDRESS_WRAP," \
"addressW = TEXTURE_ADDRESS_WRAP," \
"comparisonFunc = COMPARISON_LESS_EQUAL," \
"filter = FILTER_MIN_MAG_LINEAR_MIP_POINT)"
Vertex Shader:
#include "SkyRS.hlsli"
cbuffer VSConstants : register(b0)
{
float4x4 modelToProjection;
};
struct VSInput
{
float3 position : POSITION;
};
struct VSOutput
{
float4 position : SV_POSITION; // screen space position of the pixel
float3 texLookUp : POSITION;
};
[RootSignature(Sky_RootSig)]
VSOutput main(VSInput vsInput)
{
VSOutput vsOutput;
vsOutput.texLookUp = vsInput.position; // use position as index to cube map
float3 projected = mul(vsInput.position, (float3x3)modelToProjection); // ignore translation
vsOutput.position = float4(projected, 1.0f).xyww; // Set z = w which forces the farthest possible z value
//vsOutput.position = float4(vsInput.position, 1.0f).xyww;
return vsOutput;
}
Pixel shader:
#include "SkyRS.hlsli"
struct VSOutput
{
float4 position : SV_POSITION; // screenspace position of the pixel
float3 texLookUp : POSITION;
};
TextureCube cubeMap : register(t0);
SamplerState sampler0 : register(s0);
SamplerState sampler1 : register(s1);
[RootSignature(Sky_RootSig)]
float3 main(VSOutput pin) : SV_Target0
{
//return float3(1.f,0.f,0.f);
return cubeMap.Sample(sampler1, pin.texLookUp);
}
↧