Direct3D呈现具有“乘”的2D图像。混合模式和alpha [英] Direct3D rendering 2D images with "multiply" blending mode and alpha

查看:190
本文介绍了Direct3D呈现具有“乘”的2D图像。混合模式和alpha的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图复制Photoshop过滤器乘以Direct3D。我一直在阅读和googling关于不同的渲染状态,我已经有效果几乎工作。问题是它忽略了纹理的alpha值。



这里有一个解释这种情况的图片:



http://www.kloonigames.com/petri/stackoverflow_doesnt_allow_.jpg



我发现了一个解决方案,这是保存没有透明度和白色背景的图像。但我不满意这个解决方案。问题是,我真的需要使用alpha值。我想逐渐淡出的图像。如果混合模式忽略alpha值,我不能这样做。



所以问题是如何使用alpha渲染图像?



这里是混合模式代码:

  dev-> SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE); 
dev-> SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ZERO);
dev-> SetRenderState(D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR);



编辑添加了SetTextureStageState $ b

  dev-> SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); 
dev-> SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
dev-> SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
dev-> SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE);


解决方案

您可以通过预乘在像素着色器中,或者通过使用预先乘以alpha的纹理。



例如,如果对着色器有3种可能的混合操作, alpha。

  Blend =(src.rgb * src.a)+(dest.rgb *(1-src。 a))
Add =(src.rgb * src.a)+(dest.rgb)
Multiply =(src.rgb * dest.rgb * src.a)+(dest.rgb * 1-src.a))

你会注意到Multiply是不可能的,是对源颜色的两个操作。但是如果你在渲染器中预渲染alpha,你可以从混合操作中提取alpha分量,并且可以在同一个着色器中混合所有三个操作。



着色器,您可以手动预先alpha。或使用像DirectXTex texconv这样的工具修改纹理。

  return float4(color.rgb * color.a,color.a ); 

操作变为:

  Blend =(src.rgb)+(dest.rgb *(1-src.a))
Add =(src.rgb)+(dest.rgb)
乘=(src.rgb * dest.rgb)+(dest.rgb *(1-src.a))


I'm trying to replicate the Photoshop filter multiply with Direct3D. I've been reading and googling about the different render states and I've got the effect almost working. The problem is that it's ignoring the alpha value of the textures.

Here's an image that explains the sitution:

http://www.kloonigames.com/petri/stackoverflow_doesnt_allow_.jpg

I found one solution to this, which was to save the images with no transparency and white background. But I'm not satisfied with this solution. The problem is that I really need to use the alpha value. I want to fade out the images gradually. And I cannot do this if the blending mode is ignoring the alpha value.

So the question is how to render the images with alpha?

Here's the blending mode code:

dev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);

Edit added the SetTextureStageState

dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
dev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
dev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

解决方案

You can achieve this effect in one step by premultipling alpha in your pixel shader, or by using textures with pre-multiplied alpha.

For example if you have 3 possible blend operations for a shader, and you want each one to take alpha into account.

Blend = ( src.rgb * src.a ) + ( dest.rgb * (1-src.a) )
Add = ( src.rgb * src.a ) + ( dest.rgb )
Multiply = (src.rgb * dest.rgb * src.a) + (dest.rgb * (1-src.a) )

You'll notice that Multiply is impossible with a single pass because there are two operations on the source color. But if you premultiply alpha in your shader you can extract the alpha component from the blending operation and it becomes possible to blend all three operations in the same shader.

In your pixel shader you can pre-multiply alpha manually. Or use a tool like DirectXTex texconv to modify your textures.

return float4(color.rgb*color.a, color.a);

The operations become:

Blend = ( src.rgb ) + ( dest.rgb * (1-src.a) )
Add = ( src.rgb ) + ( dest.rgb )
Multiply = ( src.rgb * dest.rgb ) + (dest.rgb * (1-src.a) )

这篇关于Direct3D呈现具有“乘”的2D图像。混合模式和alpha的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