Flutter & GLSL - 贰 |  从坐标到色彩

上一篇 Flutter 绘制集录 | Shader 让绘制无限强大 – 壹》 介绍了 Flutter 本身支撑 GLSL 语言进行 Shader 上色器的编写。这给 Flutter 的绘制才能增加了无限的或许。GLSL 上色器代码是一个比较独立的知识体系,接下来的几篇文章将会基于 实际运用 向咱们进行介绍。


1. 坐标与色彩

咱们都知道屏幕上的展示的内容都是由一个个 像素 构成的。

  • 每个像素点包括 色彩 的信息;
  • 每个像素点散布在屏幕坐标系上,还具有位置 坐标 信息。

Flutter & GLSL - 贰 |  从坐标到色彩

本质上是树立一种 坐标色彩 的映射联系;也能够说 GLSL 是在 经过代码控制像素


色彩在 GLSL 种经过四维向量 vec4 进行表明, 重量代表 rgba 四个通道的数值。取值范围均在 [0,1] 之间,相当于对 [0~255] 表明的色彩进行单位化:

Flutter & GLSL - 贰 |  从坐标到色彩


2. 认识上色器代码

下面是一个最简略的 GLSL 上色器代码,永远输出单一的色彩:

  • #version 460 core : 是声明 GLSL 的版别。
  • precision mediump float; : 声明浮点数的精度。
  • out 关键字用于界说输超卓彩,这儿四维向量 fragColor 表明输超卓。
  • main 函数中的代码是将被运行在 GPU 上的上色程序。
---->[shaders/color.frag]----
#version 460 core
precision mediump float;
out vec4 fragColor;
void main() {
    fragColor = vec4(5, 83, 177, 255) / 255;
}

这儿为 fragColor 赋值为拾取的色彩,即可展示出对应的蓝色:

Flutter & GLSL - 贰 |  从坐标到色彩


3. 坐标的运用

上面每个像素坐标输超卓全是一种,未免有些单调。现在来了解一下坐标在 GLSL 程序中的效果,完结下面的小需求:

将小于宽度一半的区域着成 蓝色 ;大于宽度一半的区域着成 赤色

Flutter & GLSL - 贰 |  从坐标到色彩

在 Flutter 的上色器中,引进 <flutter/runtime_effect.glsl> 经过 FlutterFragCoord() 得到坐标。在上色器程序执行时,会 逐一扫描 区域内的每一个像素,输超卓彩。
比如这儿画板的尺度是 400*200,一共有 80000 的像素点,这段上色器代码的功能便是为这 80000 个像素安排色彩。

Flutter & GLSL - 贰 |  从坐标到色彩

下面代码中 coo 表明当时运算像素的坐标,咱们能够很轻松地根据 coo.x 横坐标进行校验:小于 200 输超卓设为蓝色;大于或等于 200 ,输超卓设为赤色。 即可完结需求:

#version 460 core
precision mediump float;
#include <flutter/runtime_effect.glsl>
out vec4 fragColor;
void main() {
    vec2 coo = FlutterFragCoord().xy;
    if (coo.x < 200) {
        fragColor = vec4(4, 83, 177, 255) / 255;
    } else {
        fragColor = vec4(218, 13, 21, 255) / 255;
    }
}

同理,咱们能够根据对坐标的控制。在屏幕上输出四种色彩,如下所示:

Flutter & GLSL - 贰 |  从坐标到色彩

#version 460 core
precision mediump float;
#include <flutter/runtime_effect.glsl>
out vec4 fragColor;
vec4 blue = vec4(4, 83, 177, 255) / 255;
vec4 red = vec4(218, 13, 21, 255) / 255;
vec4 yellow = vec4(250, 193, 21, 255) / 255;
vec4 green = vec4(38, 152, 70, 255) / 255;
void main() {
    vec2 coo = FlutterFragCoord().xy;
    if(coo.x<200){
        if(coo.y<100){
            fragColor = blue;
        }else{
            fragColor = red;
        }
    }else {
        if(coo.y<100){
            fragColor = yellow;
        }else{
            fragColor = green;
        }
    }
}

4. 坐标的归一化

在上面的核算中,咱们运用了画布尺度参与核算。这并不是很好,因为画板的尺度能够随意地变化,想让一个上色器具有普适性,一般会将坐标系归一,也便是横纵坐标都在 [0~1] 之间。完结归一也很简略,只要将坐标除以尺度即可:

Flutter & GLSL - 贰 |  从坐标到色彩

如下现在界说了 vec2 size, coo 坐标在核算时除以尺度,就能够单位化。下面的指示器代码中,将赤色值设置为 coo.x ,就能够得到如下的黑到红的渐变色,想一想这是为什么呢?

Flutter & GLSL - 贰 |  从坐标到色彩

#version 460 core
precision mediump float;
#include <flutter/runtime_effect.glsl>
out vec4 fragColor;
void main() {
    vec2 size = vec2(400.0,200.0);
    vec2 coo = FlutterFragCoord().xy/size;
    fragColor = vec4(coo.x,0.0,0.0,1.0);
}

想象一下:

上色器代码逐行地核算区域内每一个像素的色彩,每一行中 coo.x 此时将从 [0~1] 改动。
坐标为 0 时色彩是 0,0,0,1 黑色;
坐标为 1 时,色彩是 1,0,0,1 赤色;中间不断是 [0~1] 的过渡渐变。


相信经过这几个小例子,咱们应该理解在 GLSL 上色器代码中坐标和色彩的效果了。或许有人会说,你最终界说的 size 不也是写死的嘛,别着急,下一篇将介绍如何经过 Flutter 代码,向 GLSL 代码传递参数。本篇就到这儿,谢谢观看 ~