1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
| //MARKER:当模型本身有复杂的遮挡关系或者是包含了复杂的非凸网格的时候,纯粹依靠transparent队列来进行排序的方法有可能会因为排序错误产生错误的结果 //MARKER:因此我们可以采用开启深度写入的半透明效果的方法来实现 Shader"Map/MapCell" { Properties{ _InColor("In Color",Color)=(1,1,1,1) _OutColor("Out Color",Color)=(1,1,1,1) _MainTex("Main Tex",2D)="white"{} _OutAlphaScale("Out Alpha Scale",Range(0,1))=1 _InAlphaScale("In Alpha Scale",Range(0,1))=1 _Scale("Out Scale",Range(1,2))=1 //缩放 //_Outline("Outline",Range(0,1))=0.1 //轮廓线宽度 //_OutlineColor("Outline Color",Color)=(0,0,0,1) //轮廓线颜色 //_RimColor("Rim Color",Color)=(1,1,1,1) //边缘颜色 //_RimPower("Rim Power",range(0,10))=2 //边缘强度 //_FresnelColor("FresnelColor",Color)=(1,1,1,1) //_FresnelAmount("FresnelAmount",Range(0,1))=1 //_FresnelPower("FresnelPower",Range(0,5))=5 } //MARKER:SubShader中多PASS的注意点:pass的执行顺序是依据pass在shader中定义的先后顺序来确定的 SubShader{ Tags{"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
//Extra pass that renders to depth buffer only Pass{ ZWrite On ColorMask 0 //MARKER:ColorMask用于设置颜色通道的写掩码(write mask),当ColorMask为0时,意味着该Pass不写入任何颜色通道,即不会输出任何颜色。 //MARKER:写入深度缓冲可以剔除被自身遮挡的片元 } //MARKER:关键在于先通过pass把该模型的深度值写入深度缓冲中;第二个Pass进行正常的透明度混合 //MARKER:由于上一个的pass已经得到了逐像素的正确的深度信息,该pass就可以按照像素级别的深度排序结果进行透明渲染 Pass{ ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM
#pragma vertex vert #pragma fragment frag
fixed3 _OutColor; fixed _Scale; //fixed3 _OutlineColor; fixed _OutAlphaScale; struct appdata { float4 vertex:POSITION; float4 normal:NORMAL; };
struct v2f { float4 pos:SV_POSITION; };
float4x4 Scale(float scale) { return float4x4(scale,0,0,0, 0,scale,0,0, 0,0,0,0, 0,0,0,0); }
v2f vert(appdata v){ v2f o; v.vertex=mul(Scale(_Scale),v.vertex); //SINGAL:这里直接通过乘算来缩放也可以 //v.vertex*=_Scale; o.pos=UnityObjectToClipPos(v.vertex); o.pos.z-=0.0001; //防止zfighting return o; }
fixed4 frag(v2f i):SV_Target{ return fixed4(_OutColor,_OutAlphaScale); } ENDCG } // Pass{ // NAME "OUTLINE" // Cull Front //剔除正面 // // CGPROGRAM // // #pragma vertex vert // #pragma fragment frag // // float _Outline; // fixed3 _OutlineColor; // fixed _AlphaScale; // // struct appdata // { // float4 vertex:POSITION; // float4 normal:NORMAL; // }; // // struct v2f // { // float4 pos:SV_POSITION; // }; // // v2f vert(appdata v){ // //顶点和法线变换到视角空间,达到最好效果 // v2f o; // float4 viewPos=mul(UNITY_MATRIX_MV,v.vertex); // float4 viewNormal=mul(UNITY_MATRIX_IT_MV,v.normal); // viewNormal.z=-0.5;//对法线z分量进行处理,扁平化 // viewPos=viewPos+normalize(viewNormal)*_Outline; // o.pos=mul(UNITY_MATRIX_P,viewPos); //转换到投影空间 // // return o; // } // // fixed4 frag(v2f i):SV_Target{ // return fixed4(_OutlineColor,_AlphaScale); // } // ENDCG // } Pass{ //和8.4节同样的代码 Tags{"LightMode"="ForwardBase"}
//Src(该片元产生的颜色),Dst(已经存在于颜色缓存的颜色) //不开启深度写入 //需要开启颜色混合,调节最后的颜色缓冲输出 ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM
#pragma vertex vert #pragma fragment frag
#include"Lighting.cginc"
//与定义的Properties进行关联 fixed4 _InColor; sampler2D _MainTex; float4 _MainTex_ST; fixed _InAlphaScale; //fixed4 _FresnelColor; //fixed _FresnelAmount; //fixed _FresnelPower; //fixed3 _RimColor; //fixed _RimPower;
//定义顶点着色器 struct a2v { float4 vertex:POSITION; float3 normal:NORMAL; float4 texcoord:TEXCOORD0; //用第一套纹理坐标来初始化texcoord(自身理解的话像是每一个顶点的映射,然后在像素着色阶段时可以是每一个像素的映射) };
struct v2f { float4 pos:SV_POSITION; float3 worldNormal:TEXCOORD0; float3 worldPos:TEXCOORD1; float2 uv:TEXCOORD2; //记录下透明纹理对应的uv坐标 float3 worldViewDir:TEXCOORD3; };
v2f vert(a2v v) { v2f o; //顶点和法线变换到观察空间,达到最好效果 o.pos=UnityObjectToClipPos(v.vertex);
o.worldNormal=UnityObjectToWorldNormal(v.normal);
//MARKER:一定一定注意区分好pos和worldPos的区别,一个是转换到齐次裁剪坐标,一个是采用纹理来记录下顶点世界坐标的位置 o.worldPos=mul(unity_ObjectToWorld,v.vertex);
o.uv=TRANSFORM_TEX(v.texcoord,_MainTex); o.worldViewDir=UnityWorldSpaceViewDir(o.worldPos); return o; }
fixed4 frag(v2f i) : SV_Target { fixed3 worldNormal = normalize(i.worldNormal); fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); fixed4 texColor = tex2D(_MainTex, i.uv); fixed3 albedo = texColor.rgb * _InColor.rgb; fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; fixed3 diffuse = _LightColor0.rgb * albedo * saturate(dot(worldNormal,worldLightDir));
//△ 菲涅尔处理 //float fresnel=_FresnelAmount+(1-_FresnelAmount)*pow((1-max(0,dot(i.worldViewDir,i.worldNormal))),_FresnelPower); //fixed3 color=lerp(ambient+diffuse,_FresnelColor,max(0,fresnel));
//△ 外发光处理 //fixed3 rim=_RimColor*pow(1-saturate(dot(i.worldViewDir,i.worldNormal)),_RimPower); return fixed4(ambient+diffuse, texColor.a * _InAlphaScale); } ENDCG } } }
|