DirectX 使用多个呈现目标作为彼此的输入
DirectX using multiple Render Targets as input to each other
我有一个相当简单的 DirectX 11 框架设置,我想用它来进行各种 2D 模拟。我目前正在尝试在 GPU 上实现 2D 波动方程。它要求我将模拟的网格状态保持在之前的 2 个时间步,以便计算新的时间步。
我是怎么做的 - 我有一个名为 FrameBuffer 的类,它有以下公共方法:
bool Initialize(D3DGraphicsObject* graphicsObject, int width, int height);
void BeginRender(float clearRed, float clearGreen, float clearBlue, float clearAlpha) const;
void EndRender() const;
// Return a pointer to the underlying texture resource
const ID3D11ShaderResourceView* GetTextureResource() const;
在我的主绘制循环中,我有一个包含 3 个缓冲区的数组。每个循环我都使用前 2 个缓冲区中的纹理作为下一个帧缓冲区的输入,并且我还绘制任何用户输入来更改模拟状态。然后我画出结果。
int nextStep = simStep+1;
if (nextStep > 2)
nextStep = 0;
mFrameArray[nextStep]->BeginRender(0.0f,0.0f,0.0f,1.0f);
{
mGraphicsObj->SetZBufferState(false);
mQuad->GetRenderer()->RenderBuffers(d3dGraphicsObj->GetDeviceContext());
ID3D11ShaderResourceView* texArray[2] = { mFrameArray[simStep]->GetTextureResource(),
mFrameArray[prevStep]->GetTextureResource() };
result = mWaveShader->Render(d3dGraphicsObj, mQuad->GetRenderer()->GetIndexCount(), texArray);
if (!result)
return false;
// perform any extra input
I_InputSystem *inputSystem = ServiceProvider::Instance().GetInputSystem();
if (inputSystem->IsMouseLeftDown()) {
int x,y;
inputSystem->GetMousePos(x,y);
int width,height;
mGraphicsObj->GetScreenDimensions(width,height);
float xPos = MapValue((float)x,0.0f,(float)width,-1.0f,1.0f);
float yPos = MapValue((float)y,0.0f,(float)height,-1.0f,1.0f);
mColorQuad->mTransform.position = Vector3f(xPos,-yPos,0);
result = mColorQuad->Render(&viewMatrix,&orthoMatrix);
if (!result)
return false;
}
mGraphicsObj->SetZBufferState(true);
}
mFrameArray[nextStep]->EndRender();
prevStep = simStep;
simStep = nextStep;
ID3D11ShaderResourceView* currTexture = mFrameArray[nextStep]->GetTextureResource();
// Render texture to screen
mGraphicsObj->SetZBufferState(false);
mQuad->SetTexture(currTexture);
result = mQuad->Render(&viewMatrix,&orthoMatrix);
if (!result)
return false;
mGraphicsObj->SetZBufferState(true);
问题是什么都没有发生。我绘制的任何内容都会出现在屏幕上(我使用小四边形绘制(,但实际上没有运行模拟的任何部分。如果需要,我可以提供着色器代码,但我确信它可以工作,因为我之前已经使用相同的算法在 CPU 上实现了这一点。我只是不确定 D3D 渲染目标的工作情况如何,以及我是否只是每一帧都画错了。
编辑 1:下面是帧缓冲区的开始和结束呈现函数的代码:
void D3DFrameBuffer::BeginRender(float clearRed, float clearGreen, float clearBlue, float clearAlpha) const {
ID3D11DeviceContext *context = pD3dGraphicsObject->GetDeviceContext();
context->OMSetRenderTargets(1, &(mRenderTargetView._Myptr), pD3dGraphicsObject->GetDepthStencilView());
float color[4];
// Setup the color to clear the buffer to.
color[0] = clearRed;
color[1] = clearGreen;
color[2] = clearBlue;
color[3] = clearAlpha;
// Clear the back buffer.
context->ClearRenderTargetView(mRenderTargetView.get(), color);
// Clear the depth buffer.
context->ClearDepthStencilView(pD3dGraphicsObject->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0);
void D3DFrameBuffer::EndRender() const {
pD3dGraphicsObject->SetBackBufferRenderTarget();
}
编辑 2 好的,在设置 DirectX 调试层后,我看到我正在使用 SRV 作为渲染目标,而它仍然绑定到着色器之外的像素阶段。在使用波形着色器渲染后,我通过将着色器资源设置为 NULL 来解决此问题,但问题仍然存在 - 实际上没有运行或更新任何内容。我从这里获取了渲染目标代码并稍微修改了它,如果它有任何帮助:http://rastertek.com/dx11tut22.html
好的,据我了解,您需要对纹理进行多通道渲染。
巴西亚卡利,你这样做就像我在这里描述的那样:链接
- 创建同时具有
D3D11_BIND_SHADER_RESOURCE
和D3D11_BIND_RENDER_TARGET
绑定标志的 SRV。 - 从纹理中调用渲染目标
- 将第一个纹理设置为输入 (
*SetShaderResources()
(,将第二个纹理设置为输出 (OMSetRenderTargets()
( - 你
Draw()*
- 然后绑定第二个纹理作为输入,第三个纹理作为输出
-
Draw()*
- 等。
其他建议:
- 如果目标 GPU 能够从非计算着色器写入 UAV,则可以使用它。它更简单,更不容易出错。
- 如果目标 GPU 合适,请考虑使用计算着色器。这是一种享受。
- 不要忘记启用 DirectX 调试层。有时我们会犯明显的错误,调试输出可以指向它们。
- 使用图形调试器在每次绘制调用后查看纹理。
编辑 1:
如我所见,您只调用BeginRender
和OMSetRenderTargets
一次,因此,所有渲染都进入mRenderTargetView
。但你需要的是交错:
SetSRV(texture1);
SetRT(texture2);
Draw();
SetSRV(texture2);
SetRT(texture3);
Draw();
SetSRV(texture3);
SetRT(backBuffer);
Draw();
另外,我们还不知道mRenderTargetView
是什么。
所以,之前
result = mColorQuad->Render(&viewMatrix,&orthoMatrix);
某处必须OMSetRenderTargets
.
也许,最好查看您的Begin()/End()
设计,以使资源绑定更清晰可见。
快乐编码! =(
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 2D数组来自文本输入,中间有空格
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 检查输入是否不是整数或数字
- 正在尝试了解输入验证循环
- 读取文件并输入到矢量中
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何使用用户输入在C++中正确填充2D数组
- C++MySQL C api用户输入行
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- 用户定义函数中的指针和输入
- 如果输入类型与目标类型不同,"cin"变量是否重置为某个默认值?
- Xcode 8.3:使用来自文件的输入运行目标
- Windows SetFocus,目标窗口不会捕获键盘输入
- DirectX 使用多个呈现目标作为彼此的输入
- 目标c-在c++中用指针在类中输入数据