【Godot4自学手册】第四十三用着色器(shader)给纹理描边

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

一、进行shader初始设置

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

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

然后创建保存。

二、编写代码

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

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

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

  • 声明着色器类型 :

    glsl 复制代码
    shader_type canvas_item; // 对于 2D 渲染
    // 或者
    shader_type spatial;     // 对于 3D 渲染
  • 片段函数 :

    glsl 复制代码
    void fragment() {
        // 片段着色器的代码
        COLOR = vec4(1.0, 0.0, 0.0, 1.0); // 设置像素颜色为红色
    }
  • 使用 UV 坐标 :

    glsl 复制代码
    void fragment() {
        COLOR = vec4(UV.x, UV.y, 0.0, 1.0); // 使用 UV 坐标设置颜色
    }
  • 使用纹理 :

    glsl 复制代码
    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之间表示过度颜色。
相关推荐
千里马学框架4 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone4 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼4 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
liangshanbo12154 天前
React 性能优化实战
性能优化·react
AFinalStone4 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen4 天前
属性动画原理与高级动画实现
android·kotlin·canvas