DirectX 图像纹理四边形在透明处显示底层控件颜色
DirectX Image texture quad displays underlying controls color where it is transparent
我正在尝试在纹理上绘制纹理,如下图所示。
黄圈图片:
绿圈图片:
如上面的企鹅图片所示,我正在尝试将另一张图片渲染为绿色和黄色圆圈所示的纹理。显示紫色的图像是透明的。紫色是绘制纹理的底层控件的颜色。
渲染顺序为:
1.渲染企鹅
2.渲染绿色圆圈
3.渲染黄色圆圈
4. 渲染绿色圆圈
现在我不确定为什么我会看到 green/yellow 圆形图像是紫色的?
通过测试我发现,如果我不设置混合因子并使用不同的图像作为具有 alpha 值的叠加图像,那么它可以正常工作。因此,当我使用 alpha 值为 0 的图像时,似乎有些事情发生了。
几个星期以来,我一直试图找出这背后的原因,但无法弄清楚它的原因。
有什么建议或可以指导我正确的方向吗?
注意:将 Directx11 与 ShapDx 一起使用
P.S。我也在另一个论坛上发布了这个问题 here 但到目前为止没有运气。
编辑:
在渲染作为背景的企鹅图像后启用混合状态的代码
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。编辑:
我一直在尝试通过缩小范围来尝试不同的方法,我可以得出混合工作的结论,但不是预期的那样,但已经设法缩小了范围。
尝试在画中画上渲染图像时:
首先,我把所有四边形的图都分开了class。使用这个 class 我可以通过调用几个函数来绘制尽可能多的对象,包括在绘制调用中设置以下内容:
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);
现在,通过广泛的测试和尝试,我发现:
- 我有一个绘制背景的四边形绘图对象和一个单独的绘制旗帜 png 的四边形对象。使用这种方式,png 将显示实际的控件颜色。
现在,如果我启用 AlphaBlending,我得到的只是填充标志 png 四边形的灰色。同样为此,我尝试更新渲染,当我对纹理进行采样时返回 rgb 颜色:
ShaderTexture.Sample(采样器,input.TextureUV);
返回的颜色是黑色:r=1, g=1, b= 1, a= 1
- 如果我重复使用我用来绘制背景图像的同一个四边形对象,然后绘制旗帜 png,那么我的背景图像将绘制在代表旗帜 png 的四边形内的旗帜 png 下方,我的背景图像是在更大的四边形上没有四边形。
现在从上面(在第 2 点中找到。);如果我使用新的四边形绘制,混合似乎不起作用。
知道为什么会发生这种情况吗?
这是因为当你渲染你的圆圈时,像素alpha也会写入,如果你的最终合成图像必须是不透明的,你可以使用RGBX8表面,或者在混合状态中屏蔽掉alpha通道写入colormask ,并确保将其清除为白色:
renderTargetDesc.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL & ~D3D11_COLOR_WRITE_ENABLE_ALPHA;
好的,我让它工作了。
我执行了以下步骤:
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;
我正在尝试在纹理上绘制纹理,如下图所示。
黄圈图片:
绿圈图片:
如上面的企鹅图片所示,我正在尝试将另一张图片渲染为绿色和黄色圆圈所示的纹理。显示紫色的图像是透明的。紫色是绘制纹理的底层控件的颜色。
渲染顺序为: 1.渲染企鹅 2.渲染绿色圆圈 3.渲染黄色圆圈 4. 渲染绿色圆圈
现在我不确定为什么我会看到 green/yellow 圆形图像是紫色的?
通过测试我发现,如果我不设置混合因子并使用不同的图像作为具有 alpha 值的叠加图像,那么它可以正常工作。因此,当我使用 alpha 值为 0 的图像时,似乎有些事情发生了。
几个星期以来,我一直试图找出这背后的原因,但无法弄清楚它的原因。
有什么建议或可以指导我正确的方向吗?
注意:将 Directx11 与 ShapDx 一起使用
P.S。我也在另一个论坛上发布了这个问题 here 但到目前为止没有运气。
编辑: 在渲染作为背景的企鹅图像后启用混合状态的代码
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。编辑: 我一直在尝试通过缩小范围来尝试不同的方法,我可以得出混合工作的结论,但不是预期的那样,但已经设法缩小了范围。
尝试在画中画上渲染图像时:
首先,我把所有四边形的图都分开了class。使用这个 class 我可以通过调用几个函数来绘制尽可能多的对象,包括在绘制调用中设置以下内容:
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);
现在,通过广泛的测试和尝试,我发现:
- 我有一个绘制背景的四边形绘图对象和一个单独的绘制旗帜 png 的四边形对象。使用这种方式,png 将显示实际的控件颜色。
现在,如果我启用 AlphaBlending,我得到的只是填充标志 png 四边形的灰色。同样为此,我尝试更新渲染,当我对纹理进行采样时返回 rgb 颜色: ShaderTexture.Sample(采样器,input.TextureUV); 返回的颜色是黑色:r=1, g=1, b= 1, a= 1
- 如果我重复使用我用来绘制背景图像的同一个四边形对象,然后绘制旗帜 png,那么我的背景图像将绘制在代表旗帜 png 的四边形内的旗帜 png 下方,我的背景图像是在更大的四边形上没有四边形。
现在从上面(在第 2 点中找到。);如果我使用新的四边形绘制,混合似乎不起作用。
知道为什么会发生这种情况吗?
这是因为当你渲染你的圆圈时,像素alpha也会写入,如果你的最终合成图像必须是不透明的,你可以使用RGBX8表面,或者在混合状态中屏蔽掉alpha通道写入colormask ,并确保将其清除为白色:
renderTargetDesc.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL & ~D3D11_COLOR_WRITE_ENABLE_ALPHA;
好的,我让它工作了。
我执行了以下步骤:
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;