笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
CSDN视频网址:http://edu.csdn.net/lecturer/144
大家了解了Shader Forge的制作原理,也会使用Shader Forge制作渲染材质了,在实际项目开发中,我们会遇到各种各样的问题,有时候我们需要使用Shader Forge渲染的物体跟我们自己写的Shader相互配合才能起到作用,在配合的过程中就会遇到问题,下面就把笔者在项目开发中遇到的问题以及解决方案给读者介绍一下。
我们使用Shade Forge渲染了一个金属盔甲,这个金属盔甲里面还有一个透明的人头,渲染效果如下所示:
人脸使用的是带有Alpha通道的Shader处理,在转动的过程中,会出现人脸遮挡不住模型的情况,这样看起来就很怪异,效果如下所示:
上图箭头指示的地方没有被透明的人脸遮挡住,人脸渲染使用的Shader如下所示:
Shader "Unlit/Transparent_Test" { Properties { _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} } SubShader { Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} LOD 100 //ZWrite Off Blend SrcAlpha OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; half2 texcoord : TEXCOORD0; UNITY_FOG_COORDS(1) }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata_t v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.texcoord); UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } } }
这个Shader也是Unity3D自带的Shader,只是修改了一下文件名字,为了能让透明的人脸遮住那半边盔甲,该如何修改?
Unity3D引擎为我们提供了渲染顺序,其实出现这个情况的主要问题也是渲染顺序问题,很明显是先渲染盔甲,再渲染透明的脸。问题找到了,接下来需要修改渲染顺序,就是先渲染透明的人脸材质,再渲染金属盔甲,这样就可以实现遮挡关系了,再原有Shader的基础上修改如下:
Shader "Unlit/Transparent_Test" { Properties { _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} } SubShader { Tags {"Queue"="Transparent-2000" "IgnoreProjector"="True" "RenderType"="Transparent"} LOD 100 //ZWrite Off Blend SrcAlpha OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; half2 texcoord : TEXCOORD0; UNITY_FOG_COORDS(1) }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata_t v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.texcoord); UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } } }
见上面代码的粗体部分,这样修改后将其挂到人脸的模型上,再看一下效果:
这样我们就解决了问题,是不是很简单?其实Shader编程没有想象的那么难,只要细心分析就可以得到想要的效果,所以学习Unity Shader编程一定要深入进去。