返回
WebGL起飞:3D编程的序曲
前端
2024-03-11 02:52:47
3D编程的黎明:从灯泡到像素
计算机图形学的曙光微露于一盏闪烁的灯泡。程序员操纵这些灯泡,创造出光点和符号,将计算结果呈现给用户。这种"灯泡编程"揭开了计算机图形学的序幕。
WebGL:3D世界的画笔
随着时代的变迁,WebGL应运而生,为Web浏览器赋予了3D渲染能力。WebGL使用JavaScript作为编程语言,让开发者可以在浏览器中创建交互式的3D场景。
WebGL的力量:解锁3D可能性
WebGL赋予开发者构建令人惊叹的3D体验的能力。从逼真的游戏到交互式数据可视化,WebGL无处不在。它的轻量级和跨平台性使其成为3D编程的理想选择。
掌握计算机图形学:3D编程的垫脚石
深入理解计算机图形学是3D编程的关键。它涵盖了渲染、光照、纹理贴图等基本概念。通过掌握这些概念,开发者可以创造出视觉震撼的3D效果。
点燃你的3D编程激情
踏入3D编程的奇妙世界,你需要点燃自己的激情。从学习WebGL基础知识开始,逐步探索它的高级特性。在线教程、社区论坛和大量代码示例将成为你的向导。
示例代码:旋转立方体
// 创建 WebGL 画布
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
// 定义立方体顶点坐标
const vertices = [
-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1,
-1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1,
-1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1
];
// 定义立方体索引
const indices = [
0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7,
8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15
];
// 创建 WebGL 缓冲区对象
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
// 编译着色器程序
const vertexShader = compileShader(gl, gl.VERTEX_SHADER, `
attribute vec3 aPosition;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
void main() {
gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0);
}
`);
const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
// 获取 uniform 变量的位置
const modelViewMatrixLocation = gl.getUniformLocation(program, 'uModelViewMatrix');
const projectionMatrixLocation = gl.getUniformLocation(program, 'uProjectionMatrix');
// 创建模型视图矩阵和投影矩阵
const modelViewMatrix = mat4.create();
const projectionMatrix = mat4.create();
// 设置视口和清除颜色
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// 设置深度测试
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
// 绑定顶点位置属性
const positionAttributeLocation = gl.getAttribLocation(program, 'aPosition');
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionAttributeLocation);
// 主循环
function render() {
requestAnimationFrame(render);
// 更新模型视图矩阵
mat4.translate(modelViewMatrix, modelViewMatrix, [0.0, 0.0, -6.0]);
mat4.rotateX(modelViewMatrix, modelViewMatrix, degToRad(0.03));
mat4.rotateY(modelViewMatrix, modelViewMatrix, degToRad(0.05));
// 更新投影矩阵
mat4.perspective(projectionMatrix, degToRad(45.0), canvas.width / canvas.height, 0.1, 100.0);
// 传递 uniform 变量
gl.uniformMatrix4fv(modelViewMatrixLocation, false, modelViewMatrix);
gl.uniformMatrix4fv(projectionMatrixLocation, false, projectionMatrix);
// 绘制立方体
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
}
render();
// 编译着色器
function compileShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error('Error compiling shader: ', gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
// 度数转弧度
function degToRad(degrees) {
return degrees * Math.PI / 180.0;
}
拥抱3D编程的未来
WebGL为3D编程带来了无限可能。作为一名技术博客创作专家,我鼓励你踏上这段充满创造力和满足感的旅程。在3D图形学的海洋中遨游,释放你的想象力,打造非凡的3D体验。