7.光照模型-漫反射光照模型-半兰伯特光照模型-逐顶点光照
7.1 知识点
利用半兰伯特光照模型实现光照效果(逐顶点光照)
半兰伯特光照模型的逐顶点光照效果实现与兰伯特光照模型几乎相同,唯一的区别在于公式。具体的计算公式为:
漫反射光照颜色 = 光源的颜色 * 材质的漫反射颜色 * ((标准化后物体表面法线向量· 标准化后光源方向向量) * 0.5 + 0.5)
修改顶点函数中的颜色计算公式
我们需要将顶点函数中计算颜色的公式改成半兰伯特公式。
v2f vert(appdata_base appdata_base)
{
// 声明v2f,用于传递给片元函数的
v2f v2f;
// UnityObjectToClipPos将模型空间下的顶点转换到裁剪空间下
v2f.pos = UnityObjectToClipPos(appdata_base.vertex);
// appdata_base.normal获取到在模型空间下的法线
// UnityObjectToWorldNormal将法线从模型空间转换成世界空间,获取相对于世界坐标系下的法线信息
float3 normal = UnityObjectToWorldNormal(appdata_base.normal);
// _WorldSpaceLightPos0.xyz表示世界坐标系下光源方向,_WorldSpaceLightPos0是四维向量,只需要xyz即可
// normalize将向量归一化
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
// 使用半兰伯特公式进行计算
//_LightColor0光照颜色
//.rgb表示只使用颜色进行计算,透明度不考虑
fixed3 color = _LightColor0.rgb * _MainColor.rgb * (dot(normal, lightDir) * 0.5 + 0.5);
// UNITY_LIGHTMODEL_AMBIENT.rgb是兰伯特光照模型环境光变量
// 加上环境光变量的目的是希望阴影处不要全黑,这样看起来会更自然
// 目的是为了让表现效果更接近于真实世界,因此需要加上它
v2f.color = UNITY_LIGHTMODEL_AMBIENT.rgb + color;
return v2f;
}
进行对比
使用半兰伯特光照模型后,效果会与其他光照模型形成对比,从而展示出更自然的光照效果。
7.2 知识点代码
Lesson07_光照模型_漫反射光照模型_兰半伯特光照模型_逐顶点光照
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson07_光照模型_漫反射光照模型_兰半伯特光照模型_逐顶点光照 : MonoBehaviour
{
void Start()
{
#region 知识点 利用半兰伯特光照模型实现光照效果(逐顶点光照)
//半兰伯特光照模型的逐顶点实现
//和兰伯特一模一样
//唯一的区别就是公式
//漫反射光照颜色 = 光源的颜色 * 材质的漫反射颜色 *((标准化后物体表面法线向量· 标准化后光源方向向量)* 0.5 + 0.5)
#endregion
}
}
Lesson07_Half_Lambert_Vertex.shader
Shader "Unlit/Lesson07_Half_Lambert_Vertex"
{
Properties
{
//材质的漫反射光照颜色
_MainColor("MainColor", Color) = (1,1,1,1)
}
SubShader
{
//设置我们的光照模式 ForwardBase这种向前渲染模式 主要是用来处理 不透明物体的 光照渲染的
Tags
{
"LightMode"="ForwardBase"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//引用对应的内置文件
//主要是为了之后 的 比如内置结构体使用,内置变量使用
#include "UnityCG.cginc"
#include "Lighting.cginc"
//材质的漫反射颜色
fixed4 _MainColor;
//顶点着色器传递给片元着色器的内容
struct v2f
{
//裁剪空间下的顶点坐标信息
float4 pos:SV_POSITION;
//对应顶点的漫反射光照颜色
fixed3 color:COLOR;
};
v2f vert(appdata_base appdata_base)
{
//声明v2f 要传递给片元函数的
v2f v2f;
//UnityObjectToClipPos 把模型空间下的顶点转换到裁剪空间下
v2f.pos = UnityObjectToClipPos(appdata_base.vertex);
//appdata_base.normal 获取到在模型空间下的法线
//UnityObjectToWorldNormal 将法线从模型空间转换成世界空间 获取到相对于世界坐标系下的法线信息
float3 normal = UnityObjectToWorldNormal(appdata_base.normal);
//_WorldSpaceLightPos0.xyz 世界坐标系下光源方向 _WorldSpaceLightPos0是四维向量 只需要xyz即可
//normalize 把向量归一化
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
//使用半兰伯特公式进行计算
//_LightColor0光 照颜色
//.rgb 代表只使用颜色进行计算 透明度不考虑
fixed3 color = _LightColor0.rgb * _MainColor.rgb * (dot(normal, lightDir) * 0.5 + 0.5);
//UNITY_LIGHTMODEL_AMBIENT.rgb 兰伯特光照模型环境光变量
//加上兰伯特光照模型环境光变量的目的 是希望阴影处不要全黑 不然看起来有一些不自然
//目的就是为了让表现效果更接近于真实世界 所以需要加上它
v2f.color = UNITY_LIGHTMODEL_AMBIENT.rgb + color;
return v2f;
}
fixed4 frag(v2f v2f) : SV_Target
{
//把计算好的兰伯特光照的颜色 传递出去就可以了
//返回v2f中的颜色 透明度传1
return fixed4(v2f.color.rgb, 1);
}
ENDCG
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com