unity shader效果教程附详细代码_False Color
这一part使用shader来通过颜色来可视化模型的顶点属性,简而言之就是使用shader来给物体上色,那为什么不直接用一个材质在unity里上色然后应用呢,那样多简单。虽然简单,但是那样还是有局限性的,只能实现颜色纹理等基础属性。但是使用Shader 允许你直接操作每个顶点和像素,实现高度自定义的效果。例如这一节要实现的False Color 可视化:展示模型的法线、切线、UV 坐标等几何属性。
写在前面:
这个系列来源于书籍冯乐乐老师的《unity shader 入门精要》,
参考的代码库“https://github.com/candycat1992/Unity_Shaders_Book”
我自己跟着写了一遍代码,并在代码块里给shader代码加上了比较详细的注释
更为仔细的解释和unity shader原理和知识书里都有,本blog不做详细解释,推荐买书来看。
本项目的所有代码在https://github.com/takashiwangbh/Unity-shader-effect-reproduction/tree/main
介绍
这一part使用shader来通过颜色来可视化模型的顶点属性,简而言之就是使用shader来给物体上色,那为什么不直接用一个材质在unity里上色然后应用呢,那样多简单。虽然简单,但是那样还是有局限性的,只能实现颜色纹理等基础属性。但是使用Shader 允许你直接操作每个顶点和像素,实现高度自定义的效果。例如这一节要实现的False Color 可视化:展示模型的法线、切线、UV 坐标等几何属性。
物体和shader的创建
在unity中,创建一个球,然后再创建一个材质,将材质应用到球上,再创建一个shader应用到材质上。
shader代码
Shader "Unity Shaders Book/Chapter 5/False Color" { // 定义了一个名为 "False Color" 的着色器
SubShader { // 一个子着色器
Pass { // 着色器的一个 Pass
CGPROGRAM // 开始编写 CG 代码
#pragma vertex vert // 指定顶点着色器函数为 vert
#pragma fragment frag // 指定片段着色器函数为 frag
#include "UnityCG.cginc" // 包含 Unity 的常用 CG 工具函数
struct v2f { // 定义顶点到片段的结构体
float4 pos : SV_POSITION; // 顶点的屏幕坐标
fixed4 color : COLOR0; // 输出到片段的颜色
};
v2f vert(appdata_full v) { // 顶点着色器
v2f o; // 定义一个输出结构体
o.pos = UnityObjectToClipPos(v.vertex); // 将模型空间的顶点转换为裁剪空间坐标
// 可视化法线 (Normal)
o.color = fixed4(v.normal * 0.5 + fixed3(0.5, 0.5, 0.5), 1.0);
// 将法线值从 (-1,1) 转换为 (0,1),以便用颜色显示
// 可视化切线 (Tangent)
o.color = fixed4(v.tangent.xyz * 0.5 + fixed3(0.5, 0.5, 0.5), 1.0);
// 同样对切线进行归一化和偏移,用颜色展示
// 可视化双切线 (Binormal)
fixed3 binormal = cross(v.normal, v.tangent.xyz) * v.tangent.w;
// 计算双切线,通过法线和切线的叉积计算,乘以切线的 w 值
o.color = fixed4(binormal * 0.5 + fixed3(0.5, 0.5, 0.5), 1.0);
// 对双切线归一化并用颜色显示
// 可视化第一套纹理坐标 (UV1)
o.color = fixed4(v.texcoord.xy, 0.0, 1.0);
// 使用第一套 UV 坐标,将其 XY 直接映射为颜色的 RG 分量
// 可视化第二套纹理坐标 (UV2)
o.color = fixed4(v.texcoord1.xy, 0.0, 1.0);
// 使用第二套 UV 坐标,映射为颜色
// 可视化第一套纹理坐标的分数部分
o.color = frac(v.texcoord); // frac() 提取小数部分
if (any(saturate(v.texcoord) - v.texcoord)) {
// 检查 UV 是否超出 (0,1) 范围,若超出,则标记
o.color.b = 0.5; // 蓝色通道设为 0.5 表示标记
}
o.color.a = 1.0; // 设置透明度为 1
// 可视化第二套纹理坐标的分数部分
o.color = frac(v.texcoord1); // 同理提取第二套 UV 的小数部分
if (any(saturate(v.texcoord1) - v.texcoord1)) {
// 检查第二套 UV 是否超出范围
o.color.b = 0.5;
}
o.color.a = 1.0;
// 可视化顶点颜色
// o.color = v.color; // 如果需要可视化模型的顶点颜色,取消注释
return o; // 返回计算好的数据
}
fixed4 frag(v2f i) : SV_Target { // 片段着色器
return i.color; // 输出顶点着色器计算的颜色
}
ENDCG // 结束 CG 代码
}
}
}
结果
就这样,一个球体就被渲染上了不同的颜色
更多推荐
所有评论(0)