着色器
WARNING
本页列出的着色器与Render Dragon渲染引擎不兼容。这意味着这些着色器将无法在1.16.200版本以上的Windows和主机设备,以及其他1.18.30版本以上的设备运行!
概述
着色器代码分为两个文件夹:glsl和hlsl。要使着色器在所有设备上生效,需要同时用两种语言编写代码。在Windows平台测试时,仅需hlsl版本即可。当进行跨语言转换时需注意语法差异,例如HLSL中的float3对应GLSL中的vec3。两种语言的完整映射关系可参考此文档。
材质系统
顶点着色器、片段着色器以及部分几何着色器会与特定参数组合成材质,这是自定义着色器的必备要素。新建材质时需创建与原版资源包中同名的.material文件,例如:materials/particles.material。材质支持通过冒号语法实现继承关系,例如:entity_alpha:entity_base
通用材质字段说明
| 字段名 | 描述 | 示例值 | 备注 |
|---|---|---|---|
vertexShader | 相对于hlsl/glsl文件夹的顶点着色器路径 | HLSL着色器会自动添加.hlsl后缀 | |
fragmentShader | 相对于hlsl/glsl文件夹的片段着色器路径 | HLSL着色器会自动添加.hlsl后缀 | |
vertexFields | 传递给顶点着色器的字段数组 | 建议从原版材质复制此字段 | |
variants | 定义材质变体的对象数组 | 建议从原版材质复制此字段 | |
+defines | 添加到着色器源代码的#define指令数组 | 适用于复用着色器时调整特定参数 | |
+states | 启用的状态数组 | ["Blending", "DisableAlphaWrite", "DisableDepthWrite"] | OpenGL实现中相当于调用glEnable |
-defines | 从继承的+defines中移除的指令数组 | ||
+samplerStates | 定义纹理采样方式的对象数组 | { "samplerIndex": 0, "textureFilter": "Point" } | textureFilter指定纹理采样方式,textureWrap定义超出纹理尺寸时的处理行为 |
msaaSupport | 多重采样抗锯齿支持 | Both | |
blendSrc | 指定颜色源混合因子的计算方式 | One | OpenGL实现中相当于调用glBlendFunc |
blendDst | 指定颜色目标混合因子的计算方式 | One | OpenGL实现中相当于调用glBlendFunc |
示例:
{
"materials": {
"version": "1.0.0",
"particle_debug": {
"vertexShader": "shaders/particle_generic.vertex",
"fragmentShader": "shaders/particle_debug.fragment",
"vertexFields": [{ "field": "Position" }, { "field": "Color" }, { "field": "UV0" }],
"+samplerStates": [
{
"samplerIndex": 0,
"textureFilter": "Point"
}
],
"msaaSupport": "Both"
}
}
}完整材质文件规范请参阅material文件JSON schema。
故障排查
着色器未生效
每次修改着色器后必须重启Minecraft才能完全重新编译。
编译错误
当出现编译错误时,通常会标注错误发生的行号。建议检查报错行上方若干行代码,因为Minecraft会在编译前自动插入#define指令。
找不到常量缓冲区:$Globals
该错误可能与全局变量有关。解决方法包括:在main函数内初始化变量,或将其改为#define指令。
实用技巧
向着色器传参
可通过修改实体颜色向着色器传递参数。输入颜色会被限制在<0.0, 1.0>范围内。要传递更大数值,需要除以最大值(或其他较大数值)。
使用时间变量
全局变量TIME是以秒为单位的浮点数。要实现基于粒子生命周期的计时,需这样传递参数:
"minecraft:particle_appearance_tinting": {
"color": ["variable.particle_age/variable.particle_lifetime", 0, 0, 1]
}在着色器中使用PSInput.color.r表示时间,其中0.0为粒子诞生时刻,1.0为粒子消亡时刻。
实体朝向检测
在实体着色器中实现基于摄像机朝向的效果:
- 在顶点/片段着色器的
PS_Input中添加新字段:
float3 viewDir: POSITION;- 在顶点着色器中添加计算:
PSInput.viewDir = normalize((mul(WORLD, mul(BONES[VSInput.boneId], float4(VSInput.position, 1)))).xyz);- 在片段着色器中使用
PSInput.viewDir实现视角相关效果
数值调试
最简单的调试方法是将数值转换为颜色输出:
PSOutput.color = float4(PSInput.uv, 0., 1.);这将生成红绿渐变,显示uv值在<0, 0>到<1, 1>之间的分布。
推荐使用基于此着色器开发的调试工具。当前版本会显示传入着色器的颜色值,要显示其他数值需修改HLSL着色器第70行为:
int ascii = getFloatCharacter( cellIndex, <需显示的float4向量> );注意:GLSL版调试着色器可能导致游戏崩溃,仅限调试使用。




