Unity3D ShaderLab 使用渐变纹理着色
在我们编写着色器的过程中,还可以通过渐变纹理来控制漫反射的光照颜色。这种做法同样在VALVE的军团要塞2中及其流行。
前期,请准备一个渐变色的图片。再把我们之前的Hlf Lambert的代码稍加修改。
1:Properties添加GUI上的图片纹理属性>_RampTex ("Ramp Texture", 2D) = ""
2:在SubShader中申明图片纹理>sampler2D _RampTex;
3:光照模型函数修改>
inline float4 LightingHalfLessDiffuse(SurfaceOutput s,fixed3 lightDir,fixed atten){ float difLight = max(0,dot(s.Normal,lightDir)); float halfLight=difLight*0.5+0.5; float3 ramp = tex2D(_RampTex, float2(0,halfLight)).rgb; float4 col; col.rgb = s.Albedo * _LightColor0.rgb*(ramp); col.a=s.Alpha; return col; }
从上面可以看出,主要就是多了float3 ramp = tex2D(_RampTex, float2(0,halfLight)).rgb;
这一行代码,利用图片计算rgb。最终效果如下,_EmissiveColor,_AmbientColor都是白色哦,结果确实不一样的:
总结看来,关键的tex2D().rgb就是返回了有一个float3的颜色集,这些颜色自然也就是通过tex2D的cg函数获得的,txe2D函数有2个参数,第一个是我们使用的纹理对象,第二个参数是映射纹理的uv坐标。
这时候我们需要的是使用漫反射浮点值来映射到渐变图上的某一个颜色值,最终根据灯光计算后的方向来映射整个渐变纹理到物体表面。所以我们就传入了上面计算获得的halfLight,将它计算为float2类型的纹理像素索引值。
最终的代码如下:
code start---------------------------------------------
Shader "91YGame/BasicMyHalfLessDiffuse" { Properties { _EmissiveColor("Emissive Color",Color) = (1,1,1,1) _AmbientColor("Ambient Color",Color)=(1,1,1,1) _MySliderValue("Slider Value",Range(0,10))=1.3 _RampTex ("Ramp Texture", 2D) = "" } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM //#pragma surface surf Lambert #pragma surface surf HalfLessDiffuse float4 _EmissiveColor; float4 _AmbientColor; float _MySliderValue; sampler2D _RampTex; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { float4 c; c=pow((_EmissiveColor+_AmbientColor),_MySliderValue); o.Albedo = c.rgb; o.Alpha = c.a; } inline float4 LightingHalfLessDiffuse(SurfaceOutput s,fixed3 lightDir,fixed atten){ float difLight = max(0,dot(s.Normal,lightDir)); float halfLight=difLight*0.5+0.5; float3 ramp = tex2D(_RampTex, float2(0,halfLight)).rgb; float4 col; col.rgb = s.Albedo * _LightColor0.rgb*(ramp); col.a=s.Alpha; return col; } ENDCG } FallBack "Diffuse" }
code end-----------------------------------------------