US3S2L10——渐变纹理综合实现
渐变纹理综合实现
接下来将渐变纹理的映射实现融合到之前实现的法线纹理 Shader 内,
这里复用之前实现的 切线空间下的法线纹理 Shader
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
   | Shader "TeachShader/Lesson51" {     Properties     {         _MainColor("MainColor", Color) = (1, 1, 1, 1)         _MainTex("MainTex", 2D) = ""{}         _BumpMap("BumpMap", 2D) = ""{}         _BumpScale("BumpScale", Range(0, 1)) = 1         _SpecularColor("SpecularColor", Color) = (1, 1, 1, 1)         _SpecularNum("SpecularNum", Range(0, 20)) = 18     }     SubShader     {         Pass         {             Tags { "LightMode" = "ForwardBase" }
              CGPROGRAM             #pragma vertex vert             #pragma fragment frag
              #include "UnityCG.cginc"             #include "Lighting.cginc"
              struct v2f             {                 float4 pos: SV_POSITION;                                                   float4 uv: TEXCOORD0;                        float3 lightDir: TEXCOORD1;                  float3 viewDir: TEXCOORD2;               };
              float4 _MainColor;                   sampler2D _MainTex;                  float4 _MainTex_ST;                  sampler2D _BumpMap;                  float4 _BumpMap_ST;                  float _BumpScale;                    float4 _SpecularColor;               fixed _SpecularNum;     
              v2f vert (appdata_full v)             {                 v2f data;                                data.pos = UnityObjectToClipPos(v.vertex);                                    data.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;                 data.uv.zw = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;
                                   float3 binormal = cross(normalize(v.tangent), normalize(v.normal)) * v.tangent.w;                                  float3x3 rotation = float3x3(                     v.tangent.xyz,                       binormal,                            v.normal                         );                                data.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));                    data.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex));    
                  return data;             }
              fixed4 frag (v2f i) : SV_Target             {                 float4 packedNormal = tex2D(_BumpMap, i.uv.zw);                      float3 tangentNormal = UnpackNormal(packedNormal);                                    tangentNormal.xy *= _BumpScale;                                    tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));
                                   fixed3 albedo = tex2D(_MainTex, i.uv.xy).rgb * _MainColor.rgb;  
                                   fixed3 lambertColor = _LightColor0.rgb * albedo.rgb * max(0, dot(tangentNormal, normalize(i.lightDir)));                                  float3 halfA = normalize(normalize(i.viewDir) + normalize(i.lightDir));                      fixed3 specularColor = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0, dot(tangentNormal, halfA)), _SpecularNum);                                  fixed3 color = UNITY_LIGHTMODEL_AMBIENT.rgb * albedo + lambertColor + specularColor;
                  return fixed4(color.rgb, 1);             }             ENDCG         }     } }
   | 
 
然后,修改上述代码的实现,将渐变纹理贴图计算融合到其中
关键点:将原本的兰伯特光照模型修改为渐变纹理的计算方式(半兰伯特光照模型映射渐变纹理颜色)
因此,属性需要添加渐变纹理 _RampTex:
1 2 3 4 5 6 7 8 9 10
   | Properties {     _MainColor("MainColor", Color) = (1, 1, 1, 1)     _MainTex("MainTex", 2D) = ""{}     _BumpMap("BumpMap", 2D) = ""{}     _BumpScale("BumpScale", Range(0, 1)) = 1     _RampTex("_RampTex", 2D) = ""{}     _SpecularColor("SpecularColor", Color) = (1, 1, 1, 1)     _SpecularNum("SpecularNum", Range(0, 20)) = 18 }
   | 
 
