法向量 :垂直于平面的向量 ; float3 N = normalize(v.normal);
得到顶点到光源的向量 :_WorldSpaceLightPos0; float3 L = normalize(_WorldSpaceLightPos0);
环境光的设置 :
window --> lighting --> Ambient Source :把skybox改为color,就可以通过改变颜色从而改变环境光照的颜色
Shader "Custom/MyDiffuse" {
SubShader
{
Pass
{
Tags { "LightMode" = "ForwardBase" } // 加这个标签,才可以支持顶点光照
CGPROGRAM
#pragma multi_compile_fwdbase // multi_compile 表示支持多版本编译,fwdbase表示带有forwardbase标签
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc"
#include "lighting.cginc"
struct v2f {
float4 pos : POSITION;
fixed4 color : COLOR;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP , v.vertex);
float3 N = normalize(v.normal); // 法向量在模型坐标系中
float3 L = normalize(_WorldSpaceLightPos0); // 在世界坐标系中得到顶点到光源的向量
// 必须要保证N、L在同一个坐标系中,_World2Object (世界坐标系转换为模型坐标系)、_Object2World(模型坐标系转换为世界坐标系),这两个矩阵互为逆矩阵
N = mul(float4(N , 0), _World2Object).xyz;
N = normalize(N);
// L = mul(_World2Object , float4(L , 0)).xyz; // 两种操作,任选一种即可
float ndotl = saturate(dot(N , L));
o.color = _LightColor0 * ndotl; // 光线颜色
// 假设有多个光源在场景中同时作用
float3 wpos = mul(_Object2World , v.vertex).xyz; // 顶点在世界坐标系中的位置
o.color.rgb += Shade4PointLights (unity_4LightPosX0 , unity_4LightPosY0 , unity_4LightPosZ0 ,
unity_LightColor[0].rgb , unity_LightColor[1].rgb , unity_LightColor[2].rgb , unity_LightColor[3].rgb ,
unity_4LightAtten0 ,
wpos , N ) ;
}
fixed4 frag(v2f IN) : COLOR
{
return IN.color + UNITY_LIGHTMODEL_AMBIENT ; // 加上环境光的效果
}
}
}
}
场景中有多个灯光一同作用时,混合计算光照,研究Forward Rendering Path Details (前向渲染路径)
灯光的Render Mode :Auto 自动
Important :逐像素的方式进行渲染
Not Important :多数情况下逐顶点方式进行渲染
例 :假如加入一个点光源进场景中
1、使用辅助光照函数ShadeVertexLightsFull :
float3 ShadeVertexLightsFull (float4 vertex , float3 normal , int LightCount , bool spotlight) { }
// 处理全部的顶点光照,此函数只能使用在标签为 "Vertex"的pass通道中 : tags { "LightMode" = "Vertex" }
2、ShadeVertexLightsFull函数的包装函数ShadeVertexLights :
float3 ShadeVertexLights (float4 vertex , float3 normal ){
return ShadeVertexLightsFull(vertex , normal , 4 , false);
}
直接使用这个函数,对颜色赋值 :
o.color.rgb = ShadeVertexLights(v.vertex , v.normal);
执行完此操作。点光源的作用效果已显现出来,但是效果与Unity自带的diffuse效果不同,因为此时 Tags是 "Vertex",而我们需要的标签是 "ForwardBase" ,所以,为了实现多个光源在场景中共同作用,需要使用辅助函数 :Shade4PointLights
3、辅助函数ShadePointLights,参数列表 :
float4 LightPosX , float4 LightPosY , float4 LightPosZ,
float3 LightColor0 , float3 LightColor1 , float3 LightColor2 , float3 LightColor3,
float4 LightAttensq,(光的衰减系数)
float3 pos,(顶点在世界坐标系中的位置)
float3 normal(顶点在世界坐标系中的法向量)
在使用这个方法时,可以使用Shader中自带的一些变量。
o.color.rgb += Shade4PointLights(
unity_4LightPosX0 , unity_4LightPosY0 , unity_4LightPosZ0 , // unity shader中自带的位置
unity_LightColor[0].rgb , unity_LightColor[1].rgb , unity_LightColor[2].rgb , unity_LightColor[3].rgb, // 自带的四维的拥有8个元素的数组
unity_4LightAtten0 , //以上都是Shader中自带的变量
wpos , N
)