我们需要做的第一件事就是指出我们的着色器确实需要传递给它的光照信息。Unity 的渲染管线支持各种渲染方式;这里我们将使用默认的前向渲染。
我们首先只支持一个方向光。Unity 中的前向渲染的工作方式是在一个名为 ForwardBase 的单个通道中渲染主方向光、环境光、光照贴图和反射。在着色器中,通过添加以下通道标签来指示这一情况:__Tags {“LightMode”=“ForwardBase”}__。这将使方向光数据通过一些内置变量传入着色器。
以下着色器为每个顶点计算简单漫射光照,并使用单个主纹理:
Shader "Lit/Simple Diffuse"
{
Properties
{
[NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Pass
{
// indicate that our pass is the "base" pass in forward
// rendering pipeline. It gets ambient and main directional
// light data set up; light direction in _WorldSpaceLightPos0
// and color in _LightColor0
Tags {"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" // for UnityObjectToWorldNormal
#include "UnityLightingCommon.cginc" // for _LightColor0
struct v2f
{
float2 uv : TEXCOORD0;
fixed4 diff : COLOR0; // diffuse lighting color
float4 vertex : SV_POSITION;
};
v2f vert (appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
// get vertex normal in world space
half3 worldNormal = UnityObjectToWorldNormal(v.normal);
// dot product between normal and light direction for
// standard diffuse (Lambert) lighting
half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz));
// factor in the light color
o.diff = nl * _LightColor0;
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target
{
// sample texture
fixed4 col = tex2D(_MainTex, i.uv);
// multiply by lighting
col *= i.diff;
return col;
}
ENDCG
}
}
}
这使得对象对光线方向作出反应:面向光源的部分获得光照,而背向的部分完全没有光照。