笔者介绍:姜雪伟,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
}
}
}
见上面代码的粗体部分,这样改动后将其挂到人脸的模型上,再看一下效果:
这样我们就攻克了问题。是不是非常easy?事实上Shader编程没有想象的那么难。仅仅要细心分析就能够得到想要的效果,所以学习Unity Shader编程一定要深入进去。