04 绘制正方体和位移矩阵
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了04 绘制正方体和位移矩阵相关的知识,希望对你有一定的参考价值。
我们首先绘制一个正方体,它有8个顶点,6个面。每个面由2个三角形组成,一共12个三角形,所以顶点索引是12个。为了保证所有的面向外,三角形顶点顺序由前面介绍的右手定则确定。
生成正方体后,我们给它加一个位移矩阵。使用矩阵表示位移是非常不直观的,所以我们借助THREEJS,将欧拉角转换为矩阵,然后传递给着色器程序。着色器程序只要简单左乘顶点坐标就好了。借助上一节贴图的知识,我们可以给正方体六个面贴图,这里为了程序简洁明了,就不示范了。
1 <!DOCTYPE html> 2 3 <html lang="zh-CN"> 4 5 <head> 6 <meta charset="UTF-8" /> 7 <title>04_绘制正方体和位移矩阵</title> 8 <script src="../js/three.js"></script> 9 10 <!-- 顶点着色器 --> 11 <script id="shader-vs" type="x-shader/x-vertex"> 12 attribute vec3 aVertexPosition; // 顶点坐标 13 uniform mat4 uMVMatrix; // 位移矩阵 14 15 void main(void) { 16 gl_Position = uMVMatrix * vec4(aVertexPosition, 1.0); 17 } 18 </script> 19 20 <!-- 片源着色器 --> 21 <script id="shader-fs" type="x-shader/x-fragment"> 22 precision mediump float; 23 varying vec4 vColor; 24 25 void main(void) { 26 gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); 27 } 28 </script> 29 30 <script type="text/javascript"> 31 var start = function () { 32 // 上下文环境 33 var canvas = document.getElementById("mycanvas"); 34 var gl = canvas.getContext("experimental-webgl"); 35 gl.viewportWidth = canvas.width; 36 gl.viewportHeight = canvas.height; 37 gl.viewport(0, 0, gl.viewportWidth, gl.viewportWidth); 38 gl.clearColor(0.0, 0.0, 0.0, 1.0); 39 gl.enable(gl.DEPTH_TEST); 40 41 // 顶点着色器 42 var shader = gl.createShader(gl.VERTEX_SHADER); 43 gl.shaderSource(shader, document.getElementById(‘shader-vs‘).innerHTML); 44 gl.compileShader(shader); 45 var vertexShader = shader; 46 47 // 片源着色器 48 var shader = gl.createShader(gl.FRAGMENT_SHADER); 49 gl.shaderSource(shader, document.getElementById(‘shader-fs‘).innerHTML); 50 gl.compileShader(shader); 51 var fragmentShader = shader; 52 53 // 着色器程序 54 var shaderProgram = gl.createProgram(); 55 gl.attachShader(shaderProgram, vertexShader); 56 gl.attachShader(shaderProgram, fragmentShader); 57 gl.linkProgram(shaderProgram); 58 gl.useProgram(shaderProgram); 59 60 // 获取参数地址 61 var vertexPositionAttr = gl.getAttribLocation(shaderProgram, ‘aVertexPosition‘); 62 gl.enableVertexAttribArray(vertexPositionAttr); 63 var mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); 64 65 // 顶点 66 var vertices = [ 67 // 前面四个顶点 68 -0.5, -0.5, -0.5, 69 0.5, -0.5, -0.5, 70 0.5, 0.5, -0.5, 71 -0.5, 0.5, -0.5, 72 73 // 后面四个顶点 74 -0.5, -0.5, 0.5, 75 0.5, -0.5, 0.5, 76 0.5, 0.5, 0.5, 77 -0.5, 0.5, 0.5, 78 ]; 79 var vertexPositionBuffer = gl.createBuffer(); 80 gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer); 81 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 82 83 // 索引 84 var vertexIndices = [ 85 // 前面 86 0, 1, 2, 87 0, 2, 3, 88 89 // 后面 90 4, 5, 6, 91 4, 6, 7, 92 93 // 左面 94 4, 0, 3, 95 4, 3, 7, 96 97 // 右面 98 1, 5, 6, 99 1, 6, 2, 100 101 // 上面 102 3, 2, 6, 103 3, 6, 7, 104 105 // 下面 106 0, 1, 5, 107 0, 5, 4 108 ]; 109 var vertexIndexBuffer = gl.createBuffer(); 110 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer); 111 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexIndices), gl.STATIC_DRAW); 112 113 // 渲染循环 114 var x = 0, y = 0, z = 0; 115 var render = function () { 116 // 清屏 117 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 118 119 // 顶点 120 gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer); 121 gl.vertexAttribPointer(vertexPositionAttr, 3, gl.FLOAT, false, 0, 0); 122 123 // 位移矩阵 124 var euler = new THREE.Euler(x, y, z); 125 var mat = new THREE.Matrix4(); 126 mat.makeRotationFromEuler(euler); 127 gl.uniformMatrix4fv(mvMatrixUniform, false, mat.toArray()); 128 129 // 绘制 130 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer); 131 gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0); 132 133 x += 0.01; 134 y += 0.01; 135 z += 0.01; 136 requestAnimationFrame(render); 137 } 138 render(); 139 } 140 </script> 141 </head> 142 143 <body onload="start();"> 144 <canvas id="mycanvas" style="border: none;" width="500" height="500"></canvas> 145 </body> 146 147 </html>
效果图:
参考资料:
Lesson4 真正的3D物体:http://www.hiwebgl.com/?p=186
THREEJS官网:https://threejs.org/
以上是关于04 绘制正方体和位移矩阵的主要内容,如果未能解决你的问题,请参考以下文章