【UnityShader】渐变纹理
一开始普遍认为渲染中使用纹理是来定义物体的颜色,但后来纹理其实可以存储任何表面属性。
其中就有下文介绍的用渐变纹理来控制漫反射光照的结果。
渐变纹理的关键就在于如何把渐变纹理坐标和漫反射光照联系起来。
这里使用了半兰伯特模型,通过半兰伯特部分的纹理坐标去采样渐变纹理。这样在材质颜色和采样取得的颜色相乘就形成了最终的漫反射光照。
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Custom/Chapter7-RampTexture" { Properties{ _Color("Color Tint",Color) = (1,1,1,1) _RampTex("Ramp Tex",2D) = "white"{} //渐变纹理 _Specular("Specular",Color) = (1,1,1,1) _Gloss("Gloss",Range(8.0,256)) = 20 } SubShader { pass{ Tags{"LightMode" = "ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "Lighting.cginc" fixed4 _Color; sampler2D _RampTex; float4 _RampTex_ST; float _Gloss; fixed4 _Specular; struct a2v{ float4 vertex:POSITION; float3 normal:NORMAL; float4 texcoord:TEXCOORD; }; struct v2f{ float4 pos:SV_POSITION; float3 worldNormal:TEXCOORD0; float3 worldPos:TEXCOORD1; float2 uv:TEXCOORD2; }; v2f vert(a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz; //o.uv = v.texcoord.xy*_RampTex_ST.xy+_RampTex_ST.zw; o.uv = TRANSFORM_TEX(v.texcoord,_RampTex); return o; } fixed4 frag(v2f i):SV_Target{ fixed3 worldNormal = normalize(i.worldNormal); fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; fixed halfLambert = 0.5*dot(worldNormal,worldLightDir)+0.5; fixed3 diffuseColor = tex2D(_RampTex,fixed2(halfLambert,halfLambert)).rgb*_Color.rgb; //用半兰伯特采样,色调和漫反射就挂钩了 渐变纹理只与u方向有关,所以v值可任意 fixed3 diffuse = _LightColor0*diffuseColor; //fixed3 albedo =tex2D(_RampTex,i.uv).rgb*_Color.rgb; //对比采样自身纹理坐标,无法与漫反射联系 //fixed3 diffuse = _LightColor0.rgb*max(0,dot(worldNormal,worldLightDir))*albedo; fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); fixed3 halfDir = normalize(worldLightDir+viewDir); fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0,dot(worldNormal,halfDir)),_Gloss); return fixed4(ambient+diffuse+specular,1.0); } ENDCG } } FallBack "Specular" }