You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

DirectX渲染到纹理问题:仅显示背景无内容求助

解决DirectX中Rendering to Texture仅显示背景的问题

嘿,我一眼就发现了你的代码里的核心问题——渲染到纹理的执行顺序完全搞反了!这就是为什么你只能看到背景,看不到预期内容的原因。

先理清楚正确的Render to Texture流程

要把内容渲染到纹理上,必须遵循以下步骤:

  • 切换到目标渲染目标视图(RTV),让后续的绘制操作输出到这个纹理
  • 清除该渲染目标的背景(可选,但通常需要做,避免残留旧内容)
  • 设置好所有必要的渲染状态:图元拓扑、顶点/像素着色器、采样器、着色器资源等
  • 执行绘制调用,把内容画到这个渲染目标上
  • 切换回原来的渲染目标(比如窗口的后台缓冲区)
  • 之后才能使用这个渲染好的纹理(通过SRV)来绘制到屏幕

你的代码哪里错了?

看你的代码片段,顺序完全颠倒了:

  • 你先执行了Draw(4, 0),这时候还没设置自定义RTV,所以绘制内容直接输出到了默认的后台缓冲区
  • 之后你才设置了m_rtv作为渲染目标,紧接着就调用ClearRenderTargetView把它清空——等于这个RTV上根本没绘制任何内容
  • 最后你切换回主渲染目标,再次清空,然后尝试用m_srv[0]绘制,但这个SRV对应的纹理(也就是m_rtv关联的纹理)是空的,自然只能显示背景

修正后的代码示例

我帮你把代码顺序调整成正确的流程:

// --------------------------
// 第一步:渲染到纹理
// --------------------------
// 切换到自定义渲染目标
m_deviceContext->OMSetRenderTargets(1, m_rtv.GetAddressOf(), 0);
// 清除渲染目标背景
m_deviceContext->ClearRenderTargetView(m_rtv.Get(), m_backgroundcolors);
// 设置渲染状态
m_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
m_deviceContext->VSSetShader(m_vertexShader[6].Get(), nullptr, 0);
m_deviceContext->RSSetViewports(1, &m_viewport);
m_deviceContext->PSSetShader(m_pixelShader[3].Get(), nullptr, 0);
m_deviceContext->PSSetSamplers(0, 1, m_samplerState.GetAddressOf());
m_deviceContext->PSSetShaderResources(0, 1, srv); // 这里的srv是你要用来绘制的资源
// 执行绘制,内容会输出到m_rtv对应的纹理上
m_deviceContext->Draw(4, 0);

// --------------------------
// 第二步:把渲染好的纹理绘制到屏幕
// --------------------------
// 切换回窗口的主渲染目标
m_deviceContext->OMSetRenderTargets(1, m_renderTargetView.GetAddressOf(), 0);
// 清除主渲染目标背景
m_deviceContext->ClearRenderTargetView(m_renderTargetView.Get(), m_backgroundcolors);
// 设置绘制全屏四边形的状态,使用刚才渲染好的纹理的SRV
m_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
m_deviceContext->VSSetShader(m_vertexShader[6].Get(), nullptr, 0);
m_deviceContext->RSSetViewports(1, &m_viewport);
m_deviceContext->PSSetShader(m_pixelShader[3].Get(), nullptr, 0);
m_deviceContext->PSSetSamplers(0, 1, m_samplerState.GetAddressOf());
m_deviceContext->PSSetShaderResources(0, 1, m_srv[0].GetAddressOf());
// 绘制全屏四边形,把渲染好的纹理显示到屏幕
m_deviceContext->Draw(4, 0);

// 可选:重置着色器等状态(如果需要的话)
m_deviceContext->VSSetShader(0, 0, 0);
m_deviceContext->GSSetShader(0, 0, 0);
m_deviceContext->PSSetShader(0, 0, 0);

额外的检查点

除了顺序问题,你还可以检查以下几点确保渲染到纹理正常工作:

  • 确认创建渲染目标纹理时,设置了正确的绑定标志:必须包含D3D11_BIND_RENDER_TARGETD3D11_BIND_SHADER_RESOURCE
  • 确认m_srv[0]是从m_rtv关联的同一个纹理资源创建的,没有混淆其他资源
  • 检查视口m_viewport的尺寸是否和渲染目标纹理的尺寸完全匹配,避免绘制内容超出视口范围
  • 验证全屏四边形的顶点数据或顶点着色器是否正确,确保能完全覆盖渲染目标

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

火山引擎 最新活动