使用shader造型函数绘制图形

本文围绕使用shader造型函数绘制图形展开。先介绍了shader片段着色器基础,包括并行处理结构、Uniforms和gl_FragCoord。接着阐述使用smoothstep、step等函数绘制圆、直线、矩形、网格等图形的方法,还提及偏移图案、Truchet瓷砖绘制,最后介绍符号距离场渲染SDF在图形绘制中的应用。

使用shader造型函数绘制图形

1.shader片段着色器基础

[1]片段着色器的并行处理结构

在这里插入图片描述

片段着色器并行处理(parallel processing)为了能使许多管线并行运行,每一个线程必须与其他的相独立,因此也出现了很多限制:

  • 所有数据必须以相同的方向流动
  • 无法检查其他线程的输出结果,修改输入的数据,或者把一个线程的输出结果输入给另一个线程

简单理解:屏幕中的每个像素都会执行一次片段着色器代码(同时执行),没有执行先后的概念

[2]Uniforms

可以把 uniforms 想象成连通 GPU 和 CPU 的许多小的桥梁,尽管每个线程和其他线程之间不能有数据交换,但我们能从CPU给每个GPU线程输入数据。因为显卡的架构,所有线程的输入值必须统一(uniform),而且必须设为只读。也就是说,每条GPU线程接收相同的数据,并且是不可改变的数据。

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution; //画布尺寸vec2(宽,高)
uniform vec2 u_mouse; //鼠标位置vec2(在屏幕中的那个位置)
uniform float u_time; //shader运行时间(加载后的秒数)

void main() {
    gl_FragColor = vec4(abs(sin(u_time)),0.0,0.0,1.0);
}

[3]gl_FragCoord

gl_FragCoord存储了活动线程正在处理的像素屏幕碎片的坐标,有了它我们就知道了屏幕上的哪一个线程正在运转。因为是并行处理的,将其理解为屏幕的每个像素坐标

下面用图快速理解归于化代码vec2 st = gl_FragCoord.xy/u_resolution.xy;

在这里插入图片描述

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution; //画布尺寸(宽,高)
uniform vec2 u_mouse; //鼠标位置(在屏幕中的那个位置)
uniform float u_time; //shader运行时间(加载后的秒数)

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    gl_FragColor = vec4(st.x,st.y,0.0,1.0);
}

gl_FragCoord获取到屏幕的每个坐标,除于u_resolution,对坐标进行了规范化。这样做是为了使所有的值落在 0.0 到 1.0 之间,这样就可以轻松把 X 或 Y 的值映射到红色或者绿色通道。

是不是和之前的编程有所不同?想想shader 的并行处理特性,是不是很🐱!,最后渲染出来的图:

在这里插入图片描述

是根据屏幕坐标的变化来渲染不同的颜色值

[2]

绘制 y = x , y = x 5 y=x,y=x^5 y=xy=x5函数的线

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

// Plot a line on Y using a value between 0.0-1.0
float plot(vec2 st) {    
    //(max,min,value情况) value=0->return 1; value>0.02->return 0
    return smoothstep(0.02, 0.0, abs(st.y - st.x));
}

void main() {
	vec2 st = gl_FragCoord.xy/u_resolution;

    float y = st.x; //沿x渐变

    vec3 color = vec3(y);

    // Plot a line
    float pct = plot(st);
    color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0);

	gl_FragColor = vec4(color,1.0);
}
#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.14159265359

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

float plot(vec2 st, float pct){
   // //0.2则是线宽
  return  smoothstep( pct-0.02, pct, st.y) -
          smoothste
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

seeooco

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值