DX9下Off-Screen Particles的问题?

在普通情况下,三次 alpha blend 后:
P3 = D(1-A1)(1-A2)(1-A3) + S1A1(1-A2)(1-A3) + S2A2(1-A3) + S3A3
在渲染 off screen particle 时,将 particle 渲染到一张分辨率较小的,背景色是黑色的(alpha 通道是白色)的 render target 上,这样颜色通道就是:
S1A1(1-A2)(1-A3) + S2A2(1-A3) + S3A3
为了保存(1-A1)(1-A2)(1-A3),需要在每次 alpha blend 的时候将这个写到 alpha 通道,所以要:
AlphaBlendEnable = true;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
SeparateAlphaBlendEnable = true;
SrcBlendAlpha = Zero;
DestBlendAlpha = InvSrcAlpha;
这样每次 alpha blend,就会把 1-A 累积到那个 render target 的 alpha 通道。
最后把 off screen 的 render target 混合回场景的时候,用:
AlphaBlendEnable = true;
SrcBlend = One;
DestBlend = SrcAlpha;
就可以了。
=============================================
【DX9下Off-Screen Particles的问题?】 另外文中只是介绍了 P = D(1-A) + SA 这种 alpha blend 形式的处理,对于 P = D + SA 这种(additive blending,一般用于火焰)形式,如果也想把这种混合方式融合到上述情况,需要:
1. 在 shader 最后输出的时候,不是 float4( color.rgb, alpha), 而是 float4( color.rgb * alpha, alpha),对于 additive blending,输出用 float4( color.rgb * alpha, 0 )
2. 在每次混合的时候,用:
AlphaBlendEnable = true;
SrcBlend = One;
DestBlend = InvSrcAlpha;
SeparateAlphaBlendEnable = true;
SrcBlendAlpha = Zero;
DestBlendAlpha = InvSrcAlpha;
3. 在最后将 off screen target 混合回场景的时候,还是用:
AlphaBlendEnable = true;
SrcBlend = One;
DestBlend = SrcAlpha;

■网友
查了下sdk,可以通过开启D3DRS_SEPARATEALPHABLENDENABLE来对alpha通道单独混合。这样应该可以解决这个问题。


    推荐阅读