1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body> <div style="width:600px;height: 400px;"> <canvas id="canvas" width="600" height="400"></canvas> </div>
<script> try { const canvas = document.querySelector('#canvas'); const gl = canvas.getContext('webgl'); if (!gl) { throw new Error('浏览器不支持webgl'); } else { const vertexShaderSource = ` attribute vec2 a_position; void main() { gl_Position = vec4(a_position, 0.0, 1.0); } `; const fragmentShaderSource = ` precision mediump float; // 精度声明(必须?) uniform vec2 u_resolution; // 画布分辨率 uniform float u_time; // 时间 void main() { vec2 uv = gl_FragCoord.xy / u_resolution; gl_FragColor = vec4(1., uv.y, uv.y, 1.0); } `; const compileShader = (gl, source, type) => { const shader = gl.createShader(type); if (!shader) return null; gl.shaderSource(shader, source); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { console.error('着色器编译失败:', gl.getShaderInfoLog(shader)); gl.deleteShader(shader); return null; } return shader; } const createProgram = (gl, vertexShader, fragmentShader) => { const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { console.error('程序链接失败:', gl.getProgramInfoLog(program)); gl.deleteProgram(program); return null; } return program; } const vertexShader = compileShader(gl, vertexShaderSource, gl.VERTEX_SHADER); const fragmentShader = compileShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER); if (!vertexShader || !fragmentShader) throw new Error('着色器编译失败'); const program = createProgram(gl, vertexShader, fragmentShader); if (!program) throw new Error('程序创建失败')
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); const aPositionLoc = gl.getAttribLocation(program, 'a_position'); gl.vertexAttribPointer(aPositionLoc, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(aPositionLoc); const uResolutionLoc = gl.getUniformLocation(program, 'u_resolution'); const uTimeLoc = gl.getUniformLocation(program, 'u_time'); const render = () => { gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); gl.clearColor(0, 0, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); gl.useProgram(program);
gl.uniform2f(uResolutionLoc, canvas.width, canvas.height); const time = performance.now() / 1000; gl.uniform1f(uTimeLoc, time); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(render); } render(); } } catch (error) { console.log(error) const span = document.createElement('span'); span.innerText = error.message || JSON.stringify(error); document.body.appendChild(span); } </script> </body>
</html>
|