当前位置: 首页 > news >正文

使用 WebGL 创建 3D 对象

WebGL Demoicon-default.png?t=N7T8https://mdn.github.io/dom-examples/webgl-examples/tutorial/sample5/index.html

现在让我们给之前的正方形添加五个面从而可以创建一个三维的立方体。最简单的方式就是通过调用方法 gl.drawElements() 使用顶点数组列表来替换之前的通过方法gl.drawArrays() 直接使用顶点数组。而顶点数组列表里保存着将会被引用到一个个独立的顶点。

其实现在会存在这样一个问题:每个面需要 4 个顶点,而每个顶点会被 3 个面共享。我们会创建一个包含 24 个顶点的数组列表,通过使用数组下标来索引顶点,然后把这些用于索引的下标传递给渲染程序而不是直接把整个顶点数据传递过去,这样来减少数据传递。那么也许你就会问:那么使用 8 个顶点就好了,为什么要使用 24 个顶点呢?这是因为每个顶点虽然被 3 个面共享但是它在每个面上需要使用不同的颜色信息。24 个顶点中的每一个都会有独立的颜色信息,这就会造成每个顶点位置都会有 3 份副本。

定义立方体顶点位置

首先,更新 initBuffers() 函数中代码来创建立方体的顶点位置缓存区。现在的代码看起来和渲染正方形时的代码很相似,只是比之前的代码更长因为现在有了 24 个顶点(每个面使用 4 个顶点):

备注: 在“init-buffers.js”文件 initPositionBuffer() 函数中,用下面代码替换 positions

JSCopy to Clipboard

const positions = [// Front face-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0,// Back face-1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0,// Top face-1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,// Bottom face-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,// Right face1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0,// Left face-1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0,
];

由于我们给顶点添加了 Z 分量,因此我们需要将 vertexPosition 属性的 numComponents 更新为 3。

备注: 在“draw-scene.js”文件 setPositionAttribute() 函数中,将 numComponents 从 2 改为 3:

JSCopy to Clipboard

const numComponents = 3;

定义顶点颜色

然后我们还要为每个顶点定义颜色。下面的代码首先为每个面定义颜色,然后用一个循环语句为每个顶点定义颜色信息。

备注: 在“init-buffers.js”文件 initColorBuffer() 函数中,用下面代码替换 colors 定义:

JSCopy to Clipboard

const faceColors = [[1.0, 1.0, 1.0, 1.0], // Front face: white[1.0, 0.0, 0.0, 1.0], // Back face: red[0.0, 1.0, 0.0, 1.0], // Top face: green[0.0, 0.0, 1.0, 1.0], // Bottom face: blue[1.0, 1.0, 0.0, 1.0], // Right face: yellow[1.0, 0.0, 1.0, 1.0], // Left face: purple
];// Convert the array of colors into a table for all the vertices.var colors = [];for (var j = 0; j < faceColors.length; ++j) {const c = faceColors[j];// Repeat each color four times for the four vertices of the facecolors = colors.concat(c, c, c, c);
}

定义元素(三角形)数组

既然已经创建好了顶点数组,接下来就要创建元素(三角形)数组了。

备注: 在“init-buffer.js”文件中添加下面的函数:

JSCopy to Clipboard

function initIndexBuffer(gl) {const indexBuffer = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);// This array defines each face as two triangles, using the// indices into the vertex array to specify each triangle's// position.const indices = [0,1,2,0,2,3, // front4,5,6,4,6,7, // back8,9,10,8,10,11, // top12,13,14,12,14,15, // bottom16,17,18,16,18,19, // right20,21,22,20,22,23, // left];// Now send the element array to GLgl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(indices),gl.STATIC_DRAW,);return indexBuffer;
}

indices 数组声明每一个面都使用两个三角形来渲染。通过立方体顶点数组的索引指定每个三角形的顶点。那么这个立方体就是由 12 个三角形组成的了。

