【问题标题】:DirectX 11 Transparency IssueDirectX 11 透明度问题
【发布时间】:2016-06-20 12:05:36
【问题描述】:

我有一个透明背景的 png 文件。

当我绘制图像时,透明度会起作用。

只要它前面没有其他透明图像,如下所示。

我需要对我的透明度代码进行哪些更改才能解决此问题?

深度模板代码:

// Initialize the description of the depth buffer.
ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));

// Set up the description of the depth buffer.
depthBufferDesc.Width = screenWidth;
depthBufferDesc.Height = screenHeight;
depthBufferDesc.MipLevels = 1;
depthBufferDesc.ArraySize = 1;
depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthBufferDesc.SampleDesc.Count = 1;
depthBufferDesc.SampleDesc.Quality = 0;
depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthBufferDesc.CPUAccessFlags = 0;
depthBufferDesc.MiscFlags = 0;

// Create the texture for the depth buffer using the filled out description.
result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);
Error::ErrorCheck(result, TEXT("m_device->CreateTexture2D()"));

// Initialize the description of the stencil state.
ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));

// Set up the description of the stencil state.
depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;

depthStencilDesc.StencilEnable = true;
depthStencilDesc.StencilReadMask = 0xFF;
depthStencilDesc.StencilWriteMask = 0xFF;

// Stencil operations if pixel is front-facing.
depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

// Stencil operations if pixel is back-facing.
depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

// Create the depth stencil state.
result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);
Error::ErrorCheck(result, TEXT("m_device->CreateDepthStencilState()"));

// Set the depth stencil state.
m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 0);

// Initailze the depth stencil view.
ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));

// Set up the depth stencil view description.
depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = 0;

// Create the depth stencil view.
result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView);
Error::ErrorCheck(result, TEXT("m_device->CreateDepthStencilView()"));

// Bind the render target view and depth stencil buffer to the output render pipeline.
m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);

透明码:

//Setup Blend State for transperency
D3D11_BLEND_DESC BlendStateDescription;
ZeroMemory(&BlendStateDescription, sizeof(D3D11_BLEND_DESC));

ID3D11BlendState* blend;

BlendStateDescription.RenderTarget[0].BlendEnable = TRUE;
BlendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
BlendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;

BlendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
BlendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
BlendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
BlendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
BlendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;

m_device->CreateBlendState(&BlendStateDescription, &blend);
float blendFactor[] = { 0, 0, 0, 0 };
UINT sampleMask = 0xffffffff;

m_deviceContext->OMSetBlendState(blend, blendFactor, sampleMask);

【问题讨论】:

  • 你确定透明度在第一种情况下有效吗?可能是 png 的透明部分恰好与您的清晰颜色相匹配(它们都是白色)。
  • 我是,如果我改变背景图像仍然是透明的:)
  • 是否有一个深度缓冲区,写入它并在你的深度模板状态下测试它?
  • 我附上了深度缓冲区代码,这个代码和混合状态代码在设置期间运行一次。

标签: c++ directx transparency directx-11


【解决方案1】:

发现问题。在深度缓冲区中。只需将 depthStencilDesc.DepthFunc 从 D3D11_COMPARISON_LESS 更改为 D3D11_COMPARISON_LESS_EQUAL。

在这里找到答案,点击链接获取更详细的描述: Detailed answer

【讨论】:

  • 问题不是深度缓冲状态;问题是您在渲染透明度时完全修改了深度缓冲区。切换到LESS_EQUAL 可能已经解决了您的直接问题,但是如果您尝试做任何比在同一平面上渲染平面图像更有趣的事情,那么您正在浪费带宽并且可能会遇到更多问题。正如您链接到的答案所建议的那样,您可能应该完全关闭深度,并将透明对象重新渲染到前面。
  • 感谢您的澄清。为什么我不应该启用深度缓冲区是有道理的。但是当您说“将透明对象重新渲染到前面”时,我不能 100% 确定您的意思。您能否更详细地解释一下,以便我理解?
  • 将透明对象正确渲染到单个渲染目标的唯一方法是将它们从相对于相机的最远到最近(即相对于视口从后到前)绘制。有一些高级技术,例如与订单无关的透明度,但它们通常需要额外的中间缓冲区。
  • 啊,我明白了,反正就是这么做的。猜猜我只是关闭深度缓冲区。谢谢。
猜你喜欢
  • 2019-11-03
  • 1970-01-01
  • 2017-09-29
  • 2013-01-24
  • 2013-06-21
  • 2011-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多