定义
漫反射(diffuse) 是光线照射在物体粗糙的表面会无序地向四周反射的现象。是投射在粗糙表面上的光向各个方向反射的现象。当一束平行的入射光线射到粗糙的表面时,表面会把光线向着四面八方反射,所以入射线虽然互相平行,由于各点的法线方向不一致,造成反射光线向不同的方向无规则地反射,
我们可以通过下图观察到,反射光的强度取决于在表面法向量和入射光的光线之间的角度的余弦值。
实践
Shader "005/DiffuseSample"
{
//属性
Properties
{
//Diffuse漫反射
//变量名(“面板显示的名称”,数据类型)
_Diffuse("Diffuse",Color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
//告诉Unity,那个函数包含了顶点着色器、片元着色器的代码
#pragma vertex vert
#pragma fragment frag
//位置在Unity安装目录/Editor/Data/CGIncludes/UnityCG.cginc
#include "UnityCG.cginc"
#include "Lighting.cginc"
//为了使用Properties语义块中声明的属性,定义一个相同的变量名
fixed4 _Diffuse;
//定义输出结构体
struct v2f
{
float4 vertex:SV_POSITION;
//颜色值
fixed3 color : Color;
};
//appdata_base 包含顶点位置 法线 纹理坐标
v2f vert (appdata_base v)
{
//定义要输出的变量
v2f o;
//把顶点从模型空间直接转化到裁剪空间,也就是进行了M-V-P三次转化
o.vertex = UnityObjectToClipPos(v.vertex);
//法线方向 转为世界坐标
//在计算法线和光源方向的点积时要处于统一坐标空间 v.normal顶点法线处于模型空间
fixed3 worldNormal =UnityObjectToWorldNormal(v.normal);
//光源方向
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
//计算公式:漫反射 = 光源颜色*材质的漫反射颜色*max(0,表面法线·光源的单位矢量)
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLight));
o.color = diffuse;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4(i.color,1);
}
ENDCG
}
}
}
实现效果
右边的就是通过自己写的Shader实现的一个逐顶点的漫反射效果。