您的位置:首页 > 移动开发 > Unity3D

Unity Shader 顶点程序 实现漫反射与法向量的非等比转换

2015-12-15 12:54 513 查看
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
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: