Shader在哪写?

如图,新建一个sprite,在它的Meterial属性里点击新建shaderMaerial,在shaderMateril里点击新建shader,就会弹出着色器面板,可以在里面写shader了。
Shader格式
第一行我们先写上:
shader_type canvas_item;
void fragment(){
}shader_type是shader的类型,有spatial,canvas_item和particles 三种。必须在第一行指定shader_type。
spatial: 用来渲染3D
canvas_item: 用来渲染2D
particles:用来渲染粒子
fragment函数里面就是我们要写处理逻辑的地方。
fragment()是shader的回调函数,
每一个像素点都会运行一次fragment函数。
每一个像素点都会运行一次fragment函数。
每一个像素点都会运行一次fragment函数。
重要的事说三遍。
当然你会发现语法和gdscript有些不同,语句结尾要加分号,函数要用大括号括起来。
详细的请参考官方文档。
Shader基本逻辑
全白效果
先从简单的开始
shader_type canvas_item;
void fragment(){
COLOR=vec4(1.0,1.0,1.0,1.0);
}
效果如图,整个sprite都变白了。
COLOR是shader内置属性,它表示一个像素点的颜色。
vec4 是shader的数据类型,4维向量,可以用来表示颜色。
vec4有四个属性,x,y,z,w。每个属性都是float类型(所以用1.0而不是1)。
vec4的四个属性也可以用r,g,b,a来表示,就是说vec4.x和vec4.r是完全一样的。
shader常用类型有float,vec2,vec3,vec4等。
现在我们来看COLOR=vec4(1.0,1.0,1.0,1.0);这句话,
vec4(1.0,1.0,1.0,1.0)表示rgba都是1.0的颜色,就是白色。
每个像素点都会运行一次这个语句,所以每个像素点的颜色都变成了白色。
剪影效果
我们先写上
shader_type canvas_item;
void fragment(){
COLOR=texture(TEXTURE,UV);
}
效果如图
你可能会想:咦?这不是和原来一样吗。
是的,确实和原来一样。这句话是什么意思呢?
UV 是shader内置属性,用来表示当前像素点的坐标。它是一个vec2。

每个像素点都有一个UV值,每个像素点的UV值不一样。
左上角的像素点UV值是(0.0,0.0),
右下角的像素点UV值是(1.0,1.0),
正中心的像素点UV值是(0.5,0.5)。
TEXTURE是shader的内置属性(反正这些全大写的都是内置属性)。它表示原始的纹理。
texture函数是shader的内置函数,传入纹理和uv值,可以返回纹理上uv坐标的颜色(vec4)。
我们来看:COLOR=texture(TEXTURE,UV);
就是每个像素获取自己原来的颜色,赋值给COLOR。当然不会有任何变化。
接下来我们写
shader_type canvas_item;
void fragment(){
COLOR=texture(TEXTURE,UV);
COLOR.rgb=vec3(1.0,1.0,1.0);
}效果如图,成功实现了剪影效果。

COLOR.rgb=xxx 这是shader中的语法,可以同时给r,g,b三个值赋值,非常方便。
你可能会说,为什么要写COLOR=texture(TEXTURE,UV);?
我不能直接写 COLOR.rgb=vec3(1.0,1.0,1.0);吗?
这是不行的,COLOR默认值其实是(1.0,1.0,1.0,1.0)。
只要调用了COLOR,COLOR就会变成(1.0,1.0,1.0,1.0)。
你可以试试这样
shader_type canvas_item;
void fragment(){
COLOR;
}如图,也能让图片变全白。

制作像素化文字shader
我这里用的字体是思源黑体Medium。新建一个label,字体大小设成12,我们看看默认的效果。

放大后:

为什么看上去这么不像素,主要是字体的抗锯齿,使它有半透明的部分。
所以要做的就是去掉半透明的部分。
学习了上面的知识,你应该知道怎么做了。
在label的Meterial属性里点击,新建ShaderMeterial,然后新建Shader
Shader代码如下
shader_type canvas_item;
void fragment(){
COLOR=texture(TEXTURE,UV);
if(COLOR.a<0.5){
COLOR.a=0.0;
}else{
COLOR.a=1.0;
}
}如果像素的alpha<0.5,就把alpha变成0。如果像素的alpha>=0.5,就把alpha变成1。
看看效果

放大后:

很好很像素。
当然临界值可以不是0.5,如果我们希望可以微调临界值该怎么办?
这时要声明变量,代码如下
shader_type canvas_item;
uniform float limit=0.5;//声明变量 limit,默认值是0.5
void fragment(){
COLOR=texture(TEXTURE,UV);
if(COLOR.a<limit){ //把0.5替换成limit
COLOR.a=0.0;
}else{
COLOR.a=1.0;
}
}用uniform指定的变量可以在外部修改,可以微调像素化的效果。
最后点击保存按钮把shader保存成文件,就可以重复使用了
更多关于shader的信息请参考官方文档:
http://docs.godotengine.org/zh_CN/latest/tutorials/shading/shading_language.html



暂无关于此日志的评论。