同时,片元着色器的漫反射计算部分也要修改为:
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
   | struct v2f {     float4 pos: SV_POSITION;     float4 uv: TEXCOORD0;            float3 lightDir: TEXCOORD1;      float3 viewDir: TEXCOORD2;   };
  float4 _MainColor;       sampler2D _MainTex;      float4 _MainTex_ST;      sampler2D _BumpMap;      float4 _BumpMap_ST;      sampler2D _RampTex;      float4 _RampTex_ST;      float _BumpScale;        float4 _SpecularColor;   fixed _SpecularNum;     
  fixed4 frag (v2f i) : SV_Target {     float4 packedNormal = tex2D(_BumpMap, i.uv.zw);          float3 tangentNormal = UnpackNormal(packedNormal);            tangentNormal.xy *= _BumpScale;                      tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));
           fixed3 albedo = tex2D(_MainTex, i.uv.xy).rgb * _MainColor.rgb;  
           fixed halfLambertNum = dot(tangentNormal, normalize(i.lightDir)) * 0.5 + 0.5;     fixed3 diffuseColor = _LightColor0.rgb * albedo.rgb * tex2D(_RampTex, fixed2(halfLambertNum, halfLambertNum)).rgb;          float3 halfA = normalize(normalize(i.viewDir) + normalize(i.lightDir));          fixed3 specularColor = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0, dot(tangentNormal, halfA)), _SpecularNum);          fixed3 color = UNITY_LIGHTMODEL_AMBIENT.rgb * albedo + diffuseColor + specularColor;
      return fixed4(color.rgb, 1); }
   | 
 
完整 Shader 代码如下:
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
   | Shader "TeachShader/Lesson54" {     Properties     {         _MainColor("MainColor", Color) = (1, 1, 1, 1)         _MainTex("MainTex", 2D) = ""{}         _BumpMap("BumpMap", 2D) = ""{}         _BumpScale("BumpScale", Range(0, 1)) = 1         _RampTex("_RampTex", 2D) = ""{}         _SpecularColor("SpecularColor", Color) = (1, 1, 1, 1)         _SpecularNum("SpecularNum", Range(0, 20)) = 18     }     SubShader     {         Pass         {             Tags { "LightMode" = "ForwardBase" }
              CGPROGRAM             #pragma vertex vert             #pragma fragment frag
              #include "UnityCG.cginc"             #include "Lighting.cginc"
              struct v2f             {                 float4 pos: SV_POSITION;                 float4 uv: TEXCOORD0;                        float3 lightDir: TEXCOORD1;                  float3 viewDir: TEXCOORD2;               };
              float4 _MainColor;                   sampler2D _MainTex;                  float4 _MainTex_ST;                  sampler2D _BumpMap;                  float4 _BumpMap_ST;                  sampler2D _RampTex;                   float4 _RampTex_ST;                  float _BumpScale;                    float4 _SpecularColor;               fixed _SpecularNum;     
              v2f vert (appdata_full v)             {                 v2f data;                                data.pos = UnityObjectToClipPos(v.vertex);                                    data.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;                 data.uv.zw = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;
                                   float3 binormal = cross(normalize(v.tangent), normalize(v.normal)) * v.tangent.w;                                  float3x3 rotation = float3x3(                     v.tangent.xyz,                       binormal,                            v.normal                         );                                data.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));                    data.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex));    
                  return data;             }
              fixed4 frag (v2f i) : SV_Target             {                 float4 packedNormal = tex2D(_BumpMap, i.uv.zw);                      float3 tangentNormal = UnpackNormal(packedNormal);                                    tangentNormal.xy *= _BumpScale;                                    tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));
                                   fixed3 albedo = tex2D(_MainTex, i.uv.xy).rgb * _MainColor.rgb;  
                                   fixed halfLambertNum = dot(tangentNormal, normalize(i.lightDir)) * 0.5 + 0.5;                 fixed3 diffuseColor = _LightColor0.rgb * albedo.rgb * tex2D(_RampTex, fixed2(halfLambertNum, halfLambertNum)).rgb;                                  float3 halfA = normalize(normalize(i.viewDir) + normalize(i.lightDir));                      fixed3 specularColor = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0, dot(tangentNormal, halfA)), _SpecularNum);                                  fixed3 color = UNITY_LIGHTMODEL_AMBIENT.rgb * albedo + diffuseColor + specularColor;
                  return fixed4(color.rgb, 1);             }             ENDCG         }     } }
   | 
 
显示效果(左侧直接使用BlinnPhong光照模型,右侧在BlinnPhong光照模型的基础上半兰伯特光照计算漫反射并使用渐变贴图):

可见,左侧的明暗变化更平滑,较为拟真,而右侧更明暗界线分明一些,更加卡通化