zoukankan      html  css  js  c++  java
  • D3D中Render Target的半透明问题

    因为Alpha混合不一样,d3d渲染物体到RenderTarget再渲染到Screen的过程和把物体直接渲染到Screenbuffer中并不对等。具体为什么不对等,这里说的很详细。这样的话,有些2d游戏需要利用3d渲染的能力实现换装的过程就可能产生下面的一个问题:角色的半透明披风与身体重叠区域B会呈现不正确的半透明状态,露出地表。

    产生这个问题的原因就是2d游戏需要先将3d资源渲染到RenderTarget,然后再应用到已有的2d sprite渲染引擎中;因为渲染到RenderTarget时,如果按照默认的alpha混合方式,D3D会对颜色通道和alpha通道执行相同的混合策略,因此如上图,角色部分会导致B区域被写上Alpha信息,即呈半透明状态。

    解决这个问题的方法是:修改披风的材质,将alpha通道的混合方式独立出来。ms的官方文档这样描述这个策略:Render Target Alpha (Direct3D 9)

    但是设置了alpha单独混合之后还不够,对于alpha通道选取怎样的混合函数则照样会影响结果是否显示正确,经过一些尝试,一个比较好的方法是这样的:

    RenderState.SeparateAlphaBlendEnable = true;
    RenderState.AlphaBlendEnable = true;
    RenderState.SourceBlend = Blend.SourceAlpha; // source rgb * source alpha
    RenderState.AlphaSourceBlend = Blend.One; // don't modify source alpha
    RenderState.DestinationBlend = Blend.InverseSourceAlpha; // dest rgb * (255 - source alpha)
    RenderState.AlphaDestinationBlend = Blend.InverseSourceAlpha; // dest alpha * (255 - source alpha)
    RenderState.BlendFunction = BlendFunction.Add; // add source and dest results

    计算结果相当于:

    A_final = A_src * 1 + (1-A_src)*A_dest;
    R_final = R_src*A_src + (1-A_src)*R_dest;
    G_final = G_src*A_src + (1-A_src)*G_dest;
    B_final = B_src*A_src + (1-A_src)*B_dest;

  • 相关阅读:
    2019.3.18 IP通信基础
    2019.3.11 IP通信基础
    2019.3.7 IP通信基础
    2019.3.4 IP通信基础
    员工贷项目优劣点总结
    mysql事务_事务隔离级别详解
    mysql锁
    mybatis错误——java.io.IOException: Could not find resource com/xxx/xxxMapper.xml
    小问题
    关于char是否能表示一个中文
  • 原文地址:https://www.cnblogs.com/konlil/p/2104528.html
Copyright © 2011-2022 走看看