Shader "Custom/MyShader_Diffuse" {
SubShader {
Pass
{
CGPROGRAM
#include "lighting.cginc" //引入_WorldSpaceLightPos0
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
struct output{ //顶点输出
float4 Pos:POSITION;
float4 Col:COLOR;
};
output vert(in float4 ver:POSITION,in float3 verNormal:NORMAL) //输入顶点位置和 法向量
{
output op;
op.Pos = mul(UNITY_MATRIX_MVP,ver); //MVP变换
float3 N = normalize(verNormal); //规范化法向量 变为单位向量
float3 L = normalize(_WorldSpaceLightPos0); //规范化光照向量
//① L = mul(_World2Object,float4(L,0)).xyz; //重要:由于输入的顶点法向量为模型坐标不变,而光照向量为世界坐标也不变
//② N=mul(_Object2World,float4(N,0)).xyz; //故旋转时会光照异常,顶点坐标固定颜色不随光照变化
//解决方案: ①:将光照向量由世界坐标转换到模型坐标
// ②:将顶点法向量由模型坐标变换到世界坐标
N = mul(float4(N,0),_World2Object).xyz; //以上两种方案解决了顶点随光照位置变化的问题
//但是还有一个问题待解决 "若将模型非等比缩放,法向量转换到世界坐标会异常,变化后的法向量将不再垂直于对应的表面"
//解决方案: 将模型法向量 * (((模型到世界变换矩阵)的逆矩阵)的转置矩阵)
// (模型到世界变换矩阵)的逆矩阵 ==> 世界到模型
//(世界到模型)的 转置矩阵 ==> 将CG中 mul()方法的2个参数换位置
//最终得到左边的N
float dot_NL = saturate(dot(N,L));
op.Col = _LightColor0 * dot_NL;
return op;
}
float4 frag(output ipt):COLOR
{
return ipt.Col + UNITY_LIGHTMODEL_AMBIENT;
}
ENDCG
}
}
}
Unity Shader 顶点程序 实现漫反射与法向量的非等比转换
最新推荐文章于 2023-04-12 19:01:01 发布