首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SharpDX/DX11 Alpha混合

SharpDX/DX11 Alpha混合
EN

Stack Overflow用户
提问于 2014-07-23 07:08:59
回答 1查看 2.1K关注 0票数 1

我尝试在SharpDX中使用alpha混合。如果我在输出合并上设置了混合状态,什么都不会呈现,我完全不知道为什么。如果从不设置混合状态,则一切正常。即使我用默认的混合描述设置了混合状态,也不会渲染任何内容。我认为我遗漏了一些步骤,或者我做错了什么,所以我只是粘贴我得到的东西,并希望有人能指出一些东西……

我使用以下代码设置了一个BlendState:

代码语言:javascript
复制
bs = new BlendState(Devices.Device11, new BlendStateDescription());

var blendDesc = new RenderTargetBlendDescription(
    true,
    BlendOption.SourceAlpha,
    BlendOption.InverseSourceAlpha,
    BlendOperation.Add,
    BlendOption.One,
    BlendOption.Zero,
    BlendOperation.Add,
    ColorWriteMaskFlags.All);

bs.Description.RenderTarget[0] = blendDesc;

...and这里是我的渲染循环的内容。如果我所做的只是注释掉context.OutputMerger.SetBlendState(bs),我的网格渲染得很好(没有任何混合,也就是说):

代码语言:javascript
复制
var context = Devices.Device11.ImmediateContext;

context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);
context.ClearRenderTargetView(RenderTargetView, new Color4());

context.OutputMerger.SetTargets(DepthStencilView, RenderTargetView);
context.OutputMerger.SetBlendState(bs);
context.Rasterizer.State = rs;
context.Rasterizer.SetViewport(Viewport);

context.VertexShader.SetConstantBuffer(0, viewProjBuffer);
context.UpdateSubresource(Camera.ViewProjection.ToFloatArray(), viewProjBuffer);

Dictionary<Mesh, Buffer> vBuffers = VertexBuffers.ToDictionary(k => k.Key, v => v.Value);
Dictionary<Mesh, Buffer> iBuffers = IndexBuffers.ToDictionary(k => k.Key, v => v.Value);

foreach (var mesh in vBuffers.Keys)
{
    if (mesh.MeshType == MeshType.LineStrip)
    {
        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;
        context.InputAssembler.InputLayout = Effects.LineEffect.InputLayout;
        context.VertexShader.Set(Effects.LineEffect.VertexShader);
        context.PixelShader.Set(Effects.LineEffect.PixelShader);
    }
    else
    {
        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
        context.InputAssembler.InputLayout = Effects.FaceEffect.InputLayout;
        context.VertexShader.Set(Effects.FaceEffect.VertexShader);
        context.PixelShader.Set(Effects.FaceEffect.PixelShader);
    }

    context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vBuffers[mesh], GetMeshStride(mesh) * 4, 0));
    context.InputAssembler.SetIndexBuffer(iBuffers[mesh], Format.R32_UInt, 0);

    context.DrawIndexed(mesh.IndexUsage, 0, 0);
}

context.ResolveSubresource(RenderTarget, 0, SharedTexture, 0, Format.B8G8R8A8_UNorm);
context.Flush();

我正在渲染一个纹理,它是使用以下纹理描述进行初始化的:

代码语言:javascript
复制
Texture2DDescription colorDesc = new Texture2DDescription
{
    BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
    Format = Format.B8G8R8A8_UNorm,
    Width = width,
    Height = height,
    MipLevels = 1,
    SampleDescription = new SampleDescription(8, 32),
    Usage = ResourceUsage.Default,
    OptionFlags = ResourceOptionFlags.Shared,
    CpuAccessFlags = CpuAccessFlags.None,
    ArraySize = 1
};

渲染到纹理和使用该格式对我来说很重要。我想也许混合可以与特定的格式一起工作,但我找不到任何关于这类内容的信息。

我也是多重采样,这就是为什么我调用ResolveSubresource(...)在我的渲染方法的末尾。除了使用不同的SampleDescription,我要复制到的纹理与RenderTarget具有相同的描述。

说到多重采样,下面是我使用的RasterizerState:

代码语言:javascript
复制
rs = new RasterizerState(Devices.Device11, new RasterizerStateDescription()
{
    FillMode = FillMode.Solid,
    CullMode = CullMode.Back,
    IsFrontCounterClockwise = true,
    DepthBias = 0,
    DepthBiasClamp = 0,
    SlopeScaledDepthBias = 0,
    IsDepthClipEnabled = true,
    IsScissorEnabled = false,
    IsMultisampleEnabled = true,
    IsAntialiasedLineEnabled = true
});

我使用着色器渲染,这基本上是一个"Hello World“着色器加上一个相机矩阵和基本的法线方向照明。我已经验证了我的顶点alpha值是它们应该是的,就像它们被填充到顶点缓冲区中一样……而且,即使我在像素着色器的末尾将它们的alpha硬编码为1,只要我使用该BlendState,我仍然什么也得不到。如果不使用BlendState,则无论alpha值如何,所有内容都会按预期呈现不透明。我甚至尝试在着色器本身中实现混合状态,但似乎没有任何效果。所有的渲染看起来就像根本没有定义混合一样。

如果这很重要,我会在我的设备上使用FeatureLevel.Level.Level_11_0。

不幸的是,这就是我要继续讲的内容。就像我说的,这个问题在这一点上对我来说完全是一个谜。

EN

回答 1

Stack Overflow用户

发布于 2020-06-10 14:11:29

只是想为将来来这里的任何人更新这篇文章。对我有效的方法很简单:

代码语言:javascript
复制
            BlendStateDescription blendStateDescription = new BlendStateDescription
            {
                AlphaToCoverageEnable = false,
            };

            blendStateDescription.RenderTarget[0].IsBlendEnabled = true;
            blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha;
            blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;
            blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add;
            blendStateDescription.RenderTarget[0].SourceAlphaBlend = BlendOption.Zero;
            blendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;
            blendStateDescription.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add;
            blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;

            this._context.OutputMerger.BlendState = new BlendState(_device,blendStateDescription);

我还在我的着色器中处理了alpha组件,以防您想要手动添加透明度到模型,伪代码:

代码语言:javascript
复制
float4 PixelShaderMain( PixelShaderArgs pixelShaderArgs ) 
    : SV_Target
{
    float u = pixelShaderArgs.col.x;
    float v = pixelShaderArgs.col.y;
    float4 color = ShaderTexture.Load(int3(convertUVToPixel(u,v),0));
    return float4(color.r,color.g,color.b,0.5); // 50% transparency
}

希望这对某些人有帮助,而不是得到一个基本上无处可去的死页。祝大家编码愉快!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24899337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档