SharpDX/DX11 Alpha Blend
本文关键字:Blend Alpha DX11 SharpDX | 更新日期: 2023-09-27 18:14:09
我正在尝试使用alpha与SharpDX混合。如果我在输出合并中设置混合状态,那么什么都不会呈现,而且我完全不知道为什么。当不设置混合状态时,一切工作正常。即使我用默认的混合描述设置了一个混合状态,也没有渲染。我想我遗漏了一些步骤,或者我做的顺序不对,所以我就把我得到的粘贴起来,希望有人能指出来。
我有一个BlendState设置使用以下代码:
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;
…这是我的渲染循环的内容。如果我所做的只是注释掉context. outputmerge . setblendstate (bs),我的网格渲染得很好(没有任何混合):
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();
我正在渲染一个纹理,它是使用以下纹理描述初始化的:
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(…)在我的渲染方法结束。我要复制的纹理具有与RenderTarget相同的描述,除了不同的SampleDescription。
说到多采样,这是我正在使用的RasterizerState:
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值如何,所有内容都按照预期呈现不透明。我甚至尝试在着色器本身实现混合状态,但这似乎没有任何影响。一切看起来都像没有定义混合一样。
如果它很重要,我使用featureleel . level。Level_11_0 with my Device.
不幸的是,这是我必须继续。就像我说的,这个问题在这一点上对我来说完全是个谜。
只是想为将来来这里的任何人更新一下。对我有用的方法很简单:
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组件在我的着色器,以及,如果你想手动添加透明度的模型,伪代码:
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
}
希望这能帮助别人,而不是得到一个基本上没有指向的死页。祝大家编码快乐!