返回
CG 技术科普:一晃一颤,好个 Q 弹布丁!
IOS
2023-10-23 16:43:05
我们知道,布丁在外力的作用下,很容易发生形变。并且,由于布丁具有弹性,在形变之后会来回晃动。今天我们用 Shader 来模拟布丁晃动的效果。
入门
一开始,我们拿到的只是一张静态的图片。所以第一步要做的,是确定布丁在图片的哪个区域。先来明确下思路:布丁的位置和形状由用户来确定,需要通过鼠标或者触控笔来指定。
指定好布丁的位置和形状后,就可以开始编写着色器了。
编写着色器
首先,我们需要定义一些变量。这些变量将用于存储布丁的位置、形状、颜色以及其他属性。
uniform vec2 u_position; // 布丁的位置
uniform vec2 u_size; // 布丁的大小
uniform vec3 u_color; // 布丁的颜色
uniform float u_time; // 当前时间
接下来,我们需要定义一个函数来计算布丁的形变。这个函数将根据布丁的位置、形状、颜色以及当前时间来计算出布丁的顶点坐标。
vec3 deform(vec2 uv) {
// 计算布丁的形变
float dx = uv.x - u_position.x;
float dy = uv.y - u_position.y;
float r = sqrt(dx * dx + dy * dy);
float a = atan2(dy, dx);
float f = sin(r * u_time * 10.0) * 0.1;
return vec3(dx + f * cos(a), dy + f * sin(a), 0.0);
}
最后,我们需要定义一个函数来绘制布丁。这个函数将根据布丁的顶点坐标和颜色来绘制出布丁。
void drawPudding() {
// 绘制布丁
glBegin(GL_TRIANGLE_FAN);
glColor3f(u_color.r, u_color.g, u_color.b);
for (float i = 0.0; i < 2.0 * PI; i += 0.1) {
vec2 uv = vec2(cos(i), sin(i)) * u_size * 0.5;
glVertex3f(deform(uv).x, deform(uv).y, 0.0);
}
glEnd();
}
运行着色器
编写好着色器后,就可以运行着色器了。我们可以使用 WebGL 来运行着色器。
// 创建 WebGL 上下文
const gl = canvas.getContext("webgl");
// 编译着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
// 创建程序对象
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
// 使用程序对象
gl.useProgram(program);
// 设置uniform变量
gl.uniform2f(gl.getUniformLocation(program, "u_position"), 0.5, 0.5);
gl.uniform2f(gl.getUniformLocation(program, "u_size"), 0.5, 0.5);
gl.uniform3f(gl.getUniformLocation(program, "u_color"), 1.0, 0.0, 0.0);
gl.uniform1f(gl.getUniformLocation(program, "u_time"), 0.0);
// 绘制布丁
drawPudding();
结语
通过上面的步骤,我们就实现了用 GLSL 来模拟布丁晃动的效果。这个效果可以用于游戏、动画和其他数字艺术作品中。