DirectX图像纹理四边形在透明的地方显示基础控件的颜色 [英] DirectX Image texture quad displays underlying controls color where it is transparent

查看:81
本文介绍了DirectX图像纹理四边形在透明的地方显示基础控件的颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正尝试在纹理上绘制纹理,如下图所示。



黄色圆圈图片:



如上面的企鹅图像所示,我正在尝试将另一幅图像渲染为绿色和黄色圆圈所示的纹理。图像在显示紫色的地方是透明的。紫色是在其上绘制纹理的基础控件的颜色。



渲染顺序为:
1.渲染企鹅
2.渲染绿色圆圈
3.渲染黄色圆圈
4.渲染绿色圆圈



现在我不确定为什么我会看到绿色/黄色圆圈图像的紫色?



从测试中发现,如果我没有设置混合因子,而是使用其他图像作为具有alpha值的覆盖图像,则效果很好。因此,当我使用Alpha值为0的图像时,似乎有些事情发生。



我已经尝试了数周才能找出背后的原因,但



任何建议或可以将我引向正确的方向吗?



注意:将Directx11与ShapDx配合使用



PS我还将这个问题发布在另一个论坛上在这里,但到目前为止还没有运气。



编辑:
渲染企鹅后启用blendstate的代码图片为背景

  var renderTargetDesc = new RenderTargetBlendDescription(); 
renderTargetDesc.IsBlendEnabled = true;
renderTargetDesc.SourceBlend = BlendOption.SourceAlpha;
renderTargetDesc.DestinationBlend = BlendOption.InverseSourceAlpha;
renderTargetDesc.BlendOperation = BlendOperation.Add;
renderTargetDesc.SourceAlphaBlend = BlendOption.One;
renderTargetDesc.DestinationAlphaBlend = BlendOption.Zero;
renderTargetDesc.AlphaBlendOperation = BlendOperation.Add;
renderTargetDesc.RenderTargetWriteMask = ColorWriteMaskFlags.All;

BlendStateDescription desc = new BlendStateDescription();
desc.AlphaToCoverageEnable = false;
desc.IndependentBlendEnable = false;

if(m_blendStateEnabled == null)
{
m_blendStateEnabled = new BlendState(m_Dx11Device,desc);
}

desc.RenderTarget [0] = renderTargetDesc;
desc.RenderTarget [1] = renderTargetDesc;

m_Dx11Device.ImmediateContext.OutputMerger.BlendState = m_blendStateEnabled;
m_Dx11Device.ImmediateContext.OutputMerger.BlendFactor = new Color4(0,0,0,0);
m_Dx11Device.ImmediateContext.OutputMerger.BlendSampleMask = 0x0F;

P.S。编辑:
我一直在尝试通过缩小范围来尝试不同的方法,我可以得出混合工作的结论,但是没有达到预期的效果,但是设法缩小了范围。



当尝试在画中画中渲染图像时:



首先,我将一个类中的所有四边形图分开。使用此类,我可以通过调用几个函数来绘制所需数量的对象,其中包括在绘制调用上设置以下内容:

  DxDevice.ImmediateContext.InputAssembler.InputLayout = m_shaderData.InputLayoutConfig; 
DxDevice.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;

SetVertexBuffer();

DxDevice.ImmediateContext.VertexShader.Set(m_shaderData.VertexShaderConfig);
DxDevice.ImmediateContext.PixelShader.Set(m_shaderData.PixelShaderConfig);

DxDevice.ImmediateContext.Draw(4,0);

现在,通过广泛的测试和试验,我发现:


  1. 我有一个四边形绘制对象可以绘制背景,另外一个四边形对象可以绘制标记png。使用这种方法,png会显示实际的控件颜色。

