29 WebGL绘制立方体并为立方体每个表面指定颜色
案例查看地址:点击这里
顶点着色器进行的是逐顶点的计算,接收的是逐顶点的信息。如果我们要指定表面的颜色,需要将颜色定义给顶点。比如,我们要定义一个三角形为一种颜色,必须三个顶点的颜色都为一种颜色。
但是你会发现,立方体的一个顶点会在三个面中被使用,定义了一种颜色肯定会对别的面造成影响。为了解决这个问题,我们需要创建多个具有相同顶点坐标的顶点(虽然这样会造成一些冗余)。
此时的三角形列表,也就是顶点索引值序列,对每个面都指向一组不同的顶点,不在有前表面和上表面同享一个顶点的情况。这样一来,就可以实现前述的效果,为每个表面涂上不同的单色了。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Title</title><style>body {margin: 0;text-align: center;}#canvas {margin: 0;}</style>
</head>
<body οnlοad="main()">
<canvas id="canvas" height="800" width="1200"></canvas>
</body>
<script src="lib/webgl-utils.js"></script>
<script src="lib/webgl-debug.js"></script>
<script src="lib/cuon-utils.js"></script>
<script src="lib/cuon-matrix.js"></script>
<script>//顶点着色器var VSHADER_SOURCE = "" +"attribute vec4 a_Position;\n" +"attribute vec4 a_Color;\n" +"uniform mat4 u_ModelViewMatrix;\n" +"varying vec4 v_Color;\n" +"void main(){" +" gl_Position = u_ModelViewMatrix * a_Position;\n" +" v_Color = a_Color;\n" +"}\n";//片元着色器var FSHADER_SOURCE = "" +"#ifdef GL_ES\n" +"precision mediump float;\n" +"#endif\n" +"varying vec4 v_Color;\n" +"void main(){" +" gl_FragColor = v_Color;\n" +"}\n";//声明js需要的相关变量var canvas = document.getElementById("canvas");var gl = getWebGLContext(canvas);function main() {if (!gl) {console.log("你的浏览器不支持WebGL");return;}//初始化着色器if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {console.log("无法初始化着色器");return;}var n = initVertexBuffers(gl);if (n < 0) {console.log("无法创建缓冲区");return;}//设置视角矩阵的相关信息var u_ModelViewMatrix = gl.getUniformLocation(gl.program, "u_ModelViewMatrix");if (u_ModelViewMatrix < 0) {console.log("无法获取矩阵变量的存储位置");return;}//设置底色gl.clearColor(0.0, 0.0, 0.0, 1.0);//进入场景初始化draw(gl, n, u_ModelViewMatrix);}function draw(gl, n, u_ModelViewMatrix) {//设置视角矩阵的相关信息(视点,视线,上方向)var viewMatrix = new Matrix4();viewMatrix.setLookAt(3,3,7,0,0,0,0,1,0);//设置模型矩阵的相关信息var modelMatrix = new Matrix4();modelMatrix.setRotate(0, 0, 0, 1);//设置透视投影矩阵var projMatrix = new Matrix4();projMatrix.setPerspective(30,canvas.width/canvas.height,1,100);//计算出模型视图矩阵 viewMatrix.multiply(modelMatrix)相当于在着色器里面u_ViewMatrix * u_ModelMatrixvar modeViewMatrix = projMatrix.multiply(viewMatrix.multiply(modelMatrix));//将试图矩阵传给u_ViewMatrix变量gl.uniformMatrix4fv(u_ModelViewMatrix, false, modeViewMatrix.elements);//开启隐藏面清除gl.enable(gl.DEPTH_TEST);//清空颜色和深度缓冲区gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);//绘制图形gl.drawElements(gl.TRIANGLES,n,gl.UNSIGNED_BYTE,0);}function initVertexBuffers(gl) {// 创建一个立方体// v6----- v5// /| /|// v1------v0|// | | | |// | |v7---|-|v4// |/ |/// v2------v3var vertices = new Float32Array([ // 顶点的位置坐标数据1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, // v0-v1-v2-v3 front1.0, 1.0, 1.0, 1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0, // v0-v3-v4-v5 right1.0, 1.0, 1.0, 1.0, 1.0,-1.0, -1.0, 1.0,-1.0, -1.0, 1.0, 1.0, // v0-v5-v6-v1 up-1.0, 1.0, 1.0, -1.0, 1.0,-1.0, -1.0,-1.0,-1.0, -1.0,-1.0, 1.0, // v1-v6-v7-v2 left-1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,-1.0, 1.0, -1.0,-1.0, 1.0, // v7-v4-v3-v2 down1.0,-1.0,-1.0, -1.0,-1.0,-1.0, -1.0, 1.0,-1.0, 1.0, 1.0,-1.0 // v4-v7-v6-v5 back]);var colors = new Float32Array([ // 顶点的颜色0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, // v0-v1-v2-v3 front(blue)0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, // v0-v3-v4-v5 right(green)0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, // v0-v5-v6-v1 up(red)0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, // v1-v6-v7-v2 left0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, // v7-v4-v3-v2 down0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8 // v4-v7-v6-v5 back]);var indices = new Uint8Array([ // 绘制的索引0, 1, 2, 0, 2, 3, // front4, 5, 6, 4, 6, 7, // right8, 9,10, 8,10,11, // up12,13,14, 12,14,15, // left16,17,18, 16,18,19, // down20,21,22, 20,22,23 // back]);//创建缓冲区对象initArrayBuffer(gl,vertices,3,gl.FLOAT,"a_Position");initArrayBuffer(gl,colors,3,gl.FLOAT,"a_Color");//将顶点索引数据写入缓冲区对象var indexBuffer = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indices,gl.STATIC_DRAW);return indices.length;}function initArrayBuffer(gl,data,num,type,attribute) {//创建缓冲区对象var buffer = gl.createBuffer();if (!buffer) {console.log("无法创建缓冲区对象");return -1;}//绑定缓冲区对象并写入数据gl.bindBuffer(gl.ARRAY_BUFFER, buffer);gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);//获取顶点位置变量位置var a_attribue = gl.getAttribLocation(gl.program, attribute);if (a_attribue < 0) {console.log("无法获取顶点位置的存储变量");return -1;}//对位置的顶点数据进行分配,并开启gl.vertexAttribPointer(a_attribue, num, type, false, 0, 0);gl.enableVertexAttribArray(a_attribue);}
</script>
</html>
虽然本例使用的是gl.drawElements(),使用了24个顶点。而使用gl.drawArrays()绘图也就使用36个顶点。看上去没有省多少的内存开销。但是,在实际生产当中,使用gl.drawElements()还是值得的。
就这样,我们实现了绘制相同颜色的面。
29 WebGL绘制立方体并为立方体每个表面指定颜色相关推荐
- 用webgl绘制一个彩色旋转立方体
#用webgl绘制一个旋转立方体 ** 学习交流欢迎加群:789723098,博主会将一些demo整理共享 ** 今天给大家分享一个用webgl写的简单的三维场景:转动的交互式彩色立方体,其六个面的颜 ...
- WebGL绘制立方体-每个面一种颜色
WebGL绘制立方体-每个面一种颜色 本文是WebGL电子书的1.8节内容 思路很简单,在线框模式的立方体源码基础上直接进行更改,添加varying变量,引入顶点数据颜色,立方体6个面,每个面可以分为 ...
- 28 WebGL绘制立方体
案例查看地址:点击这里 到现在为止,一直学的都是绘制一些简单的三角形.下面,我们将学习如何绘制如图所示的一个立方体,目标: 如果按以前所学的知识,制作这个正方体就需要使用三角形两个拼一个矩形,最后拼出 ...
- 【视觉高级篇】20 # 如何用WebGL绘制3D物体?
说明 [跟月影学可视化]学习笔记. 如何用 WebGL 绘制三维立方体 我们知道立方体有8个顶点,6个面,在 WebGL 中,需要用 12 个三角形来绘制它.把每个面的顶点分开,需要 24 个顶点. ...
- 利用javascript和WebGL绘制地球 【翻译】
利用javascript和WebGL绘制地球 [翻译] 原翻译:利用javascript和WebGL绘制地球 [翻译] 在我们所有已知的HTML5API中,WebGL可能是最有意思的一个,利用这个AP ...
- WebGL 绘制Line的bug(一)
插播一则广告(长期有效) MONO哥需要在武汉招JavaScript工程师若干 要求:对前端技术(JavasScript.HTML.CSS),对可视化技术(Canvas.WebGL)有浓厚的兴趣 基础 ...
- 使用WebGL绘制流动虚线
使用WebGL绘制流动虚线 上文中介绍了如何在片元着色器中绘制虚线,通过计算屏幕像素到折线的距离和屏幕像素投影到折线的长度可以绘制折线. 接下来尝试使用WebGL2在canvas中绘制流动的折线. 需 ...
- webgl绘制客厅房间的家具+座椅板凳床
一.开发环境说明 开发软件:webstorm 浏览器 : 火狐firefox 编程语言:webgl 二.内容说明 1.内容要求 实现一个小型的3D客厅环境,包括对象建模.照明.摄像机设置:必须使用纯的 ...
- 【图形基础篇】04 # GPU与渲染管线:如何用WebGL绘制最简单的几何图形?
说明 [跟月影学可视化]学习笔记. 图形系统是如何绘图的? 一个通用计算机图形系统主要包括 6 个部分,分别是: 输入设备 中央处理单元:首先,数据经过 CPU 处理,成为具有特定结构的几何信息. 图 ...
最新文章
- pandas使用nlargest函数返回特定数据列中前N个最大值(搜寻最大的n个元素)、pandas使用nlargest函数返回特定数据列中前N个最大值所对应的数据行
- python listen_python socket编程中listen和accept的区别
- vba代码编程800例_VBA编程常用“积木”过程代码Address的含义
- 模拟 Codeforces Round #249 (Div. 2) C. Cardiogram
- Keepalived实现LVS-DR双机热备_2015101601
- 【C++的深度剖析教程20】类型转换函数上
- hive序列生成_常见的序列化框架及Protobuf原理
- HTML 图片加载问题
- 无法扩展该卷 因为群集的数量将超过文件系统_Ubifs文件系统分析
- UML统一建模语言(UML类图)
- Android截图功能
- [转]100个经典C语言程序(益智类问题)
- webview适配(一):文件选择,相机拍照,相册选择
- 吴翰清(道哥):我对计算的理解
- png图片转化为ico图标并保留透明背景方法
- swarm集群搭建教程
- macOS Big Sur 11.5.2 (20G95) 虚拟机 ISO 镜像
- 空气质量指数(AQI)分析与预测
- excel 2010 删除重复行(按某一列重复)
- IDL语法基础(01)