并非译文,官网原文请见《Godot 4.0 gets global and per-instance shader uniforms》
文章目录全局uniform衍生玩法:1. 将角色的信息传递给所有相关的着色器2. 以不变应万变的方式改变世界3. 控制天气和环境4. 让材质和环境交互实例uniform使用须知小结 全局uniform在Godot Shader中uniform
类型是逻辑代码(GDScript等)与着色器代码(Shader)传递数据的必经之路。截至目前Godot Shader中的uniform
都隶属于每个独立的材质实例,也就是说,即使你的很多2D节点或3D节点都是用相同的材质,你用uniform
传一个参数,也只能影响当前的实例的材质,如果想让所有具有该材质的对象都发生改变,必须要在逻辑代码层级,通过Signal等手段,把参数传递给每一个使用该材质的Node。这样做相对比较麻烦,而且效率也不高。
在Godot Engine 4.0中将提供一种global uniform
,你可以简单地把它们想象成C++中的静态成员变量。有了这种机制,我们就可以在着色器层级很方便地控制所有具有共同材质的对象了。
shader_type canvas_item;
global uniform vec4 my_color;
void fragment() {
COLOR = mycolor.rgb;
}
不要小看这个global uniform
,它可以衍生出很多新的着色器玩法:
还记得旷野之息中,克林穿越在茂盛的草丛中,走到哪里,角色身边的草都会受到影响么?通过global uniform
将角色的位置信息实时传给Shader,每一棵草就可以很方便地知道自己是不是会受到影响了。
还是旷野之息中的名场面,克林可以对草地刀砍火烧,同样也是通过global uniform
告知所有的草地着色器,当前挥刀或点火的位置甚至方向,然后每一棵草计算自己是否受到影响,然后通过顶点着色器决定自身的显示/隐藏以及移动方向,用片元着色器决定自身的颜色或纹理。
大风吹过,青草随风而倒,通过global uniform
把风的方向传递进去就可以了。
天空突然下起雨来,可以通过global uniform
改变所有材质的金属都和粗糙度,让一切看起来湿漉漉。
global uniform
可以大大提升游戏的细节,并且所有的Shader类型(包含即将诞生的Sky Shader)都可以支持。
instance uniform
并不是原来的uniform
,这个机制并不是针对运行时,而是在编辑器编辑uniform的默认值时使用的。以前我们新建一个Shader Material,当我们在编辑器中修改其中的uniform
时,实际上是修改了整个材质的这个默认值,要避免这种情况,必须要新建一个材质,再赋上这个Shader,这样做是比较麻烦的。在4.0版本中声明为instance uniform
以后,就可以仅仅针对这个节点来设置默认值了。
每个shader最多16个instance uniform
不支持纹理类型,仅支持普通的向量和标量类型
在多材质的网格模型上,第一个材质的instance uniform
将优先占用(注:这部分可能理解有误,等见到4.0实物再修改
)
可以通过instance_index
来手动避免冲突:
例如:
instance uniform vec4 hello : instance_index(5);
小结
不断地看到可喜的新功能加入,Godot 4.0真的非常让人期待的。