写在前面:
这个系列来源于书籍冯乐乐老师的《unity shader 入门精要》,
参考的代码库“https://github.com/candycat1992/Unity_Shaders_Book”
我自己跟着写了一遍代码,并在代码块里给shader代码加上了比较详细的注释
更为仔细的解释和unity shader原理和知识书里都有,本blog不做详细解释,推荐买书来看。
本项目的所有代码在https://github.com/takashiwangbh/Unity-shader-effect-reproduction/tree/main
结果
后面代码有点多,把最后的效果放在前面
介绍
在任何与渲染相关的内容中,光照始终是一个至关重要的主题。这本书呢介绍了基础光照的实现方式共包括六种,主要分为两类:漫反射和高光反射。
漫反射部分,除了实现基础的逐顶点和逐片元渲染之外,还额外引入了一种改进的光照模型——Half Lambert Lighting,通过对传统 Lambert 光照模型的优化,使得背光区域能够保留一定亮度,从而呈现更加柔和的效果。
高光反射部分,同样实现了逐顶点和逐片元渲染,并在此基础上加入了Blinn-Phong 光照模型,相较于经典 Phong 模型,Blinn-Phong 提供了更加高效的计算方法,并且在视觉效果上对于镜面反射的模拟更加自然。
物体和shader的创建
这个就创建胶囊体来应用就行,在3D object中创建胶囊,然后创建材质,应用到胶囊上,再创建shader应用到这个材质上就可以。对了,为了观察方便,我是把天空盒子关了的,具体是在hierarchy里的main camera的inspector中将camera的天空盒子改为单色。
shader code
Per-vertex diffuse shader
/Shader "Unity Shaders Book/Chapter 6/Diffuse Vertex-Level" {
// 定义材质的可调属性
Properties {
_Diffuse ("Diffuse", Color) = (1, 1, 1, 1) // 用于调整材质的漫反射颜色
}
SubShader {
Pass {
Tags { "LightMode"="ForwardBase" } // 指定渲染模式为前向渲染的基础光照
CGPROGRAM
#pragma vertex vert // 指定顶点着色器函数名
#pragma fragment frag // 指定片段着色器函数名
#include "Lighting.cginc" // 引入 Unity 提供的光照计算库
fixed4 _Diffuse; // 漫反射颜色,从材质属性传入
// 顶点着色器的输入结构
struct a2v {
float4 vertex : POSITION; // 顶点位置
float3 normal : NORMAL; // 顶点法线
};
// 顶点着色器的输出结构
struct v2f {
float4 pos : SV_POSITION; // 裁剪空间的位置
fixed3 color : COLOR; // 计算出的颜色
};
// 顶点着色器
v2f vert(a2v v) {
v2f o;
// 将顶点从物体空间变换到裁剪空间
o.pos = UnityObjectToClipPos(v.vertex);
// 环境光分量
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
// 将法线从物体空间变换到世界空间
fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
// 获取光源方向(世界空间)
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
// 计算漫反射光照分量
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));
// 合成最终的颜色(环境光 + 漫反射)
o.color = ambient + diffuse;
return o;
}
// 片段着色器
fixed4 frag(v2f i) : SV_Target {
// 返回顶点着色器计算的颜色,并设置不透明度为 1
retur