Godot-StartUP

创建于:2018-07-28

创建人: Justus

38 信息 13 成员
讨论基于Godot以及Unity引擎的游戏开发经验,理论和最佳实践。共享一些通用思路以启发另一种生产工具中的实践。独立开发群QQ: 122017359

Godot的Shader入门+制作像素文字Shader

logoss 2018-10-17

Shader在哪写?

Image title

如图,新建一个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);
}

Image title

效果如图,整个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);
}

Image title

效果如图

你可能会想:咦?这不是和原来一样吗。

是的,确实和原来一样。这句话是什么意思呢?

UV 是shader内置属性,用来表示当前像素点的坐标。它是一个vec2。

Image title

每个像素点都有一个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);
}

效果如图,成功实现了剪影效果。

Image title

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;
}

如图,也能让图片变全白。

Image title

制作像素化文字shader

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

Image title

放大后:

Image title

为什么看上去这么不像素,主要是字体的抗锯齿,使它有半透明的部分。

所以要做的就是去掉半透明的部分。

学习了上面的知识,你应该知道怎么做了。

在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。

看看效果

Image title

放大后:

Image title

很好很像素。

当然临界值可以不是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指定的变量可以在外部修改,可以微调像素化的效果。Image title

最后点击保存按钮把shader保存成文件,就可以重复使用了Image title

更多关于shader的信息请参考官方文档:

http://docs.godotengine.org/zh_CN/latest/tutorials/shading/shading_language.html

(转发自:原日志地址

近期喜欢的会员

 
Niilii 2018-10-17

硬核像素hhh

 
logoss 2018-10-18

Niilii 找不到免费的中文像素字体,这算是个备选方案吧。

 
Justus 2018-10-18
马克
 
JamBob 2018-10-22

nice

 
sloaix 2020-12-01

这个方案好,省钱了,人民群众的智慧果然是无穷的。

 

加入 indienova

  • 建立个人/工作室档案
  • 建立开发中的游戏档案
  • 关注个人/工作室动态
  • 寻找合作伙伴共同开发
  • 寻求线上发行
  • 更多服务……
登录/注册