如何使用预乘alpha实现D3D输出,以便在WPF中与D3DImage一起使用?

如何使用预乘alpha实现D3D输出,以便在WPF中与D3DImage一起使用?,wpf,direct3d,alphablending,Wpf,Direct3d,Alphablending,我们在WPF中使用D3DImage,在WPF中创建的背景上显示使用Direct3D渲染的部分透明3D内容。所以,我们有这样的东西: <UserControl Background="Blue"> <Image> <Image.Source> <D3DImage .../> </Image.Source> </Image> </UserControl

我们在WPF中使用
D3DImage
,在WPF中创建的背景上显示使用Direct3D渲染的部分透明3D内容。所以,我们有这样的东西:

<UserControl Background="Blue">
    <Image>
        <Image.Source>
            <D3DImage .../>
        </Image.Source>
    </Image>
</UserControl>

现在,我们有一个问题,抗锯齿边没有正确显示。我们在一些边缘得到某种白色的“发光”效果,类似于第一张图片中显示的文本周围的效果:

(摘自)

原因是我们从DirectX获得的数据显然不是与alpha通道的预乘。但是WPF和
D3DImage
希望将此作为他们的输入(请参见CodeProject中的“D3D互操作需求简要介绍”一节)

我用C#中的每个像素乘以其alpha值并使用自定义像素着色器来验证这实际上是个问题。结果都很好。但是,我想直接从DirectX获得这个结果


如何直接从DirectX获取预乘数据?我可以在调用
CreateRenderTarget
时指定它吗?我不是DirectX专家,因此请原谅,如果解决方案可能是显而易见的…

为了正确地预乘DirectX内容,您需要自定义ID3D11BlendState。结构应按如下方式设置:

AlphaToCoverageEnable = FALSE;
IndependentBlendEnable = FALSE;
RenderTarget[0].BlendEnable = TRUE;

// dest.rgb = src.rgb * src.a + dest.rgb * (1 - src.a)
RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;

// dest.a = 1 - (1 - src.a) * (1 - dest.a) [the math works out]
RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;

RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
使用创建混合状态,然后将其设置为。然后,只需将Direct3D管道的其余部分设置为正常,渲染目标的输出应具有预乘alpha和正确的alpha通道输出,以便与Direct2D、WPF或任何其他需要预乘内容的API一起使用


请注意,如果使用的是Direct3D 9,则概念相同,但API不同。如果您正在使用9,请寻找一个好的开始位置。

谢谢您的回答!事实上,我们正在使用D3D9(忘了提到这一点),所以我无法使用这段代码,最后我把它交给了一些在D3D方面有更多经验的同事。无论如何,我假设你的答案对D3D11是正确的,所以我会接受它。D3DImage使用D3D9,所以这个答案没有帮助。