Shader Learing(Basic Lighting And Texturing篇)
顶点着色程序和片段着色程序的基本功能和数据输入输出,实际上现在的着色程序已经可以接受多种数据类型,并灵活的进行各种算法的处理,如,可以接受光源信息(光源位置、强度等)、材质信息(反射系数、折射系数等)、运动控制信息(纹理投影矩阵、顶点运动矩阵等),可以在顶点程序中计算光线的折射方向,并传递到片段程序中进行光照计算。
通常我们在应用程序涉及的顶点位置和法向量都是三元向量,使用时将三元向量便为四元向量,顶点位置坐标传入顶点着色程序中转化为四元向量,最后一元数据为 1 ,而顶点法向量传入顶点着色程序中转化为四元向量,最后一元数据为 0 。
Lighting:
diffuse
漫反射与 Lambert 模型粗糙的物体表面向各个方向等强度地反射光,这种等同地向各个方向散射的现象称为光的漫反射( diffuse reflection)。产生光的漫反射现象的物体表面称为理想漫反射体,也称为兰伯特(Lambert )反射体。当方向光照射到朗伯反射体上时,漫反射光的光强与入射光的方向和入射点表面法向夹角的余弦成正比,这称之为 Lambert 定律。
漫反射利用了向量的点积公式N•L = |N|*|L|*cosθ,可以求出反射光照:
diffuse = Kd * lightColor * max(N•L,0)。
下面分别以代码实现Vertex,Fragment和半Lambert漫反射:
Shader "Custom/015_DiffuseVertex" {
Properties{
_Diffuse("Diffuse Color",Color) = (1,1,1,1)//材质漫反射颜色
}
SubShader{
Pass{
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM
#include "UnityCG.cginc"
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed4 _Diffuse;
//application to vertex
struct a2v {
float4 vertex:POSITION;
float3 normal:NORMAL;
};
struct v2f {
float4 position:SV_POSITION;
fixed3 color : COLOR;
};
v2f vert(a2v v) {
v2f f;
f.position = mul(UNITY_MATRIX_MVP,v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
//nvidia:
//Returns the normalized version of a vector, meaning a vector
//in the same direction as the original vector
//but with a Euclidean length of one
//法线的变换与顶点的变换是有区别的(非等比例缩放)
fixed3 normalDir = normalize( mul( v.normal, (float3x3) _World2Object) );
fixed3 lightDir = normalize( _WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0) *_Diffuse.rgb;
f.color = diffuse + ambient;
return f;
}
fixed4 frag(v2f f) :SV_Target//SV_Target (render target pixel color)
{
return fixed4(f.color,1);
}
ENDCG
}
}
Fallback "Diffuse"
}
Shader "Custom/016_DiffuseFragment" {
Properties{
_Diffuse("Diffuse Color",Color) = (1,1,1,1)
}
SubShader{
Pass{
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM
#include "UnityCG.cginc"
#