本文借鉴《Unity Shader入门精要》,算是对自己学习的总结,也希望分享下所学知识~~
最初纹理是为了定义一个物体的颜色。
纹理也可以存储任何表面属性。
纹理渐变:使用渐变纹理控制漫反射光照的结果。
使用这种方式,可以保证物体的轮廓线相比于之前使用的传统漫反射光照更加明显,而且能够提供多种色调变化。
(现在很多卡通风格都使用了渐变纹理)
原理:
使用半兰伯特模型构建一个纹理坐标,并用这个纹理坐标对渐变纹理进行采样。
因为纵轴方向颜色不变,所以纹理坐标的 u 和 v 都使用了 half 标量。
最后把采样得到的颜色和材质颜色叠加即可。
代码如下:
Shader "RampTexture"
{
Properties
{
_Color ("Color Tint", Color) = (1,1,1,1)
_RampTex ("RampTex", 2D) = "white" {}//渐变纹理
_Specular ("Specular", Color) = (1,1,1,1)
_Gloss("Gloss", Range(8.0, 256)) = 20
}
SubShader
{
Tags { "LightMode" = "ForwardBase" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD0;
float3 worldPos : TEXCOORD1;
};
fixed4 _Color;
sampler2D _RampTex;
float4 _RampTex_ST;
fixed4 _Specular;
float _Gloss;
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal( v.normal );
o.worldPos = mul( unity_ObjectToWorld, v.vertex).xyz;
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;//获取half标量
fixed3 diffuseColor = tex2D(_RampTex, fixed2(halfLambert, halfLambert)).rgb * _Color.rgb;//对渐变纹理采样
fixed3 diffuse = _LightColor0.rgb * diffuseColor;
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"
}
与普通漫反射区别如下:
可以看到明显的渐变效果。