我们在WPF中使用D3DImage来显示使用Direct3D在WPF中创建的背景上呈现的部分透明的3D内容。所以,我们有这样的东西
<UserControl Background="Blue">
<Image>
<Image.Source>
<D3DImage .../>
</Image.Source>
</Image>
</UserControl>现在,我们有一个问题,即反锯齿边缘没有正确显示.我们在一些边缘得到了某种白色的“发光”效果,类似于第一张图片中所显示的文本周围的效果:

(取自matting.php)
原因是我们从DirectX获得的数据显然不是与alpha通道相乘的。但是WPF和D3DImage期望这是它们的输入(参见“D3DImage简介” on CodeProject,“简要介绍D3D互操作需求”一节)。
我通过在C#中将每个像素乘以其alpha值并使用自定义像素着色器验证了这一点。结果都很好。但是,我想直接从DirectX获得这个结果。
如何直接从DirectX获得预乘数据?我可以在对CreateRenderTarget的调用中指定它吗?我不是DirectX专家,所以请原谅这个解决方案可能是显而易见的.
发布于 2013-09-24 04:22:16
为了使您的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;用ID3D11设备::CreateBlendState创建混合状态,然后用ID3D11DeviceContext:OMSetBlendState设置它。然后,只需将Direct3D管道的其余部分设置为正常,到呈现目标的输出应该具有正确的alpha通道输出,以便与Direct2D、WPF或任何其他需要预乘内容的API一起使用。
注意,如果您使用的是Direct3D 9,那么概念是相同的,但是API是不同的。如果您使用的是9,请查看这里以找到一个开始的好地方。
https://stackoverflow.com/questions/18918643
复制相似问题