提示
教程例子都可以到下面网址进行运行,不需要另外安装软件环境:
官方提供在线编写shader工具:https://thebookofshaders.com/edit.php
glslsandbox网站:http://glslsandbox.com/
shadertoy网站:https://www.shadertoy.com/
本文提到的关键字
关键字 | 描述 | 图像 |
---|---|---|
y = mod(x,0.5); | 返回 x 对 0.5 取模的值 | |
y = fract(x); | 仅仅返回数的小数部分 | |
y = ceil(x); | 向上取整 | |
y = floor(x); | 向下取整 | |
y = sign(x); | 提取 x 的正负号 | |
y = abs(x); | 返回 x 的绝对值 | |
y = min(0.0,x); | 返回 x 和 0.0 中的较小值 | |
y = max(0.0,x); | 返回 x 和 0.0 中的较大值 | |
y = clamp(x,0.0,1.0); | 把 x 的值限制在 0.0 到 1.0 | |
y = sin(x); | 正弦函数 | |
smoothstep | 获得0~1之间的平滑过度 | |
- | smoothstep( 0., 1., .0) | |
- | smoothstep( 0., 1., 1.) | |
- | smoothstep( 0., 1., .5) | |
- | smoothstep( 0., st.x, .01) | st.x小于0.01时输出1,st.x大与0.01时,输出区间曲线,右侧的黑块是无限趋近于0的,但并不是0,因为通过公式可以算出插值结果只是趋于0 |
- | smoothstep( st.x, st.x, .01) | 这个理解更简单了,只要st.x小于0.01, 就输出1, 只要大于0.01就输出0。这时候如果将下限改小,则会增大过度区间,增大方向为0.01的右侧 |
- | smoothstep( st.x-0.02, st.x, st.y) | 上面公式看懂后,这个公式就简单了,由于第三个参数是动态的,则这个插值是随着y的增大而向右倾斜的 |
- | 1.-smoothstep( st.x-0.02, st.x, st.y) | 获得反转的图像结果 |
- | smoothstep( st.x-0.02, st.x, st.y)-smoothstep( st.x, st.x+0.02, st.y) | 获得两个面积的公共区域,这就是下面例子得到的值 |
step(a,b) | 如果ba输出1 |
亮度渐变、绘制一条绿色的线
#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, float pct){
return smoothstep( pct-0.020, pct+-0.004, st.y) -
smoothstep( pct, pct+0.02, st.y);
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution;
float y = st.x;
vec3 color = vec3(y);
// Plot a line
float pct = plot(st,y);
color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0);
gl_FragColor = vec4(color,1.0);
}
黑白过度填充
vec2 st = gl_FragCoord.xy/u_resolution;
float y = st.x;
vec3 color = vec3(y);
gl_FragColor = vec4(color,1.0);
绘制绿线
vec2 st = gl_FragCoord.xy/u_resolution;
float y = st.x;
float pct = plot(st,y);
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){
return smoothstep( pct-0.02, pct, st.y) -
smoothstep( pct, pct+0.02, st.y);
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution;
float y = pow(st.x,5.0);
vec3 color = vec3(y);
float pct = plot(st,y);
color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0);
gl_FragColor = vec4(color,1.0);
}
不难理解 pow(st.x,5.0)可以获得抛物线了
step
···
ifdef GL_ES
precision mediump float;
endif
define PI 3.14159265359
uniform vec2 u_resolution;
uniform float u_time;
float plot(vec2 st, float pct){
return smoothstep( pct-0.02, pct, st.y) -
smoothstep( pct, pct+0.02, st.y);
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution;
// Step will return 0.0 unless the value is over 0.5,
// in that case it will return 1.0
float y = step(0.5,st.x);
vec3 color = vec3(y);
float pct = plot(st,y);
color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0);
gl_FragColor = vec4(color,1.0);
}
···
函数图形
多项式造型函数
指数造型函数
圆与椭圆的造型函数
贝塞尔造型函数
Iñigo Quiles 收集了一套有用的函数
公式表
Grapher
如果你是用 MacOS 系统,用 spotlight 搜 grapher 就会看到这个超级方便的工具了。
GraphToy
仍然是 Iñigo Quilez 为大家做的工具,用于在 WebGL 中可视化 GLSL 函数。
Shadershop
这个超级棒的工具是 Toby Schachman 的作品。它会以一种极其视觉化和直观的方式教你如何建造复杂的函数。