Shader学习笔记之砖块shader
2015年03月21日 10:22
0 点赞
0 评论
更新于 2025-11-21 17:55
准备工作
首先,我们需要创建一个球体(sphere)、一个材质(material)以及一个自定义的Shader。以下是具体的Shader代码:
Shader "Custom/BlockballShader" {
SubShader {
// 设置替换渲染时的类型为不透明物体
Tags { "RenderType"="Opaque" }
// 关闭剪裁,即渲染物体的所有面
Cull Off
CGPROGRAM
// 声明表面着色器,使用Lambert光照模型,并指定自定义的顶点函数myVertex
#pragma surface surf Lambert vertex:myVertex
// 指定Shader的目标版本为3.0
#pragma target 3.0
// 输入结构体,用于传递顶点数据到表面着色器
struct Input {
// 声明一个三维向量,用于存储顶点的原始位置
float3 orginPosition;
};
// 自定义顶点函数,对顶点数据进行处理
void myVertex(inout appdata_full v, out Input o) {
// 初始化输出结构体
UNITY_INITIALIZE_OUTPUT(Input, o);
// 将顶点的原始位置赋值给输入结构体的orginPosition变量
o.orginPosition = v.vertex.xyz;
}
// 表面着色器函数,计算每个片元的颜色
void surf(Input IN, inout SurfaceOutput o) {
// 定义三种颜色:泥的颜色、砖的颜色和另一种颜色
float4 niC = float4(0.763, 0.657, 0.614, 0);
float4 zhuanC = float4(0.678, 0.231, 0.129, 0);
float4 colo = float4(0, 0, 1, 0);
// 获取当前片元的原始位置
float3 currPos = IN.orginPosition;
// 计算当前片元的纬度
float wd = asin(currPos.y);
// 计算当前片元的经度
float jd = atan2(currPos.x, currPos.z);
// 定义一个接近1的系数,用于避免直接赋值颜色时可能出现的错误
float yss = 0.9999999;
float4 finalColor;
// 计算当前片元所在的行是奇数行还是偶数行
int row = int(fmod((wd * 100.0 + 90.0) / 12.0, 2.0));
// 计算一个辅助变量,用于判断当前片元是否在当前行的砖块垂直区间内
float ny = fmod(wd * 100.0 + 90.0, 12.0);
// 每行的砖块偏移值,奇数行偏移半个砖块
float oeoffset = 0.0;
// 用于判断当前片元是否在当前列的砖块水平区间内的辅助变量
float nx;
if (ny > 10.0) {
// 当前片元不在当前行的砖块垂直区间内,使用泥的颜色
finalColor = niC;
} else {
if (row == 1) {
// 若为奇数行,则加上列偏移
oeoffset = 11.0;
}
// 计算当前片元是否在当前列的砖块水平区间内的辅助变量
nx = fmod(jd * 100 + oeoffset, 22.0);
if (abs(nx) > 20.0) {
// 当前片元不在当前列的砖块水平区间内,使用泥的颜色
finalColor = niC;
} else {
// 当前片元在当前列的砖块水平区间内,使用砖的颜色
finalColor = zhuanC;
}
}
// 将最终颜色乘以系数后赋值给表面输出的反照率
o.Albedo = yss * finalColor;
}
ENDCG
}
// 当当前Shader无法运行时,回退到Diffuse Shader
FallBack "Diffuse"
}
效果图
运行上述Shader后,会呈现出相应的砖块效果。你可以在Unity中查看具体的渲染结果。