众所周知,Unity的前向管线并没有GBuffer可以用,Unity提供通过DepthTextureMode的手段来获取Depth和DepthNormal
实现原理是使用替代shader渲染的方式来获取的:
渲染时机是在正式绘制前进行~
展开可以看到所有的物体用替代shader渲染了一遍。
Depth是使用ShadowCasterPass来生成:
使用时采样宏_CameraDepthTexture即可,Depth大家都很熟了,这里不多说~
而DepthNormalsTexture则是用了一个Hidden属性的Shader来替代,源码地址:
https://github.com/TwoTailsGames/Unity-Built-in-Shaders/blob/master/DefaultResourcesExtra/Internal-DepthNormalsTexture.shader
查看源码可以看到,DepthNormalsTexture是把屏幕空间法线和depth01(近0远1)Encode进一张4通道贴图:
我们从FrameDebuger可以看到4通道如图:
细心如你肯定注意到树叶的透明区域没有裁切掉,我们来找一下原因,看下源代码中TransparentCutout的Subshader:
使用_MainTex的a通道 和Color.a相乘,使用_Cutoff参数来裁切片元。
只需要确保自定的shader符合这个规范,是不是就可以正确渲染处法线?
我们来试试看(这里拿ASE举例):
主帖图命名为MainTex,确保A通道是透明贴图,
拥有Color属性
_Cutoff参数和Clip都符合规范
接下来是见证奇迹的时刻,透明部分的法线正确了。
使用方式:采样_CameraDepthNormalsTexture,然后DecodeDepthNormal
DecodeDepthNormal,生成两张图:
再进一步,如果要树叶进行大幅度的摆动,也需要在shader中写入对应的顶点变换,我们从源码里可以看到有相关的subshader存在。
如果需要定制就可以按照这个方式来改写Internal-DepthNormalsTexture.shader
最后在ProjectSetting里把默认的DepthNormalsshader换为我们改写过的即可。