Screen-door transparency (also called screen space stipple, stipple patterns, dissolve, fizzle, etc.) 是一种利用alpha testing来实现半透明融合的技术
参考:
http://digitalrune.github.io/DigitalRune-Documentation/html/fa431d48-b457-4c70-a590-d44b0840ab1e.htm

优点:

  1. 对老显卡友好,几乎支持所有Pixel Shader环境
  2. 是opaque渲染,效率比传统alpha blend高
  3. 不需要z深度排序
  4. 可以实现半透明影子

缺点:

  1. 抖动色,有杂点
    在这里插入图片描述

实现原理就是每4x4个像素做alpha权重表,当像素的alpha值小于权重值,就剔除该像素渲染
VS中需要将VS Output中的POSITION声明为SV_Position,这样在PS中就可以直接取出像素位置坐标

struct VS_OUTPUT
{
	float4 Pos : SV_Position;
	...
};

VS中正常变换到World、View、Projection空间

VS_OUTPUT VSFunc( VS_INPUT In )
{
    COLOR_VS_OUTPUT Output;
	float4 PosWS = mul(In.Pos, g_World);
	Output.Pos = mul(PosWS, g_ViewProj);
	...
    return Output;    
}

PS中提前判断像素alpha,这里的alpha可以是In.Color.w整体半透明,也可以是tex2D(DiffuseTextureSampler, In.Tex0)采样后获得的贴图alpha(树叶、头发用这种方式)

float4 PSFunc( COLOR_VS_OUTPUT In ) : COLOR0
{ 
	float4x4 thresholdMatrix =
	{
		1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
		13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
		4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
		16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
	};
	clip(In.Color.w - thresholdMatrix[In.Pos.x % 4][In.Pos.y % 4]);
	...
}

Unity中LOD融合,也采用这种方式,参见:
Editor\Data\CGIncludes\UnityCG.cginc

#ifdef LOD_FADE_CROSSFADE
    #define UNITY_APPLY_DITHER_CROSSFADE(vpos)  UnityApplyDitherCrossFade(vpos)
    sampler2D unity_DitherMask;
    void UnityApplyDitherCrossFade(float2 vpos)
    {
        vpos /= 4; // the dither mask texture is 4x4
        float mask = tex2D(unity_DitherMask, vpos).a;
        float sgn = unity_LODFade.x > 0 ? 1.0f : -1.0f;
        clip(unity_LODFade.x - mask * sgn);
    }
#else
    #define UNITY_APPLY_DITHER_CROSSFADE(vpos)
#endif

《原神》的角色靠近相机时的融出表现
在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