现在,如果我启用AlphaBlending,我得到的只是填充标志png四边形的灰色。也是为此,我尝试更新渲染时采样纹理时返回的rgb颜色:
ShaderTexture.Sample(Sampler,input.TextureUV);
返回的颜色为黑色:r = 1,g = 1,b = 1,a = 1


  1. 如果我重复使用用于绘制背景图像的同一个四边形对象,然后绘制标志png,则将背景图像绘制在代表标志png的四边形中的标志png下方,而我的背景图像不是四边形

现在从上方(在第2点中查找);



任何想法为什么会发生这种情况?

解决方案

好的,我可以使用它。



我使用以下步骤执行:

  var renderTargetDesc = new RenderTargetBlendDescription(); 
renderTargetDesc.IsBlendEnabled = true;
renderTargetDesc.SourceBlend = BlendOption.SourceAlpha;
renderTargetDesc.DestinationBlend = BlendOption.InverseSourceAlpha;
renderTargetDesc.BlendOperation = BlendOperation.Add;
renderTargetDesc.SourceAlphaBlend = BlendOption.Zero;
renderTargetDesc.DestinationAlphaBlend = BlendOption.One;
renderTargetDesc.AlphaBlendOperation = BlendOperation.Add;
renderTargetDesc.RenderTargetWriteMask = ColorWriteMaskFlags.All;

BlendStateDescription desc = new BlendStateDescription();
desc.AlphaToCoverageEnable = false;
desc.IndependentBlendEnable = false;
desc.RenderTarget [0] = renderTargetDesc;

var blendStateEnabled = new BlendState(DxDevice,desc);

var blendFactor = new Color4(0,0,0,0);
var iSampleMask =〜0;
DxDevice.ImmediateContext.OutputMerger.SetBlendState(blendStateEnabled,blendFactor,iSampleMask);

UpdateShaderResource();

DxDevice.ImmediateContext.InputAssembler.InputLayout = m_shaderData.InputLayoutConfig;
DxDevice.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;

SetVertexBuffer();

DxDevice.ImmediateContext.VertexShader.Set(m_shaderData.VertexShaderConfig);
DxDevice.ImmediateContext.PixelShader.Set(m_shaderData.PixelShaderConfig);

DxDevice.ImmediateContext.OutputMerger.BlendState = null;


I'm trying to draw a texture on texture as show in the image below.

Yellow circle Image:

Green circle Image:

As shown in the above image of penguins, i'm trying to render another image as texture which is shown by green and yellow circles. The image is transparent where purple is shown. Purple is color of the underlying control on which the texture is drawn.

The order of rendering is: 1. render penguins 2. Render green circle 3. render yellow circle 4. render green circle

Now I'm not sure as to why i would be seeing the purple for the green/yellow circle images ?

From testing what I've found is that if I don't set the blend factor and use a different image as the overlay image which has an alpha value then it works fine. So it seems there is something going when i use an image which has its alpha value to be 0.

I've been trying to identify the reason behind this for weeks but can't figure it out the reason for it.

Any suggestions or can direct me into the correct direction ?

Note: Using Directx11 with ShapDx

P.S. I've also posted this question on another forum here but having no luck so far.

Edit: Code to enable blendstate after rendering the penguins image which is background

        var renderTargetDesc = new RenderTargetBlendDescription();
        renderTargetDesc.IsBlendEnabled = true;
        renderTargetDesc.SourceBlend = BlendOption.SourceAlpha;
        renderTargetDesc.DestinationBlend = BlendOption.InverseSourceAlpha;
        renderTargetDesc.BlendOperation = BlendOperation.Add;
        renderTargetDesc.SourceAlphaBlend = BlendOption.One;
        renderTargetDesc.DestinationAlphaBlend = BlendOption.Zero;
        renderTargetDesc.AlphaBlendOperation = BlendOperation.Add;
        renderTargetDesc.RenderTargetWriteMask = ColorWriteMaskFlags.All;

        BlendStateDescription desc = new BlendStateDescription();
        desc.AlphaToCoverageEnable = false;
        desc.IndependentBlendEnable = false;

        if (m_blendStateEnabled == null)
        {
            m_blendStateEnabled = new BlendState(m_Dx11Device, desc);
        }

        desc.RenderTarget[0] = renderTargetDesc;
        desc.RenderTarget[1] = renderTargetDesc;

        m_Dx11Device.ImmediateContext.OutputMerger.BlendState = m_blendStateEnabled;
        m_Dx11Device.ImmediateContext.OutputMerger.BlendFactor = new Color4(0, 0, 0, 0);
        m_Dx11Device.ImmediateContext.OutputMerger.BlendSampleMask = 0x0F;

