UnityShader案例(六)——渐变纹理

来源:互联网 发布:淘宝面试问题及答案 编辑:程序博客网 时间:2024/06/04 23:22

一、使用渐变纹理控制漫反射光的结果

Shader "Custom/Texture/RampTexture"{    Properties    {        _Color("Color",Color)=(1,1,1,1)        _RampTex ("RampTexture", 2D) = "white" {}        _Specular("Specular",Color)=(1,1,1,1)        _Gloss("Gloss",Range(8.0,256))=20    }    SubShader    {        Tags { "RenderType"="Opaque" }        LOD 100        Pass        {            Tags{"LightMode"="ForwardBase"}            CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"            #include "Lighting.cginc"            fixed4 _Color;            sampler2D _RampTex;            float4 _RampTex_ST;            float4 _Specular;            float _Gloss;            struct appdata            {                float4 vertex : POSITION;                float4 uv : TEXCOORD0;                float3 normal:NORMAL;            };            struct v2f            {                float4 vertex :SV_POSITION;                float2 uv : TEXCOORD0;                float3 worldNormal:TEXCOORD2;                float3 worldPos:TEXCOORD1;            };            v2f vert (appdata v)            {                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                o.uv = TRANSFORM_TEX(v.uv, _RampTex);                o.worldNormal=UnityObjectToWorldNormal(v.normal);                o.worldPos=mul(unity_ObjectToWorld,v.vertex);                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 halfLambent=0.5*dot(worldLightDir,worldNormal)+0.5;                //提取对于位置渐变纹理中中的像素颜色                fixed3 diffuseColor = tex2D(_RampTex,fixed2(halfLambent,halfLambent)).rgb * _Color.rgb;                fixed3 diffuse=_LightColor0.rgb*diffuseColor.rgb;                fixed3 viewDir=normalize(UnityWorldSpaceViewDir(i.worldPos));                fixed3 halfDir=normalize(viewDir+worldNormal);                fixed3 specular=_LightColor0.rgb*_Specular.rgb*pow(max(0,dot(worldNormal,halfDir)),_Gloss);                return  fixed4(ambient+diffuse+specular,1.0);            }            ENDCG        }    }    Fallback "Specular"}

本案例中使用的渐变纹理:
这里写图片描述

这里写图片描述

二、代码详解

本案例中对漫反射反射光的求解用的是半兰伯特模型,通过对法线方向和光照方向的点解做一次0.5倍的缩放以及一个0.5倍大小的偏移来计算半兰伯特部分。这样得到的halfLambert的范围被映射到了[0,1]之间,之后,我们使用halfLambert来构建一个纹理坐标,并用这个纹理坐标对渐变纹理_RampTex进行采样。由于_RampTex
实际就是一个一维的纹理(它在纵坐标的方向轴上颜色不变),因此纹理的坐标的u和V方向我们使用了halfLambert。然后把从渐变纹理采样得到的颜色和材质的_Color相乘,得到最终的漫反射颜色。剩下的就是计算环境光和高光反色,前几节已详细介绍了方法。