kanzi中shader的学习笔记
📘 Kanzi Shader 核心笔记
一、基本概念与工作流程
1.1 Shader 是什么?
-
Shader 是运行在 GPU 上的小程序,用 GLSL (OpenGL Shading Language) 编写。
-
两种必须的 Shader:
-
顶点着色器 (Vertex Shader):处理顶点位置/法线等。
-
片段着色器 (Fragment Shader):计算每个像素颜色。
-
-
Kanzi 支持 OpenGL ES 2.0 (
#version 100) 和 ES 3.0 (#version 300 es)。
1.2 Shader 在 Kanzi 中的位置
-
源码必须放在
Projects/<项目名>/Shaders目录下,Studio 自动索引。 -
通过 材质类型 (Material Type) 关联 Shader,再通过 材质 (Material) 给模型/UI赋值。
-
渲染流程:网格 (Mesh) → 材质 (Material) → 材质类型 (Material Type) → Shader 代码。
二、GLSL 语法核心(Kanzi 环境)
2.1 文件结构必备要素
#version 100 // 必须首行,声明 GLSL 版本
precision mediump float; // 片段着色器必须声明默认精度
// uniform / attribute / varying 声明...
void main() {
// 你的代码
}
2.2 常用数据类型
| 类型 | 说明 | 示例 |
|---|---|---|
float | 单精度浮点 | 0.5 |
vec2 | 2 分量向量 | UV 坐标 (u, v) |
vec3 | 3 分量向量 | 颜色 (r,g,b) 或方向 (x,y,z) |
vec4 | 4 分量向量 | 颜色+透明度 (r,g,b,a) 或齐次坐标 (x,y,z,w) |
mat3 | 3×3 矩阵 | 法线变换矩阵 |
mat4 | 4×4 矩阵 | 世界/视图/投影矩阵 |
sampler2D | 2D 纹理采样器 | 声明贴图变量 |
2.3 变量修饰符(极重要)
| 修饰符 | 用途 | 应用阶段 | Kanzi 对应 |
|---|---|---|---|
attribute (ES2) / in (ES3) | 从网格传入顶点数据,每个顶点不同 | 顶点着色器 | kzPosition |
uniform | CPU 传入,一次绘制内所有顶点/像素相同 | 两种着色器都可 | 材质属性、矩阵 |
varying (ES2) / out (顶点) in (片段)(ES3) | 从顶点着色器插值传到片段着色器 | 两阶段间传递 | 自定义 UV、颜色 |
精度 highp/mediump/lowp | 声明浮点计算精度,片段着色器需默认声明 | 片段着色器 | precision mediump float; |
Kanzi 习惯:公司代码可能 ES2 和 ES3 混用,记住 varying ≈ in/out 就行。
三、Kanzi 内置变量(不需要声明,直接使用)
所有以 kz 开头的变量都是引擎自动注入的,绝不可自行声明。
3.1 顶点着色器输入(从网格传入)
| 变量名 | 类型 | 说明 |
|---|---|---|
kzPosition | vec3 | 顶点局部坐标,必须使用 |
kzNormal | vec3 | 顶点法线 |
kzTextureCoordinate0 | vec2 | 第一套 UV(最常用) |
kzTextureCoordinate1 | vec2 | 第二套 UV(如果有) |
kzColor | vec4 | 顶点颜色(通常来自笔刷) |
kzTangent | vec3/vec4 | 切线,法线贴图需要 |
3.2 内置 Uniform(变换矩阵 & 相机)
| 变量名 | 类型 | 作用 |
|---|---|---|
kzWorldMatrix | mat4 | 模型 → 世界空间 |
kzViewMatrix | mat4 | 世界 → 相机(视图)空间 |
kzProjectionMatrix | mat4 | 相机 → 裁剪空间(投影) |
kzWorldViewProjectionMatrix | mat4 | 三合一,最常用。直接把局部坐标转到裁剪空间 |
kzNormalMatrix | mat3 | 用于法线的正确变换(世界矩阵的逆转置) |
kzCameraPosition | vec3 | 相机在世界空间的位置 |
3.3 必须输出的变量
| 变量 | 用途 | 示例 |
|---|---|---|
gl_Position (顶点着色器) | 顶点最终裁剪坐标,必赋值 | gl_Position = kzWorldViewProjectionMatrix * vec4(kzPosition, 1.0); |
gl_FragColor (片段着色器,ES2) | 像素最终颜色 | gl_FragColor = vec4(1.0,0.0,0.0,1.0); |
自定义 out vec4 (ES3) | 替代 gl_FragColor | out vec4 FragColor; 然后赋值 FragColor = ... |
四、自定义 Uniform:让 Studio 控制 Shader
4.1 Shader 中声明
uniform vec4 MyColor;
uniform sampler2D MyTexture;
-
命名规则:不要用
kz前缀,用小写字母开头即可。
4.2 Studio 中绑定
-
找到对应 Material Type。
-
在 Property Types 里创建同名属性,选对类型(如 Color 绑 vec4,Texture 绑 sampler2D)。
-
在具体 Material 中给属性赋值(选颜色、拖图片)。
这样数据就自动传入 Shader。
五、高频内置函数(UI Shader 精华)
| 函数 | 作用 | 常用场景 |
|---|---|---|
texture2D(sampler, uv) (ES2) / texture(sampler, uv) (ES3) | 纹理采样,返回 vec4 颜色 | 获取贴图颜色 |
step(edge, x) | x < edge 返回 0,否则 1 | 硬边遮罩 |
smoothstep(edge0, edge1, x) | 平滑过渡,抗锯齿边缘 | 进度条边缘、光晕、渐变 |
mix(a, b, t) | 线性插值 a*(1-t) + b*t | 纹理混合、颜色切换 |
clamp(x, min, max) | 钳制范围 | 防止数值溢出 |
dot(a, b) | 向量点积 | 漫反射光照 N·L;灰度计算 |
length(v) | 向量长度 | 制作圆形遮罩 |
normalize(v) | 向量归一化 | 方向单位化 |
pow(x, y) | 幂运算 | Gamma 校正、高光 |
实用套路举例:
// 进度条平滑边缘
float alpha = smoothstep(progress, progress+0.02, uv.x);
// 圆形裁剪
float dist = length(uv - 0.5);
float mask = 1.0 - smoothstep(radius-0.01, radius, dist);
// 灰度化
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
六、UV 与多套纹理坐标
6.1 UV 是什么?
-
纹理的二维坐标系
(U,V),范围 0~1,左下角为原点。 -
作用:告诉 GPU “贴图的哪一部分”贴到“模型的哪个顶点”。
6.2 为什么有多套 UV?
同一模型可能需要不同的贴图映射。例如:
-
第一套
kzTextureCoordinate0:颜色贴图。 -
第二套
kzTextureCoordinate1:光照贴图或细节纹理。
在 Studio 中检查网格属性可看到 UV 套数。
6.3 传递多套 UV 示例
// 顶点着色器
attribute vec2 kzTextureCoordinate0;
attribute vec2 kzTextureCoordinate1;
varying vec2 vUV0;
varying vec2 vUV1;
void main() {
vUV0 = kzTextureCoordinate0;
vUV1 = kzTextureCoordinate1;
gl_Position = kzWorldViewProjectionMatrix * vec4(kzPosition, 1.0);
}
// 片段着色器
uniform sampler2D Diffuse; // 绑到 vUV0
uniform sampler2D Lightmap; // 绑到 vUV1
varying vec2 vUV0;
varying vec2 vUV1;
void main() {
vec4 col = texture2D(Diffuse, vUV0);
vec4 lit = texture2D(Lightmap, vUV1);
gl_FragColor = col * lit;
}
七、矩阵与坐标空间(白话理解)
7.1 三个核心变换
| 变换 | 矩阵 | 比喻 |
|---|---|---|
| World | kzWorldMatrix | 把玩具车放到房间某个位置 |
| View | kzViewMatrix | 扛起相机对准玩具车 |
| Projection | kzProjectionMatrix | 按下快门,拍成2D照片 |
7.2 最重要的一行代码
gl_Position = kzWorldViewProjectionMatrix * vec4(kzPosition, 1.0);
-
kzPosition是模型自身的局部坐标 (vec3)。 -
必须转为
vec4(kzPosition, 1.0),1.0表示“这是一个点”。 -
乘法是 左乘:矩阵在左,向量在右。
八、写 Shader 的注意事项清单
-
命名:自定义变量一律不用
kz前缀,避免冲突。 -
精度:ES2 片段着色器首行必须写
precision mediump float;,否则编译失败。 -
版本:
#version必须放第一行。 -
纹理采样:ES2 用
texture2D+varying;ES3 用texture+in/out。 -
矩阵乘法顺序:永远左乘。
-
UV 禁止
.uv成员:UV 是普通vec2,没有.uv这种写法。 -
测试:保存即编译,错误时节点变红,看控制台日志。
-
性能:尽量用
smoothstep/mix代替if分支。
九、极简代码模板(可以直接复制实验)
9.1 最简顶点着色器
#version 100
attribute vec3 kzPosition;
void main() {
gl_Position = kzWorldViewProjectionMatrix * vec4(kzPosition, 1.0);
}
9.2 带纹理的片段着色器
#version 100
precision mediump float;
uniform sampler2D MainTexture;
varying vec2 vTexCoord; // 需顶点着色器传来
void main() {
gl_FragColor = texture2D(MainTexture, vTexCoord);
}
更多推荐

所有评论(0)