P.S. Edit: I have been trying out different ways by trying to narrowing it down and i can conclude the blending works but not as expected but have managed to narrow things down.

While trying to render images on Picture in Picture:

Firstly, i have separated all the drawing of quads in a class. using this class i can draw as many objects as required with calling a couple of functions including setting the following on a draw call:

DxDevice.ImmediateContext.InputAssembler.InputLayout = m_shaderData.InputLayoutConfig;
DxDevice.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;

SetVertexBuffer();

DxDevice.ImmediateContext.VertexShader.Set(m_shaderData.VertexShaderConfig);
DxDevice.ImmediateContext.PixelShader.Set(m_shaderData.PixelShaderConfig);

DxDevice.ImmediateContext.Draw(4, 0);

Now, from extensive testing and playing around what i have found is:

  1. I have a quad drawing object which draws the background and a separate quad object to draw the flag png. Using this way the png would show the actual controls color.

Now if i enable the AlphaBlending, what i get is just a gray color filling the flag png quad. Also for this i have tried to update the render the rgb colors returned when i sample the texture: ShaderTexture.Sample(Sampler, input.TextureUV); the color returned is black : r=1, g=1, b= 1, a= 1

  1. If i reuse the same quad object that i have used to draw the background image, and then draw the flag png then my background image is drawn underneath the flag png within the quad representing the flag png and my background image is not quad on the bigger quad.

Now from above (finding in point 2.); it seems the blending doesn't work if i draw using a new quad.

Any ideas why this would happen ?

解决方案

OK I got this to work.

I performed using the following steps:

        var renderTargetDesc = new RenderTargetBlendDescription();
        renderTargetDesc.IsBlendEnabled = true;
        renderTargetDesc.SourceBlend = BlendOption.SourceAlpha;
        renderTargetDesc.DestinationBlend = BlendOption.InverseSourceAlpha;
        renderTargetDesc.BlendOperation = BlendOperation.Add;
        renderTargetDesc.SourceAlphaBlend = BlendOption.Zero;
        renderTargetDesc.DestinationAlphaBlend = BlendOption.One;
        renderTargetDesc.AlphaBlendOperation = BlendOperation.Add;
        renderTargetDesc.RenderTargetWriteMask = ColorWriteMaskFlags.All;

        BlendStateDescription desc = new BlendStateDescription();
        desc.AlphaToCoverageEnable = false;
        desc.IndependentBlendEnable = false;
        desc.RenderTarget[0] = renderTargetDesc;

        var blendStateEnabled = new BlendState(DxDevice, desc);

        var blendFactor = new Color4(0, 0, 0, 0);
        var iSampleMask = ~0;
        DxDevice.ImmediateContext.OutputMerger.SetBlendState(blendStateEnabled, blendFactor, iSampleMask);

        UpdateShaderResource();

        DxDevice.ImmediateContext.InputAssembler.InputLayout = m_shaderData.InputLayoutConfig;
        DxDevice.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;

        SetVertexBuffer();

        DxDevice.ImmediateContext.VertexShader.Set(m_shaderData.VertexShaderConfig);
        DxDevice.ImmediateContext.PixelShader.Set(m_shaderData.PixelShaderConfig);

        DxDevice.ImmediateContext.OutputMerger.BlendState = null;

这篇关于DirectX图像纹理四边形在透明的地方显示基础控件的颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