GLSL
宏
#ifdef GL_ESprecision mediump float;#endif基础数据类型
传递数据
Uniform
JS 可以向 Vertex Shader、Fragment Shader 传值
uniform vec3 u_resolution;const uResolution = gl.getUniformLocation(program, "u_resolution");gl.uniform3f(uResolution, 400.0, 400.0, 400.0);Attribute
JS 只可以向 Vertex Shader 传值;Vertex Shader 可以向 Fragment Shader 传值
#version 300 es
in vec3 a_position;
out vec4 v_color; // 线 fragment shader 输出const positionLoc = gl.getAttribLocation(program, "aPosition");gl.enableVertexAttribArray(positionLoc);gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 0, 0);Vertex Shader
#version 300 es
in vec4 a_Position; // 表示通过GPU传递过来的顶点,法线等数据
void main(){ gl_Position = a_Position; // gl_Position 为顶点着色器的默认输出}内置变量
- gl_Position:顶点坐标
Fragment Shader
#version 300 es
precision highp float; // 精度
uniform sampler2D u_image0; // 纹理
out vec4 out_color;
void main() { out_color = vec4(0, 0, 0, 1);}内置变量
- gl_FragCoord:表示当前的窗口二位坐标,左下角为原点 (0, 0),x 轴向右为正方向,y 轴向上为正方向
- gl_FragColor:导出颜色,也可以直接赋值给他,内置变量,但是 out 语法能导出多个值
计算
ceil
向上取整
result = step($x);step
val 为阈值,x 输出值
- 如果 输入值 < 阈值,return 0
- 如果 输入值 >= 阈值,return 1
result = step($val, $x);fract
返回小数部分,不论正负,fract 的返回值为 [0,1)
result = fract($x);场景
- 将递增的数,编程周期性的数
clamp
返回数的整数部分
result = clamp($x);pow
result = pow($x, $y); // x^ymix
插值函数,result = x * (1 - a) + y * a
result = mix($x, $y, $a)smoothstep
平滑过渡
- 如果 x 处于 [edge0, edge1] 时,输出 [0, 1]
- 如果 x < edge0,则输出 0
- 如果 x > edge1,则输出 1
result = smoothstep($edge0, $edge1, $x);distance
result = distance($x, $y);length
向量的模
result = length($x);三角函数
tan($x);atan($y, $x); // 反正切
sin($x);asin($x);
cos($x);acos($x);<<<<<<< HEAD
normalize
归一化,使得向量的模为 1
result = normalize($1);加减乘除余
// + - * /
result = cross($x, $y); // 叉乘
result = dot($x, $y); // 点乘
result = mod($x, $y);=======
导数
计算变量,相对于屏幕的x,y轴的变化率,即偏导函数
# dFdx(p) 计算的是当前片段的 p 值与屏幕空间中 x 轴正方向相邻片段的 p 值之差# dFdy(p) 计算的是当前片段的 p 值与屏幕空间中 y 轴正方向相邻片段的 p 值之差Type dFdx(Type p);Type dFdy(Type p);纹理
用于边缘检测,例如检测纹理的边缘,用于抗锯齿
vec4 color = texture(image0, uv);cross
估算法线
cross(dFdx(position), dFdy(position))
// 估计LOD,需要根据纹理在屏幕上的投影大小选择合适的 Mipmap 层级// 通过计算纹理坐标 uv 的屏幕空间导数 dFdx(uv) 和 dFdy(uv),可以估算出当前片元覆盖了多少纹理像素(Texel)discard
抛弃该片元
fdf34fae1bd85d604b44f19ebabf36b9fdd3c5a7