Flutter & GLSL#9 | 函数曲线

张风捷特烈 Flutter & GLSL 系列文章:

案例代码开源地址 【skeleton】


1. 复习 smoothstep 函数

第六篇 中,我们已经认识了 smoothstep 函数,它可以让一指定的区间内平滑过渡。下面先通过一个小例子回顾一下:

左图 smoothstep(0.4, 0.4 + 0.1, coo.y)

表示: 纵坐标小于 0.4 时,返回 0 展示黑色;纵坐标大于 0.5 时,返回 1 展示白色。在 [0.4,0.5] 之间平滑过渡。

y= 0.4 y= 0.8

我们将 0.4 记为一个变量值 y, 那么 smoothstep(y, y + 0.1, coo.y) 就可以表示:

y 在 [0,y) 返回 0 展示黑色。

y 在 [y,y+0.1] 之间从 0~1 平滑过渡。

y 在 (y+0.1,1] 返回 1 展示白色.

上面右图中 y=0.8 时,就可以将黑色区域下移:

c 复制代码
#version 460 core
#include <flutter/runtime_effect.glsl>
precision mediump float;

out vec4 fragColor;
uniform vec2 uSize;

void main() {
    vec2 coo = FlutterFragCoord() / uSize;
    float y = 0.4;
    //float y = 0.8;
    float ret = smoothstep(y, y + 0.1, coo.y);
    fragColor = vec4(vec3(ret), 1.0);
}

同理我们可以分析出 smoothstep(y-0.1, y, coo.y) 就可以表示:

y 在 [0,y-0.1) 返回 0 展示黑色。

y 在 [y-0.1,y] 之间从 0~1 平滑过渡。

y 在 (y,1] 返回 1 展示白色.

smoothstep(y, y + 0.1, coo.y) smoothstep(y - 0.1, y, coo.y)

仔细观察这两个图,想一想,如果让右侧减去左侧会发生什么呢?

提示:黑色是 0,白色时 1 ,渐变是 0~1 之间.


2. 生成线条

白色区域相减 1-1 =0 ,会呈现黑色,黑色区域 0 - 0 也是黑色。左侧白色区域减去过渡区域,相当于 1-过渡值,也就是反向过渡。左侧过渡区域对应的右侧是黑色,也就是减 0 ,保持不变。于是乎可以得到如下的光线。当控制 y 的数值,可以控制光线在的纵向位置:

y=0.4 y=0.8
dart 复制代码
#version 460 core
#include <flutter/runtime_effect.glsl>
precision mediump float;

out vec4 fragColor;
uniform vec2 uSize;


void main() {
    vec2 coo = FlutterFragCoord() / uSize;
    float y = 0.8;
    float ret0 = smoothstep(y, y + 0.1, coo.y);
    float ret1 = smoothstep(y - 0.1, y, coo.y);
    float ret =  ret1-ret0;
    fragColor = vec4(vec3(ret), 1.0);
}

如果我们把过渡区域改小,就可以看到更明显的线条。顺便可以把光线的生成逻辑封装成一个函数,效果如下:

y=0.4 y=0.8
c 复制代码
#version 460 core
#include <flutter/runtime_effect.glsl>
precision mediump float;

out vec4 fragColor;
uniform vec2 uSize;

float plot(vec2 coo, float y, float e) {
    float ret0 = smoothstep(y, y + e, coo.y);
    float ret1 = smoothstep(y - e, y, coo.y);
    return ret1 - ret0;
}

void main() {
    vec2 coo = FlutterFragCoord() / uSize;
    float y = 0.4;
    float ret = plot(coo,y,0.005);
    fragColor = vec4(vec3(ret), 1.0);
}

3. 函数曲线

上面只是画了一条线,那这和函数曲线有什么关系呢?其实仔细信息,上面的曲线不就是 y =0.4 这个特殊函数的曲线表现吗?如果我们通过 coo.x 控制 y 的数值,会发生什么化学反应呢? 比如我们最熟悉的 y = x:

c 复制代码
#version 460 core
#include <flutter/runtime_effect.glsl>
precision mediump float;

out vec4 fragColor;
uniform vec2 uSize;

float plot(vec2 coo, float y, float e) {
    float ret0 = smoothstep(y, y + e, coo.y);
    float ret1 = smoothstep(y - e, y, coo.y);
    return ret1 - ret0;
}

void main() {
    vec2 coo = FlutterFragCoord() / uSize;
    float x = coo.x;
    float y = x;
    float ret = plot(coo,y,0.005);
    fragColor = vec4(vec3(ret), 1.0);
}

这样我们就可以设置任意的函数,通过自变量 x 的变化,影响 y 值:

y=x^2 y = 0.2*sin(16*x)+0.5

小彩蛋 : 仔细想一想,其实 smoothstep 本身就是一个函数,他将输入值转为输出。通过如下的函数,我们就可以非常直观地看出 smoothstep 的过渡效果:

float y = smoothstep(0, 1, coo.x);


本篇主要通过两个 smoothstep 相减生成线条,通过函数关系,来构造对应的函数曲线线条。还是非常有意思的,理解本篇内容,你将会对 smoothstep 函数有一个更深的认识。那么本篇就到这里,谢谢观看,我们下次再见 ~

相关推荐
双鱼大猫12 分钟前
一句话说透Android里面的ServiceManager的注册服务
android
双鱼大猫1 小时前
一句话说透Android里面的Window的内部机制
android
怪怪王1 小时前
【GPU驱动】OpenGLES图形管线渲染机制
驱动开发·gpu·opengl
双鱼大猫1 小时前
一句话说透Android里面的为什么要设计Window?
android
双鱼大猫1 小时前
一句话说透Android里面的主线程创建时机,frameworks层面分析
android
苏金标2 小时前
android 快速定位当前页面
android
Zsnoin能4 小时前
flutter国际化、主题配置、视频播放器UI、扫码功能、水波纹问题
flutter
早起的年轻人4 小时前
Flutter CupertinoNavigationBar iOS 风格导航栏的组件
flutter·ios
HappyAcmen4 小时前
关于Flutter前端面试题及其答案解析
前端·flutter
雾里看山5 小时前
【MySQL】内置函数
android·数据库·mysql