这一节我们学一下用着色器(shader)描边效果。来看看最终效果:
请添加图片描述

一、进行shader初始设置

首先我们进入NPC场景,选择Sprite2D节点,在检查器中中岛CanvasItem属性,并在Material->Material后方选择下拉按钮选择新建ShaderMaterial
请添加图片描述

然后选中新建的材质球,在Shader属性选择新建着色器,在弹出框内进行如下设置:
请添加图片描述

然后创建保存。

二、编写代码

这样我们就可以在着色器内进行编码了。我们先来学习一下Shader的基本知识。在 Godot 游戏引擎中,片段着色器(Fragment Shader)是一种运行在图形处理单元(GPU)上的程序,用于计算并确定屏幕上每个像素的颜色。片段着色器是图形渲染过程中的关键部分,它们使得开发者能够创造出丰富和动态的视觉效果。

片段着色器的基本概念:
  1. 像素颜色计算
    • 片段着色器的主要任务是计算每个像素的颜色。这可以通过直接指定颜色值或使用纹理映射来实现。
  2. 并行处理
    • 片段着色器在 GPU 上并行运行,这意味着它们同时对所有像素进行处理。这种并行处理方式使得着色器非常适合执行复杂的数学运算,以实现高效的图形渲染。
  3. 输入和输出
    • 片段着色器接收一系列输入,如纹理坐标(UV)、顶点颜色、时间变量等,并输出最终的颜色值。
片段着色器的结构:

一个基本的片段着色器通常包含以下部分:

  • 声明着色器类型
    shader_type canvas_item; // 对于 2D 渲染
    // 或者
    shader_type spatial;     // 对于 3D 渲染
    
  • 片段函数
    void fragment() {
        // 片段着色器的代码
        COLOR = vec4(1.0, 0.0, 0.0, 1.0); // 设置像素颜色为红色
    }
    
  • 使用 UV 坐标
    void fragment() {
        COLOR = vec4(UV.x, UV.y, 0.0, 1.0); // 使用 UV 坐标设置颜色
    }
    
  • 使用纹理
    void fragment() {
        COLOR = texture(TEXTURE, UV); // 从纹理中获取颜色
    }
    
片段着色器的应用:
  • 颜色效果:可以创建颜色渐变、色调映射、颜色校正等效果。
  • 纹理处理:可以实现纹理混合、模糊、锐化等效果。
  • 光照和阴影:模拟不同的光照模型和阴影效果。
  • 后处理效果:如模糊、边缘检测、颜色过滤等。
在 Godot 中使用片段着色器:
  1. 创建材质:在 Godot 中,首先需要创建一个 ShaderMaterial
  2. 编写着色器代码:在材质编辑器中,可以编写和修改着色器代码。
  3. 应用到对象:将材质应用到场景中的对象上,着色器效果就会应用到该对象。
    片段着色器是 Godot 提供的一个强大工具,可以极大地扩展游戏的视觉表现力。开发者可以通过不断学习和实践,创造出各种独特的视觉效果。

三、编写代码

请添加图片描述

我们先录入如下代码,然后我在解释一下原理和重点知识:

shader_type canvas_item;
uniform float outline_width=1.0;
uniform vec4 outline_color:source_color =vec4(0,0,0,1);

void fragment() {
	vec2 uv =UV;
	vec2 uv_up = uv+vec2(0,TEXTURE_PIXEL_SIZE.y)*outline_width;
	vec2 uv_down = uv + vec2(0,-TEXTURE_PIXEL_SIZE.y)*outline_width;
	vec2 uv_left = uv + vec2(TEXTURE_PIXEL_SIZE.x,0)*outline_width;
	vec2 uv_right = uv + vec2(-TEXTURE_PIXEL_SIZE.x,0)*outline_width;
	vec4 color_up = texture(TEXTURE,uv_up);
	vec4 color_down = texture(TEXTURE,uv_up);
	vec4 color_left = texture(TEXTURE,uv_left);
	vec4 color_right = texture(TEXTURE,uv_right);
	vec4 outline = color_down+color_up+color_left+color_right;
	outline.rgb = outline_color.rgb;
	vec4 original_color = texture(TEXTURE,UV);	
	COLOR = mix(outline,original_color,original_color.a);
	}

看一下前后对比效果:
未添加描边效果如下:
请添加图片描述

添加描边效果如下:
请添加图片描述

而且描边的宽度和颜色均可以通过参数来控制。
请添加图片描述

原理

我们想要实现描边效果,只需每个点位上下左右向外扩展一个点位,这样在与原图像叠加到一起,让后把扩展的点变成描边颜色即可。

重点知识学习
  1. shader_type::是用来定义一个着色器(Shader)的类型的关键字,Godot 支持多种类型的着色器,每种类型的着色器都有其特定的用途和上下文环境。
  2. canvas_item:着色器类型用于处理 2D 渲染,它通常用于控制 CanvasItem 类型的节点,比如 Sprite、TextureRect 或自定义的 2D 节点。当你在 Godot 中使用这种类型的着色器时,你可以自定义这些节点的渲染行为,比如颜色混合、纹理处理、光照效果等。
  3. uniform:该关键字用于声明全局变量,这些变量在着色器的所有执行实例中保持一致。换句话说,uniform 变量是那些你在渲染过程中想要从 CPU 传递到 GPU 的值,并且这些值对于同一绘制调用的所有片段都是相同的。
  4. TEXTURE_PIXEL_SIZE:是一个内置变量,用于在着色器中获取纹理的像素大小。这个变量通常用于片段着色器中,以确定纹理中每个像素的物理大小。在 Godot 的片段着色器中,TEXTURE_PIXEL_SIZE 的值通常表示为二维向量,其中包含了纹理的宽度和高度上的像素大小。例如,如果纹理的分辨率是 320x240,那么 TEXTURE_PIXEL_SIZE 应该是 (1/320, 1/240),这意味着在每个维度上,一个单元代表一个像素。
  5. texture() 函数用于在着色器中从指定的纹理中采样颜色值。
  6. mix() 函数用于在两个值之间进行线性插值,常用于混合颜色或向量。一句话描述其用途是:函数有三个参数,第一个参数表示起始颜色,第二参数表示结束颜色;第三个参数(通常是一个介于 0.0 和 1.0 之间的系数)在两个值之间进行平滑过渡,如果为0,表示第一种颜色;1表示第二种颜色;0到1之间表示过度颜色。
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