光照模型就是一个公式,使用这个公式来计算在某个点的光照效果。
标准光照模型-光的分类
●自发光
●高光反射 Specular
●漫反射 Diffuse=直射光的颜色 * max(0,cos夹角(光和法线的夹角)) cosi =光方向 · 法线方向
●环境光
只有定义了正确的LightMode与引用这个光照文件才能得到unity的内置光照变量:
Tags("LightMode"="ForwardBase")
#include "Lighting.cgnic"
代码如下:
Shader "BanMing/DiffuseVertex" {
SubShader
{
Pass
{
Tags{"LightMode"="ForwardBase"}//光照标签
CGPROGRAM
//引入光照文件
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
struct a2v {
float4 vertex:POSITION;//告诉unity把模型空间下的顶点坐标填充给vertex
fixed3 normal :NORMAL;
};
struct v2f{
float4 position :SV_POSITION;
float3 color:COLOR;
};
v2f vert(a2v v){
v2f f;
f.position=mul(UNITY_MATRIX_MVP,v.vertex);
//坐标转换可以使用mul()中间带入参数unity_WorldToObject,同时也可以使用UnityObjectToWorldDir这个方法来调用
// fixed3 normalDir=normalize(mul(v.normal,(float3x3)unity_WorldToObject));
//漫反射公式 :光照颜色*(cos(法线与光照夹角))
//这里求角度使用到了点乘,如果两个向量都是单位向量的话,乘出来就是夹角的cos
fixed3 normalDir=normalize(UnityObjectToWorldDir((float3)v.normal));
//光照的位置,因为光是平行光所以也是方向
fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);
//_LightColor0是光照的颜色
fixed3 diffuse =_LightColor0.rgb*max(dot(normalDir,lightDir),0);
f.color =diffuse;
return f;
}
fixed4 frag (v2f f):SV_TARGET{
return fixed4(f.color,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
环境光获取UNITY_LIGHTMODEL_AMBIENT
两个光叠加就把两个颜色值相加,两个光融合则把两个颜色值相乘。
像素漫反射:
struct a2v {
float4 vertex:POSITION;
fixed3 normal :NORMAL;
};
struct v2f{
float4 position :SV_POSITION;
float3 worldNormalDir:COLOR;
};
v2f vert(a2v v){
v2f f;
f.position=UnityObjectToClipPos(v.vertex);
f.worldNormalDir=UnityObjectToWorldDir((float3)v.normal);
return f;
}
fixed4 frag (v2f f):SV_TARGET{
fixed3 normalDir= normalize(f.worldNormalDir);
fixed3 ambient= UNITY_LIGHTMODEL_AMBIENT.rgb;
//光照的位置,因为光是平行光所以也是方向
fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);
//_LightColor0是光照的颜色
fixed3 diffuse =_LightColor0.rgb*max(dot(normalDir,lightDir),0);
fixed3 tempColor =diffuse*_Diffuse.rgb+ambient;
return fixed4(tempColor,1);
}
一般使用半兰伯特光照,正常的光照计算出来是-1到1,所以在平行光的背面的漫反射计算出来是-1所以这个地方是黑色的。公式如下:
diffuse=light*cosθ 正常的是这样的。
diffuse=light*(cosθ*0.5+0.5) 半兰伯特光照
半兰伯特与兰伯特
高光反射公式:
Specular = 直射光*pow(max(cosθ,0),高光的参数)
这里的θ是指反射光与反射点到相机方向的夹角。
示意图
Blinn-Phong高光模型,公式是计算是不变的,这里的θ是上面夹角的一半。也就是反射光与反射点到相机方向的夹角的一半。这里求一个夹角的的cos,是先求出平分线,直接把两个向量相加然后再单位化就是平分线向量。
网友评论