【问题标题】:Render to texture, but how to save it with transparency using DirectX?渲染到纹理,但如何使用 DirectX 以透明度保存它?
【发布时间】:2012-12-25 20:03:39
【问题描述】:

我正在使用 DirectX 11 SDK 并为纹理渲染一些东西(它的工作原理)。比使用 D3DX11SaveTextureToFile 将输出保存到 PNG 纹理。一切正常,但我没有得到透明度。

我想要背景(没有呈现任何元素的空间)透明。而不是这个,我得到了一些背景。

我试图将 ClearRenderTargetView 函数的 float ClearColor[4] 更改为 { 0.0f, 0.0f, 0.0f, 1.0f },因为我认为最后一个是 alpha 和 1.0f 给我透明度,但那没有t 对我有用(0.0f 也一样)。

这是我的代码中可能有用的部分:

混合状态(我认为这很好,它们适用于在屏幕上渲染透明元素 - 当然监视器的屏幕总是有一些“背景”,PNG文件没有):

D3D11_BLEND_DESC blendDesc;
ZeroMemory(&blendDesc, sizeof(D3D11_BLEND_DESC) );
blendDesc.AlphaToCoverageEnable = false;
blendDesc.IndependentBlendEnable = false;        
blendDesc.RenderTarget[0].BlendEnable = true;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;

blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; 
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; 
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL ;

ID3D11BlendState * blendState;

if(FAILED(device->CreateBlendState(&blendDesc, &blendState))){
        //...
}

g_pImmediateContext->OMSetBlendState(blendState,NULL,0xffffffff);

还有:

// Setup the render target texture description.
textureDesc.Width = textureWidth;
textureDesc.Height = textureHeight;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;    
...
//Create the render target texture.
result = device->CreateTexture2D(&textureDesc, NULL, &renderTargetTexture);  
...
result = device->CreateShaderResourceView(renderTargetTexture, 
    &shaderResourceViewDesc, &shaderResourceView);  
...
g_pImmediateContext->OMSetRenderTargets(1, &renderTargetView, 
    g_pDepthStencilView);
float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; //red, green, blue, alpha
g_pImmediateContext->ClearRenderTargetView( renderTargetView, ClearColor );

//clear the depth buffer to 1.0 (max depth)
g_pImmediateContext->ClearDepthStencilView( g_pDepthStencilView, 
    D3D11_CLEAR_DEPTH, 1.0f, 0 ); 
...
//render here
...
D3DX11SaveTextureToFile(g_pImmediateContext, renderTargetTexture, 
    D3DX11_IFF_BMP, CommonFunctions::s2ws(newTextureName).c_str());

【问题讨论】:

  • 阿尔法的工作方式相反。 0.0f 代表完全透明,1.0f 代表完全可见。 (阿尔法值 = 不透明度)

标签: directx png transparency render-to-texture


【解决方案1】:

如果要保存 PNG 文件,请使用 D3DX11_IFF_PNG 而不是 D3DX11_IFF_BMP


正如 PolGraphic 在他的评论中提到的,可能需要将混合状态从 D3D11_BLEND_SRC_ALPHA 和 D3D11_BLEND_INV_SRC_ALPHA 更改为适用于 PNG 的 D3D11_BLEND_ONE。但是,在大多数情况下,默认设置 SRC_ALPHA / INV_SRC_ALPHA 应该可以工作。

【讨论】:

  • 我试过了,但我根本没有得到我的图像。图像的一半和透明背景上只有一个黑色矩形。更奇怪的是,矩形出现在应该有透明背景(没有元素)的地方,而透明的是有物体的地方。
  • 你确定你有正确的混合状态吗?并确保清除到 (0,0,0,0)。
  • 感谢混合状态。从 D3D11_BLEND_SRC_ALPHA 和 D3D11_BLEND_INV_SRC_ALPHA 更改为 D3D11_BLEND_ONE 适用于 PNG!但在场景中我得到半透明的所有对象。不知道为什么,但我必须使用不同的混合状态来渲染 PNG 和场景。您可以编辑您的答案并在那里放置有关混合状态的信息吗?读者会更清楚,因为最终答案现在部分在评论中;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 2017-08-16
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
相关资源
最近更新 更多