备注: 在“init-buffers.js”文件 initBuffers()函数中,添加下面的代码替换之前的 return 代码片段:

JSCopy to Clipboard

const indexBuffer = initIndexBuffer(gl);return {position: positionBuffer,color: colorBuffer,indices: indexBuffer,
};

渲染立方体

接下来就需要在 drawScene() 函数里添加代码使用立方体顶点索引数据来渲染这个立方体了。代码里添加了对 gl.bindBuffer() 和 gl.drawElements()的调用:

备注: 在 drawScene() 函数中,gl.useProgram 代码前添加如下代码:

JSCopy to Clipboard

// Tell WebGL which indices to use to index the vertices
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices);

备注: 在“draw-scene.js”文件 drawScene() 函数中,用下面这段代码替换之前 gl.drawArrays()

JSCopy to Clipboard

{const vertexCount = 36;const type = gl.UNSIGNED_SHORT;const offset = 0;gl.drawElements(gl.TRIANGLES, vertexCount, type, offset);
}

立方体的每个面都由 2 个三角形组成,那就是每个面需要 6 个顶点,或者说总共 36 个顶点,尽管有许多重复的。然而,因为索引数组的每个元素都是简单的整数类型,所以每一帧动画需要传递给渲染程序的数据也不是很多。

最后,让我们把变量 squareRotation 替换成 cubeRotation 并添加 X 轴的第二个旋转。

备注: 在“webgl-demo.js”文件的头部,把变量 squareRotation 替换成 cubeRotation

JSCopy to Clipboard

let cubeRotation = 0.0;

备注: 在 drawScene() 函数声明中,将变量 squareRotation 替换成 cubeRotation

JSCopy to Clipboard

