着色器与高级渲染
本页属于 GenPy Ren'Py 学习路线。教程内容面向 Ren'Py 8.x,并在页面末尾连接到 GenPy 的对应工作流。
学习目标
- 了解“着色器与高级渲染”在 Ren'Py 项目中的用途。
- 能在一个最小项目里验证本章相关语法或工作流。
- 知道发布前需要检查的常见风险,并能在 GenPy 中继续维护。
核心语法
mesh Trueshaderrenpy.register_shaderuniformGLSLModel-Based Rendering
可运行示例
text
transform crt:
mesh True
shader "example.scanline"
show bg room at crt教程正文
当内置变换(ATL、matrixcolor、blur)还不够时,可用 基于模型的渲染(Model-Based Rendering) 写自定义 GLSL 着色器,做出 CRT 扫描线、色散、水波、溶解、光照等效果。 本章是入门导引——着色器是图形编程,落地前请对照官方 Model-Based Rendering 文档逐字校验。
1. 开启模型渲染
普通图像是“贴图”;加上 mesh=True 后,它变成一个可被着色器处理的“模型”:
text
transform crt:
mesh True
shader "example.scanline"
show bg room at crtmesh True:把可显示物切成网格、走模型渲染管线(着色器才能生效)。shader "...":应用一个已注册的着色器 part(可多个)。blur(第 31 章)本质也是 model 渲染,是最易用的“内置着色器”。
2. 注册自定义着色器:renpy.register_shader
着色器由若干 part 组成,每个 part 声明变量并提供顶点/片段代码片段,按 优先级 拼接:
- 优先级约定:100 建立几何,200 决定初始片段颜色(
gl_FragColor), 更高的优先级在此基础上叠加效果。 - 关键字参数以
vertex_或fragment_开头、以整数优先级结尾,如fragment_300。 - 变量命名约定:uniform 用
u_、attribute 用a_、varying 用v_前缀。
官方示例:横向渐变(逐字可用)
text
init python:
renpy.register_shader("example.gradient", variables="""
uniform vec4 u_gradient_left;
uniform vec4 u_gradient_right;
uniform vec2 u_model_size;
varying float v_gradient_done;
attribute vec4 a_position;
""", vertex_300="""
v_gradient_done = a_position.x / u_model_size.x;
""", fragment_300="""
float gradient_done = v_gradient_done;
gl_FragColor *= mix(u_gradient_left, u_gradient_right, gradient_done);
""")
transform gradient:
shader "example.gradient"
u_gradient_left (1.0, 0.0, 0.0, 1.0)
u_gradient_right (0.0, 0.0, 1.0, 1.0)
# 用法
show eileen happy at gradient在 transform 里直接写
u_xxx (...)就能给着色器的 uniform 传参。
3. 标准变量(着色器里可直接用)
Ren'Py 会自动提供这些常用变量,你在 variables 里声明后即可使用:
| 变量 | 含义 |
|---|---|
sampler2D tex0(tex1/tex2) | 第 1/2/3 张纹理 |
attribute vec2 a_tex_coord | 顶点对应的纹理坐标 |
varying vec2 v_tex_coord | 片段的纹理坐标 |
gl_FragColor | 输出像素颜色(在 fragment 里写它) |
vec2 u_model_size | 模型尺寸 |
float u_lod_bias | 纹理 LOD 偏置 |
简易扫描线(基于标准变量,自行校验)
text
init python:
renpy.register_shader("example.scanline", variables="""
uniform sampler2D tex0;
uniform vec2 u_model_size;
varying vec2 v_tex_coord;
""", fragment_300="""
float scan = 0.92 + 0.08 * sin(v_tex_coord.y * u_model_size.y * 3.1416);
gl_FragColor.rgb *= scan;
""")
transform scanline:
mesh True
shader "example.scanline"priority 200 已把纹理颜色填进 gl_FragColor,我们在 300 处再乘以扫描明暗。
4. 常见高级效果(思路)
| 效果 | 思路 |
|---|---|
| CRT / 扫描线 | 按 y 周期性压暗 + 轻微桶形畸变 |
| 色散 / 故障 | R/G/B 三通道用不同偏移采样 tex0 |
| 水波 / 热浪 | 用 sin(time + coord) 扰动采样坐标 |
| 溶解 / 过渡 | 按噪声纹理阈值控制 alpha |
| 光照 | 顶点法线 + 光源方向点乘(见官方 lighting 示例) |
时间驱动动画着色器需要 u_time 之类 uniform,并配合 mesh/Model,详见官方 “Animated Shaders”。
5. 用现成的就好
自己写 GLSL 门槛高。社区有大量开源 Ren'Py 着色器(itch.io、GitHub、Lemma Soft), 覆盖 CRT、雨滴、色差、辉光等,直接 register_shader 引入即可——优先复用、再改造。
常见坑
- 着色器是 GPU 代码,写错通常是“黑屏/不显示”而非报错,逐步加效果调试。
- Web/移动端 GPU 能力参差,复杂着色器务必真机实测并提供降级开关。
- 变量名严格遵循
u_/a_/v_约定;标准变量名(tex0/v_tex_coord/gl_FragColor)不要拼错。 - 多个 shader part 共享同名变量会相互影响,注意命名避免冲突。
- GLSL 版本与精度(
precision)在不同平台有差异,参考官方“GLSL Version”。
官方参考
- 基于模型的渲染:https://www.renpy.org/doc/html/model.html
- 自定义着色器写作:https://www.renpy.org/doc/html/custom_text_tags.html (文本相关见第 33 章)
- 变换属性(mesh/blur/shader):https://www.renpy.org/doc/html/transform_properties.html
在 GenPy 里怎么做
- 在 GenPy 的代码模式中维护相关 .rpy 文件,先保持语法清晰,再逐步加入本章功能。
- 用故事图谱、变量、校验或演出编辑器把“能运行”提升到“可维护”。
- 导出前结合 Ren'Py Lint 和 GenPy 校验结果,确认脚本、素材和发布路径一致。
推荐继续阅读:
