You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 ;

问题排查方向

  1. 管线配置笔误:
    管线代码中PS绑定的是cShader,但编译代码中Pixel Shader的变量是pShader,这会导致像素着色器未正确绑定,直接引发画面空白。修正代码:

    pipeLineDesc.PS={DX12.Shaders.pShader->GetBufferPointer(), DX12.Shaders.pShader->GetBufferSize()};
    
  2. 绘制拓扑未更新:
    启用曲面细分后,除了设置管线的PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH,还需要在绘制时将输入装配阶段的拓扑设置为D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,即调用:

    CommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST);
    

    如果仍使用原三角形拓扑,GPU无法正确解析Patch数据,导致无输出。

  3. 坐标裁剪验证:
    可临时修改Domain Shader的输出Position为固定NDC坐标(如float4(0, 0, 0, 1.0f)),测试是否有画面输出,排除坐标不在视锥体内被裁剪的问题。

  4. 语义匹配检查:
    确保VS输出的结构体与HS输入的InputPatch结构体语义完全匹配,内存布局一致。当前VS输出的pos : POSITION与HS输入的Position : POSITION语义匹配,这部分无明显问题,但可通过调试工具(如RenderDoc)查看着色器阶段的输出数据是否正常。

内容的提问来源于stack exchange,提问作者I101I

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 03:04:58