【问题标题】:How does D3D11 render pixels with an alpha value of 0 in the texture as transparent?D3D11如何将纹理中alpha值为0的像素渲染为透明?
【发布时间】:2021-02-14 08:11:25
【问题描述】:
  • 我使用 DrawIconEx(GDI/D3D11 互操作性和 CopyResource)生成了一个 ID3D11Texture2D,它有许多 alpha 通道值为 0 的像素。此纹理已通过 D3D11_USAGE_STAGING/Map 验证以查看像素值和ScreenGrab保存 png (相关代码需要修改:DXGI_FORMAT_B8G8R8A8_UNORM->使用GUID_WICPixelFormat32bppBGRA代替GUID_WICPixelFormat24bppBGR)。

  • 当我使用Tutorial 5: Texturing的渲染纹理方法时,0像素的alpha值会被渲染为黑色,这不是我想要的,我希望这些像素渲染是透明的。将采取什么措施来实现目标?这是我的相关代码:

     HRESULT CGraphRender::Init()
     {
         ...
    
         // Create an alpha enabled blend state description.
         _blend_state = nullptr;
    
         D3D11_BLEND_DESC blendDesc;
         ZeroMemory(&blendDesc, sizeof(D3D11_BLEND_DESC));
    
         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_ONE;
         blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
         blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
         blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
    
         hr = _d3d_device->CreateBlendState(&blendDesc, &_blend_state);
         RETURN_ON_FAIL(hr);
    
         ....
     }
    
     HRESULT CGraphRender::Clear_3D(float color[])
     {
         ID3D11RenderTargetView* rtv[] = { _back_rendertarget_view };
         _immediate_context->OMSetRenderTargets(_countof(rtv), rtv, nullptr);
         _immediate_context->ClearRenderTargetView(_back_rendertarget_view, color);
    
         float blendFactor[4] = { 1.f, 1.f, 1.f, 1.f };
         _immediate_context->OMSetBlendState(_blend_state, blendFactor, 0xffffffff);
    
         return S_OK;
     }
    

【问题讨论】:

    标签: winapi gdi direct3d direct3d11


    【解决方案1】:

    问题已解决:在渲染“alpha”纹理之前执行OMGetBlendState(_blend_state...设置,渲染后恢复默认的blendstate

    HRESULT CGraphRender::DrawTexture(const std::shared_ptr<CDrawTextureShader>& texture, const RECT& dst_rect, const BOOL& is_blend_alpha)
    {
        CComPtr<ID3D11DeviceContext> immediate_context;
        _d3d_device->GetImmediateContext(&immediate_context);
        if (!immediate_context)
        {
            return E_UNEXPECTED;
        }
    
        if (is_blend_alpha)
        {
            CComPtr<ID3D11BlendState> old_blend_state;
            FLOAT   old_blend_factor[4] = { 0.f };
            UINT    old_sample_mask = 0;
    
            immediate_context->OMGetBlendState(&old_blend_state, old_blend_factor, &old_sample_mask);
    
            float blend_factor[4] = { 1.f, 1.f, 1.f, 1.f };
            immediate_context->OMSetBlendState(_blend_state, blend_factor, 0xffffffff);
    
            HRESULT hr = texture->Render(immediate_context, dst_rect);
    
            immediate_context->OMSetBlendState(old_blend_state, old_blend_factor, old_sample_mask);
    
            return hr;
        }
        else
        {
            return texture->Render(immediate_context, dst_rect);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-21
      • 1970-01-01
      • 2017-08-16
      • 1970-01-01
      • 2018-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多