在WebGL中绘制函数图像是一项非常有趣且具有挑战性的任务。通过使用顶点着色器和片段着色器,你可以将数学函数直接可视化在WebGL画布上。下面是一个基本的入门指南,教你如何使用WebGL来绘制简单的函数图像。
1. 准备WebGL上下文
首先,你需要一个HTML文件和一个包含WebGL上下文的<canvas>元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebGL函数图像绘制</title>
</head>
<body>
<canvas id="webgl-canvas" width="500" height="500"></canvas>
<script src="shader.js"></script>
</body>
</html>
在这个HTML文件中,<canvas>元素用于渲染图像。接下来我们需要用JavaScript代码初始化WebGL上下文。
2. 初始化WebGL
在shader.js文件中,我们首先初始化WebGL。
// 获取canvas元素
const canvas = document.getElementById('webgl-canvas');
// 获取WebGL上下文
const gl = canvas.getContext('webgl');
if (!gl) {
console.log('无法获取WebGL上下文');
throw new Error('WebGL不支持');
}
// 设置WebGL视口
gl.viewport(0, 0, canvas.width, canvas.height);
// 设置清屏颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
3. 编写顶点着色器
顶点着色器负责定义图形的几何形状。在这个例子中,我们将用简单的顶点位置来定义整个屏幕。
const vertexShaderSource = `
attribute vec4 a_Position;
void main() {
gl_Position = a_Position;
}
`;
// 创建并编译顶点着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
4. 编写片段着色器
片段着色器负责计算每个像素的颜色。在这个片段着色器中,我们可以定义一个函数,例如f(x) = sin(x),并用它来绘制图像。
const fragmentShaderSource = `
precision mediump float;
void main() {
// 获取当前片段的坐标
vec2 st = gl_FragCoord.xy / vec2(500.0, 500.0);
// 将坐标转换到[-1, 1]范围
float x = (st.x * 2.0) - 1.0;
// 定义函数 y = sin(10.0 * x)
float y = sin(10.0 * x);
// 如果当前y坐标接近函数值,则设置为白色,否则为黑色
if (abs(st.y - (y * 0.5 + 0.5)) < 0.01) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
} else {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}
`;
// 创建并编译片段着色器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
5. 创建着色器程序并绘制
将顶点和片段着色器链接到一个着色器程序中,并使用这个程序来绘制。
// 创建着色器程序
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
// 使用程序
gl.useProgram(shaderProgram);
// 定义一个覆盖整个画布的三角形
const vertices = new Float32Array([
-1.0, 1.0,
-1.0, -1.0,
1.0, 1.0,
1.0, -1.0,
]);
// 创建缓冲区
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 获取a_Position属性位置
const a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);
// 绘制图像
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
6. 完整代码
将上述代码整合在一起,你就可以在WebGL画布上绘制出函数图像。此代码绘制的是y = sin(10 * x)的图像。
7. 进阶
你可以尝试修改片段着色器中的函数,或者添加用户交互功能,来实时调整函数的形状和参数。此外,还可以实现更复杂的函数,比如多变量函数,或者使用颜色渐变来表示函数值的大小。
通过这些步骤,你可以初步掌握如何使用WebGL绘制函数图像,并为更复杂的图像渲染打下基础。