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

Direct3D 12/PIX调试异常:像素着色器未被调用

Direct3D 12像素着色器未被调用的排查方向

我是Direct3D 12开发新手,搭建测试项目熟悉流程时遇到问题:通过PIX调试确认顶点着色器运行正常,但像素着色器未被调用。已检查裁剪区域、视口和深度缓冲,确认顶点未被裁剪,但问题仍未解决。

相关截图说明:

  • PIX中的管线状态
  • PIX中的顶点着色器输出

相关代码片段

光栅化状态、深度模板状态

D3D12_RASTERIZER_DESC rasterizer{};

rasterizer.FillMode = D3D12_FILL_MODE_SOLID;
rasterizer.CullMode = D3D12_CULL_MODE_NONE;
rasterizer.FrontCounterClockwise = FALSE;
rasterizer.DepthClipEnable = TRUE; 
rasterizer.MultisampleEnable = FALSE;
rasterizer.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;

pipelineDesc.RasterizerState = rasterizer;

D3D12_DEPTH_STENCIL_DESC depthStencil{};

depthStencil.DepthEnable = TRUE; 
depthStencil.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
depthStencil.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
depthStencil.StencilEnable = FALSE;
depthStencil.FrontFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
depthStencil.BackFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
depthStencil.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
depthStencil.BackFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
depthStencil.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
depthStencil.BackFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;

交换链创建、RTV创建

DXGI_SWAP_CHAIN_DESC1 swapchainDescription{};
DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreenDescription{};

swapchainDescription.Width = 0;
swapchainDescription.Height = 0;
swapchainDescription.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
swapchainDescription.Stereo = FALSE;
swapchainDescription.SampleDesc = { 1, 0 };
swapchainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapchainDescription.BufferCount = 2;
swapchainDescription.Scaling = DXGI_SCALING_NONE;
swapchainDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapchainDescription.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
swapchainDescription.Flags = 0;

fullscreenDescription.RefreshRate = { 1, 60 };
fullscreenDescription.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
fullscreenDescription.Scaling = DXGI_MODE_SCALING_CENTERED;
fullscreenDescription.Windowed = TRUE;

CheckHresult(factory->CreateSwapChainForHwnd(commandQueue, hwnd, &swapchainDescription, &fullscreenDescription, NULL, &t_swapchain));

HRESULT sres = t_swapchain->QueryInterface(IID_PPV_ARGS(&swapchain));

D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapInfoRtv{};

descriptorHeapInfoRtv.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
descriptorHeapInfoRtv.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
descriptorHeapInfoRtv.NumDescriptors = 2;
descriptorHeapInfoRtv.NodeMask = 0;

device->CreateDescriptorHeap(&descriptorHeapInfoRtv, IID_PPV_ARGS(&rtv_descriptorHeap.descriptorHeap));
rtv_descriptorHeap.incrementSize = device->GetDescriptorHandleIncrementSize(descriptorHeapInfoRtv.Type);
rtv_descriptorHeap.startHandle = rtv_descriptorHeap.descriptorHeap->GetCPUDescriptorHandleForHeapStart();

device->CreateRenderTargetView(swapchainBuffers[0], NULL, rtv_descriptorHeap.startHandle);
device->CreateRenderTargetView(swapchainBuffers[1], NULL, rtv_descriptorHeap.AddOffset(1));

着色器代码

// Vertex Shader
struct VS_IN
{
    float4 pos : POSITION;
};

struct VS_OUT
{
    float4 pos : SV_Position;
};

VS_OUT main(VS_IN inp) 
{
    VS_OUT outp;
    outp.pos = float4(inp.pos.x, inp.pos.y, inp.pos.z, 1.0f);
    return outp;
}

// Pixel Shader
struct PS_OUT
{
    float4 col_in : COLOR;
};

struct VS_OUT
{
    float4 pos : SV_Position;
};

float4 main(VS_OUT inp) : SV_Target
{
    PS_OUT outp;
    outp.col_in = float4(1.0f, 1.0f, 1.0f, 1.0f);
    return outp.col_in;
}

已尝试操作:使用默认设置和自定义RenderTargetView描述、禁用深度测试、修改管线状态samplemask,问题仍未解决。

排查方向

  • 检查齐次坐标转换:顶点着色器直接输出w=1.0的原始坐标,未转换到Direct3D要求的齐次裁剪空间(x,y,z需落在[-w,w]范围内)。如果顶点不在此范围,光栅化阶段会被剔除。需将顶点坐标映射到NDC空间(比如正交投影下转换到[-1,1],透视投影执行对应计算)。
  • 验证深度缓冲的创建与绑定:当前代码仅创建了RTV,未看到深度缓冲(DSV)的创建和绑定逻辑。开启DepthEnable=TRUE但未正确绑定深度缓冲会导致光栅化异常,进而不触发像素着色器。需确认:
    • 创建了格式正确的深度纹理(如DXGI_FORMAT_D32_FLOAT)
    • 创建DSV描述符堆并正确绑定到命令列表
    • OMSetRenderTargets时同时设置RTV和DSV
  • 确认PSO的像素着色器关联:检查管线状态对象(PSO)是否正确加载了像素着色器字节码,可在PIX中查看PSO的像素着色器配置是否正常。
  • 重新验证视口与裁剪矩形:确保命令列表中调用了RSSetViewports和RSSetScissorRects,且参数覆盖了渲染区域,没有意外剔除像素。
  • 检查顶点输入布局匹配性:确认顶点输入布局的格式、步长与实际传入的顶点数据完全一致,避免因顶点位置解析错误导致输出坐标异常。
  • 分析PIX光栅化统计:在PIX中查看光栅化阶段的像素生成数量,若为0说明顶点虽通过裁剪,但光栅化后无像素生成(如图元完全在视口外、图元面积为0)。
  • 禁用光栅化相关限制:尝试将RasterizerState.DepthClipEnable设为FALSE,同时关闭深度测试(DepthEnable=FALSE),再次测试是否触发像素着色器,排除深度相关问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:10:08