DirectX12启用曲面细分后画面空白问题排查求助
问题:DirectX12启用曲面细分后屏幕空白
我在DirectX12中尝试为多边形实现曲面细分功能,编写了简化的Hull Shader(HS)和Domain Shader(DS),但启用后屏幕显示空白。所有曲面细分参数都设为1.0f,理论上应和原图形一致,且无编译错误。以下是相关代码与配置:
着色器代码
曲面细分着色器(HS/DS)
struct Vertex{ float3 Position : POSITION; float4 Color : COLOR; }; struct tesOutput{ float edgeTessellationFactor[3] : SV_TessFactor; float insideTessellationFactor : SV_InsideTessFactor; }; tesOutput ConstantHS(InputPatch< Vertex, 3> patch, uint patchID : SV_PrimitiveID ){ tesOutput output; output.edgeTessellationFactor[0] = 1.0f; output.edgeTessellationFactor[1] = 1.0f; output.edgeTessellationFactor[2] = 1.0f; output.insideTessellationFactor = 1.0f; return output; } [domain("tri")] [partitioning("integer")] [outputtopology("triangle_cw")] [outputcontrolpoints(3)] [patchconstantfunc("ConstantHS")] Vertex hull(InputPatch< Vertex, 3> patch, uint cPoint : SV_OutputControlPointID){ return patch[cPoint]; } struct DomainOut{ float4 Position : SV_POSITION; float4 Color : COLOR; }; [domain("tri")] DomainOut domain(OutputPatch< Vertex, 3> patch, tesOutput tessInput, float3 UVW : SV_DomainLocation ){ DomainOut output; float4 _1=float4(patch[0].Position.xyz,1); float4 _2=float4(patch[1].Position.xyz,1); float4 _3=float4(patch[2].Position.xyz,1); output.Position=_1 * UVW.x + _2 * UVW.y + _3 * UVW.z ; output.Position=float4(output.Position.xyz, 1.0f); output.Color = float4(1.0f, 0.0f, 1.0f, 1.0f); return output; }
配套Vertex Shader(VS)与Pixel Shader(PS)
VS代码:
struct vertex{ float3 pos : POSITION; float4 color : COLOR; }; vertex main(float3 position : POSITION, float4 color : COLOR) { vertex output; output.pos = position; output.color = float4(1.0f, 0.0f, 1.0f, 1.0f); return output; }
PS代码:
struct VS_OUTPUT { float4 pos: SV_POSITION; float4 color: COLOR; }; float4 main(VS_OUTPUT input) : SV_TARGET { return input.color; }
未启用细分时正常渲染的VS代码
struct vertex{ float4 pos : SV_POSITION; float4 color : COLOR; }; vertex main(float3 position : POSITION, float4 color : COLOR) { vertex output; output.pos = float4(position, 1); output.color = float4(1.0f, 0.0f, 1.0f, 1.0f); return output; }
编译与管线配置代码
着色器编译代码
D3DCompileFromFile(L"Shaders/VertexShader.hlsl", nullptr, nullptr, "main", "vs_5_0", D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &DX12.Shaders.vShader, &error) D3DCompileFromFile(L"Shaders/TeselationShader.hlsl", nullptr, nullptr, "hull", "hs_5_0", D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &DX12.Shaders.hShader, &error) D3DCompileFromFile(L"Shaders/TeselationShader.hlsl", nullptr, nullptr, "domain", "ds_5_0", D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &DX12.Shaders.dShader, &error) D3DCompileFromFile(L"Shaders/ColorShader.hlsl", nullptr, nullptr, "main", "ps_5_0", D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &DX12.Shaders.pShader, &error)
管线配置代码
pipeLineDesc.VS={DX12.Shaders.vShader->GetBufferPointer(), DX12.Shaders.vShader->GetBufferSize()}; pipeLineDesc.PS={DX12.Shaders.cShader->GetBufferPointer(), DX12.Shaders.cShader->GetBufferSize()}; pipeLineDesc.HS={DX12.Shaders.hShader->GetBufferPointer(), DX12.Shaders.hShader->GetBufferSize()}; pipeLineDesc.DS={DX12.Shaders.dShader->GetBufferPointer(), DX12.Shaders.dShader->GetBufferSize()}; pipeLineDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED; pipeLineDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH ;
问题排查方向
管线配置笔误:
管线代码中PS绑定的是cShader,但编译代码中Pixel Shader的变量是pShader,这会导致像素着色器未正确绑定,直接引发画面空白。修正代码:pipeLineDesc.PS={DX12.Shaders.pShader->GetBufferPointer(), DX12.Shaders.pShader->GetBufferSize()};绘制拓扑未更新:
启用曲面细分后,除了设置管线的PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH,还需要在绘制时将输入装配阶段的拓扑设置为D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,即调用:CommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST);如果仍使用原三角形拓扑,GPU无法正确解析Patch数据,导致无输出。
坐标裁剪验证:
可临时修改Domain Shader的输出Position为固定NDC坐标(如float4(0, 0, 0, 1.0f)),测试是否有画面输出,排除坐标不在视锥体内被裁剪的问题。语义匹配检查:
确保VS输出的结构体与HS输入的InputPatch结构体语义完全匹配,内存布局一致。当前VS输出的pos : POSITION与HS输入的Position : POSITION语义匹配,这部分无明显问题,但可通过调试工具(如RenderDoc)查看着色器阶段的输出数据是否正常。
内容的提问来源于stack exchange,提问作者I101I
相关产品推荐
相关产品推荐