function drawScene(gl, programInfo, buffers, cubeRotation) {

备注: 在 drawScene() 函数中,用下面代码替换之前的 mat4.rotate 函数:

JSCopy to Clipboard

mat4.rotate(modelViewMatrix, // destination matrixmodelViewMatrix, // matrix to rotatecubeRotation, // amount to rotate in radians[0, 0, 1],
); // axis to rotate around (Z)
mat4.rotate(modelViewMatrix, // destination matrixmodelViewMatrix, // matrix to rotatecubeRotation * 0.7, // amount to rotate in radians[0, 1, 0],
); // axis to rotate around (Y)
mat4.rotate(modelViewMatrix, // destination matrixmodelViewMatrix, // matrix to rotatecubeRotation * 0.3, // amount to rotate in radians[1, 0, 0],
); // axis to rotate around (X)

备注: 在 main() 函数中,替换 drawScene() 函数调用参数中的 squareRotation 为 cubeRotation

JSCopy to Clipboard

drawScene(gl, programInfo, buffers, cubeRotation);
cubeRotation += deltaTime;

到现在为止,我们已经创建了一个颜色生动的并且会在场景中移动和旋转的立方体,这一定很酷吧。

相关文章:

使用 WebGL 创建 3D 对象

WebGL Demohttps://mdn.github.io/dom-examples/webgl-examples/tutorial/sample5/index.html 现在让我们给之前的正方形添加五个面从而可以创建一个三维的立方体。最简单的方式就是通过调用方法 gl.drawElements() 使用顶点数组列表来替换之前的通过方法gl.drawArrays() 直接…...

百度地图3d区域掩膜,最常见通用的大屏地图展现形式

需求及效果 原本项目使用的是百度地图3.0,也就是2d版本的那个地图&#xff0c;客户不满意觉得不够好看&#xff0c;让把地图改成3d的&#xff0c;但是我们因为另外的系统用的都是百度地图&#xff0c;为了保持统一只能用百度地图做 经过3天的努力&#xff0c;最后我终于把这个…...

小区物业管理收费系统源码小程序

便捷、透明、智能化的新体验 一款基于FastAdminUniApp开发的一款物业收费管理小程序。包含房产管理、收费标准、家属管理、抄表管理、在线缴费、业主公告、统计报表、业主投票、可视化大屏等功能。为物业量身打造的小区收费管理系统&#xff0c;贴合物业工作场景&#xff0c;轻…...

C++实现一个简单的Qt信号槽机制

昨天写这个文章《深入探讨C的高级反射机制&#xff08;2&#xff09;&#xff1a;写个能用的反射库》的时候就在想&#xff0c;是不是也能在这套反射逻辑的基础上&#xff0c;实现一个类似Qt的信号槽机制&#xff1f; Qt信号槽机制简介 所谓的Qt的信号槽&#xff08;Signals …...

微信小程序常用的传值

1.通过 URL 传参 在页面跳转时&#xff0c;可以在 URL 中携带参数进行传递&#xff0c;然后在目标页面的 onLoad 生命周期中获取参数。 // 在页面 A 中跳转到页面 B 并传递参数 wx.navigateTo({url: /pages/detail/index?id123 });// 在页面 B 的 onLoad 生命周期中获取参数…...

SQL面试真题解答 数据统计分析,求“同比、环比”等(SQL窗口函数使用)

SQL面试真题解答 数据统计分析&#xff0c;求“同比、环比”等&#xff08;SQL窗口函数使用&#xff09; 环比、环比增长率、同比、同比增长率&#xff0c;根据百度百科上的 说明&#xff1a; 环比增长率 环比增长率&#xff0c;一般是指和上期相比较的增长率。 环比增长率&a…...

【递归、搜索与回溯】floodfill算法二

floodfill算法二 1.被围绕的区域2.太平洋大西洋水流问题3.扫雷游戏4.衣橱整理 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.被围绕的区域…...

Dataease安装,配置Jenkins自动部署

Dataease安装&#xff0c;配置Jenkins自动部署 一.安装Dataease 安装前准备&#xff1a;1.Ubuntu20.04 LTS国内源安装指定版本Docker 2.docker-compose安装 下载离线安装的安装包&#xff0c;下载地址&#xff1a;https://community.fit2cloud.com/#/download/dataease/v1-…...

关于IDEA启动报错 【JAVA_HOME does not point to a valid JM installation】

希望文章能给到你启发和灵感&#xff5e; 感谢支持和关注&#xff5e; 阅读指南 一、基础环境说明1.1 硬件环境1.2 软件环境 二、起因 一、基础环境说明 考虑环境因素不同&#xff0c;大家适当的对比自己的软硬件环境情况分析&#xff5e; 1.1 硬件环境 MacOS Monterey 版本 1…...

设置小蓝熊的CPU亲和性、CPU优先级再设置法环的CPU亲和性

# 适用于Windows系统 # 时间 : 2024-06-28 # 作者 : 三巧(https://blog.csdn.net/qq_39124701) # 文件名 : 设置小蓝熊的CPU亲和性、CPU优先级再设置法环的CPU亲和性.ps1 # 使用方法: 打开记事本&#xff0c;将所有代码复制到记事本中&#xff0c;保存文件时候修改文件后…...

Oracle中的序列(Sequence)是一种数据库对象

Oracle中的序列&#xff08;Sequence&#xff09;是一种数据库对象&#xff0c;用于生成数字序列&#xff0c;通常用于为主键列生成唯一、连续的数值。以下是一些使用序列的案例&#xff1a; 1. **为主键生成唯一值**&#xff1a; 在Oracle中&#xff0c;序列最常用的场景是…...

热点观察 | 《姜饼人王国》新作来袭、《Monopoly GO!》荣登5月全球畅销榜榜首

本周出海热点&#xff1a; 1. 中国品牌借欧洲杯打响知名度 2. 米哈游玩家切割二次元 3. 6月27日&#xff0c;Steam游戏《六月衷曲》上线TapTap 4. 《Monopoly GO!》荣登5月全球畅销榜榜首 5. 《地下城与勇士》拿下本周亚洲T1市场畅销榜冠军 6. 《姜饼人王国》新作强势登顶…...

智能网络构建:探索大模型在网络领域的应用

网络领域以其高度复杂性和快速迭代为特点&#xff0c;完成从网络设计、配置、诊断到安全的网络任务需要广泛的专业知识。这些任务的固有复杂性&#xff0c;加上网络技术和协议不断变化的格局&#xff0c;为传统基于机器学习的方法带来了显著的障碍。这些方法在泛化和自动化网络…...

C++编程逻辑讲解step by step:定义一个Person类,它的每个对象表示一个人。

题目 定义一个Person类,它的每个对象表示一个人。数据成员必须包含姓名、出生年份、死亡年份&#xff0c;一个构造函数&#xff0c;一析构函数&#xff0c;读取数据的成员函数&#xff0c;一个print()成员函数显示所有数据。 #include <iostream> using namespace std;…...

DBdoctor产品介绍

基本信息 DBdoctor是一款企业级数据库监控、巡检、性能诊断、SQL审核与优化平台&#xff0c;致力于解决一切数据库性能问题。采用eBPF技术可对数据库做细粒度的扫描&#xff0c;帮助您一分钟内找到数据库性能问题&#xff0c;实现性能诊断百倍提效。针对数据库性能诊断门槛高、…...

一加Ace3 刷机救砖简化说明

注意&#xff1a;工具使用英文目录&#xff0c;支持救砖和降级。PJE110国行版&#xff0c;CPH2609国际版。目前国行版不能完美转换国际版&#xff0c;每次升级都需要刷oplusstanvbk&#xff0c;不建议使用。跨国转换或ROOT一定先解锁Bootloader&#xff0c;可以使用“一加全能工…...

【服务器05】之【登录/注册账号成功转至游戏场景】

Unity登录注册数据库 打开【服务器01】的文章项目 导入新UI系统 点击2D 双击输入栏位置 修改输入框尺寸及位置 放大字体 修改默认输入文字 发现中文字变成了口口口口 原因是新UI系统不支持中文&#xff0c;解决这个问题需要更换字体 并且修改输入时字体大小 我们取电脑中找Fon…...

平价蓝牙耳机推荐性价比高,性价比高的蓝牙耳机学生党推荐

市场上的蓝牙耳机价格从几十元到几百甚至上千不等&#xff0c;性能与价格也呈现多样化&#xff0c;对于学生党来说&#xff0c;一个理想的选择是那些性价比高的平价蓝牙耳机&#xff0c;它们在不牺牲必要功能的同时&#xff0c;提供了可接受的音质和足够的便利性&#xff0c;接…...

【华为战报】5月、6月HCIP考试战报!

华为认证&#xff1a;HCIA-HCIP-HCIE 点击查看&#xff1a; 【华为战报】4月 HCIP考试战报&#xff01; 【华为战报】2月、3月HCIP考试战报&#xff01; 【华为战报】11月份HCIP考试战报&#xff01; 【HCIE喜报】HCIE备考2个月丝滑通关&#xff0c;考试心得分享&#xff…...

OBD诊断

文章目录 OBD 参考标准OBD 服务OBD服务中的DTCOBD服务中0x03和0x07的区别参考 OBD 参考标准 OBD的标准&#xff1a; ISO 15031 Road Vehicles-Communication between vehicle and external equipment for emission-related diagnostics OBD 服务 序号ID服务说明服务详解10x0…...

告别bypy上传失败!用Aria2+百度云直链脚本,让服务器下载速度飙升5倍

告别bypy上传失败&#xff01;用Aria2百度云直链脚本&#xff0c;让服务器下载速度飙升5倍 如果你经常需要将百度网盘中的大文件&#xff08;比如几十GB的机器学习模型或数据集&#xff09;传输到服务器上&#xff0c;一定对bypy的种种限制深有体会——速度慢、不稳定、大文件容…...

Word自动编号的隐藏玩法:用题注和交叉引用,打造能“自我修复”的智能文档

Word文档工程化&#xff1a;构建自动编号与交叉引用的智能系统 在技术文档撰写过程中&#xff0c;最令人头疼的莫过于图表编号的维护。当你在200页的文档中插入新图表时&#xff0c;手动编号意味着要逐个修改后续所有编号和引用——这种痛苦只有经历过的人才懂。但很少有人意识…...

DbGate数据库管理工具:Docker一键部署与跨平台远程访问实战

1. 为什么选择DbGateDocker组合 第一次接触DbGate是在一个需要同时管理MySQL和MongoDB的项目中。当时团队里有人用Navicat&#xff0c;有人用DBeaver&#xff0c;数据库类型切换时总要重新适应界面。直到发现这个支持多数据库的开源工具&#xff0c;才真正体会到什么叫"一…...

告别模糊地图!5分钟教你用leafletwx实现微信小程序高清地图渲染

5分钟实战&#xff1a;用leafletwx为微信小程序打造视网膜级高清地图 第一次在小程序里集成地图时&#xff0c;我盯着屏幕上模糊的路线和文字皱起了眉头——原生map组件在高端手机上的表现简直像回到了像素游戏时代。直到发现leafletwx这个开源神器&#xff0c;才明白原来微信小…...

保姆级教程:在Windows 11上用VSCode和Conda搞定Depth-Anything-3(含常见报错修复)

Windows 11深度估计实战&#xff1a;VSCodeConda环境下的Depth-Anything-3全流程指南 深度估计作为计算机视觉领域的重要技术&#xff0c;正在自动驾驶、增强现实等场景中发挥关键作用。本文将带你在Windows 11系统上&#xff0c;使用VSCode和Conda搭建Depth-Anything-3开发环境…...

别再手动同步了!利用STM32定时器主从模式与ITR触发,实现硬件级精准定时联动

嵌入式系统中的定时器协同&#xff1a;STM32主从模式与ITR触发的硬件级联动 在工业控制、电机驱动和精密测量等场景中&#xff0c;多个定时器的精确协同往往是系统可靠性的关键。想象一下&#xff0c;当你的电机控制PWM需要与电流采样ADC严格同步&#xff0c;或者多个通信接口必…...

飞书文档到Markdown的突破性转换技术:feishu2md架构深度解析

飞书文档到Markdown的突破性转换技术&#xff1a;feishu2md架构深度解析 【免费下载链接】feishu2md 一键命令下载飞书文档为 Markdown 项目地址: https://gitcode.com/gh_mirrors/fe/feishu2md 在当今企业协作环境中&#xff0c;飞书文档已成为团队知识沉淀的核心载体&…...

HunyuanVideo-Foley 社区贡献指南:如何提交Prompt案例与优化建议

HunyuanVideo-Foley 社区贡献指南&#xff1a;如何提交Prompt案例与优化建议 1. 为什么你的贡献很重要 开源项目的生命力来自社区的共同参与。HunyuanVideo-Foley作为一款专注于音效生成的AI模型&#xff0c;其效果提升离不开用户的实际使用反馈和创意贡献。你的每一次Prompt…...

LazyVim终极指南:如何快速打造你的Neovim梦幻开发环境

LazyVim终极指南&#xff1a;如何快速打造你的Neovim梦幻开发环境 【免费下载链接】LazyVim Neovim懒人配置。 项目地址: https://gitcode.com/GitHub_Trending/la/LazyVim 你是否曾经因为Neovim配置的复杂性而望而却步&#xff1f;是否尝试过各种配置方案却始终找不到那…...

空洞骑士模组管理终极指南:Scarab如何让复杂模组安装变得简单快速

空洞骑士模组管理终极指南&#xff1a;Scarab如何让复杂模组安装变得简单快速 【免费下载链接】Scarab An installer for Hollow Knight mods written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/sc/Scarab 对于《空洞骑士》玩家来说&#xff0c;模组&…...