1. 准备一个HTML文件:创建一个新的HTML文件,将 HTML 文件命名为 `index.html`,并添加一个用于显示图形的元素。

Simple WebGL Renderingbody { margin: 0; }canvas { width: 100%; height: 100%; }

2. 创建JavaScript文件:创建一个名为`script.js`的 JavaScript 文件来处理图形的渲染逻辑。

// 获取canvas元素const canvas = document.getElementById("canvas");// 创建WebGL上下文const gl = canvas.getContext("webgl");// 定义顶点着色器代码const vertexShaderSource = `attribute vec2 position;void main() {gl_Position = vec4(position, 0.0, 1.0);}`;// 创建顶点着色器const vertexShader = gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader, vertexShaderSource);gl.compileShader(vertexShader);// 检查顶点着色器是否编译成功if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {console.error("Vertex shader compilation error:", gl.getShaderInfoLog(vertexShader));}// 定义片段着色器代码const fragmentShaderSource = `precision mediump float;void main() {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}`;// 创建片段着色器const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader, fragmentShaderSource);gl.compileShader(fragmentShader);// 检查片段着色器是否编译成功if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {console.error("Fragment shader compilation error:", gl.getShaderInfoLog(fragmentShader));}// 创建着色器程序const shaderProgram = gl.createProgram();gl.attachShader(shaderProgram, vertexShader);gl.attachShader(shaderProgram, fragmentShader);gl.linkProgram(shaderProgram);// 使用着色器程序gl.useProgram(shaderProgram);// 渲染图形const vertices = [-0.5, -0.5,0.5, -0.5,0.0, 0.5];const vertexBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);const positionAttributeLocation = gl.getAttribLocation(shaderProgram, "position");gl.enableVertexAttribArray(positionAttributeLocation);gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);gl.clearColor(0, 0, 0, 1);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);

运行成功页面

一个简单的glsl小实验成功了,不过我想要这个三角形动起来。

修改后的script代码如下

// 获取画布元素和 WebGL 上下文var canvas = document.getElementById("canvas");var gl = canvas.getContext("webgl");// 顶点着色器代码const vertexShaderSource = `attribute vec2 a_position;uniform vec2 u_translation;void main() {gl_Position = vec4(a_position + u_translation, 0, 1);}`;// 片段着色器代码const fragmentShaderSource = `precision mediump float;void main() {gl_FragColor = vec4(1, 0, 0, 1);}`;// 创建着色器程序var program = createProgram(gl, vertexShaderSource, fragmentShaderSource);// 获取顶点位置 attribute 的位置var positionAttributeLocation = gl.getAttribLocation(program, "a_position");// 创建并绑定顶点缓冲区var positionBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);// 定义一个简单的三角形顶点位置数组var positions = [0, 0,-0.5, -0.5,0.5, -0.5];gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);// 设置顶点属性指针gl.enableVertexAttribArray(positionAttributeLocation);gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);// 清空画布gl.clearColor(0, 0, 0, 1);// 设置着色器程序gl.useProgram(program);// 获取着色器程序中 uniform 变量的位置var translationUniformLocation = gl.getUniformLocation(program, "u_translation");// 更新平移向量function updateTranslation() {var time = new Date().getTime() * 0.001; // 获取时间并转换为秒var translation = [Math.sin(time), // x 轴上的移动,使用正弦函数模拟Math.cos(time)// y 轴上的移动,使用余弦函数模拟];gl.uniform2fv(translationUniformLocation, translation);}// 动画循环function animate() {// 清空画布gl.clear(gl.COLOR_BUFFER_BIT);// 绘制三角形gl.drawArrays(gl.TRIANGLES, 0, 3);// 更新平移向量updateTranslation();// 请求下一次动画循环requestAnimationFrame(animate);}// 开始动画循环animate();// 创建着色器程序的函数function createProgram(gl, vertexShaderSource, fragmentShaderSource) {// 创建顶点着色器和片段着色器var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);// 创建着色器程序var program = gl.createProgram();// 附加着色器到着色器程序gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);// 链接着色器程序gl.linkProgram(program);// 检查链接状态var success = gl.getProgramParameter(program, gl.LINK_STATUS);if (success) {return program;}// 链接错误,打印错误信息console.log(gl.getProgramInfoLog(program));gl.deleteProgram(program);}// 创建着色器的函数function createShader(gl, type, source) {// 创建着色器var shader = gl.createShader(type);// 附加着色器源代码到着色器gl.shaderSource(shader, source);// 编译着色器gl.compileShader(shader);// 检查编译状态var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);if (success) {return shader;}// 编译错误,打印错误信息console.log(gl.getShaderInfoLog(shader));gl.deleteShader(shader);}

运行成功截图

他现在就是一个游来游去的红色三角形了。太神奇了!~