我有一些用OpenGL编写的渲染代码。我使用模板缓冲区来实现剪切:
//Let's assume this is done in render loop.
if(!already_created())
{
create_stencil_attachment_and_bind_to_FB_as_depth_stencil_attachment();
}
glEnable(GL_STENCIL_TEST);
glColorMask(0,0,0,0);
glDepthMask(0);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS,1,1);
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
render_to_stencil();
glColorMask(1,1,1,1);
glDepthMask(1);
glStencilFunc(GL_EQUAL,1,1);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
render_with_clipping();
glDisable(GL_STENCIL_TEST);
现在,问题是,我需要将此代码移植到DX11。我在MSDN上看到了一些示例和一些很好的教程。我最终得到了这个逻辑:
1. Create ID3D11Texture2D with format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT. 2. Create ID3D11DepthStencilState for rendering to stencil: //Let's call it DS_RENDER - For both front and back faces: - op = D3D11_STENCIL_OP_REPLACE for all 3 cases - func = D3D11_COMPARISON_ALWAYS - DepthEnable = FALSE - StencilEnable = TRUE - StencilReadMask = 0xFF - StencilWriteMask = 0xFF 3. Create ID3D11DepthStencilView for state and texture created before. //Let's call it DSV 4. Create ID3D11DepthStencilState for using stencil as 'input': //Let's call it DS_CLIP - For both front and back faces: - op = D3D11_STENCIL_OP_KEEP for all 3 cases - func = D3D11_COMPARISON_EQUAL - DepthEnable = FALSE - StencilEnable = TRUE - StencilReadMask = 0xFF - StencilWriteMask = 0xFF
现在,我不确定如何将模板设置为目标或输入。
MSDN说:
`pDevice->OMSetDepthStencilState(pDSState, 1);`
和
`pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, pDSV);`
如果我正确理解这些调用,首先设置模板状态,而第二个将pDSV绑定为渲染目标的附加“附件”。这是对的吗?
如果是这样,这会像我期望的那样起作用吗?
pDevice->OMSetDepthStencilState(DS_RENDER, 1);
pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, DSV);
render_geometry_to_stencil_buffer();
pDevice->OMSetDepthStencilState(DS_CLIP, 1);
render_geometry_with_clipping();
pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, NULL); //Does this disable stencil testing?
提前感谢您的每一个帮助或有用的提示。
答案 0 :(得分:1)
如果您只想渲染模具,请使用(设置您的写入状态):
pd3dDeviceContext->OMSetRenderTargets(0, NULL, DSV);
您无需渲染到颜色缓冲区,因此无需绑定它。
然后,要渲染到目标并启用模板测试,请使用:
pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, DSV);
当你使用模板作为输入时,一个非常简单的事情也是设置StencilWriteMask = 0; 因此它永远不会写入它(这是你想要渲染剪裁的几何体)。
如果您使用:
pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, NULL);
您确实会禁用任何形式的深度/模板测试(不再有深度限制,因此DepthStencilState根本不起作用)。
另外,我会使用DXGI_FORMAT_D24_UNORM_S8_UINT作为深度格式(个人偏好),它将完全适合您的用例并消耗更少的内存。
希望有所帮助。