three.js 入门三:buffergeometry贴图属性(position、index和uvs)
环境:
- three.js 0.159.0
一、基础知识
geometry
:决定物体的几何形状、轮廓;material
:决定物体呈现的色彩、光影特性、贴图皮肤;mesh
:场景中的物体,由geometry
和materia
组成;texture
:贴图,用于将一个jpg等格式的图片贴到material上面(当然,material
也可以不贴texture
);
另外,如果material
上是定义的color
,那么说明,物体是自发光的,不需要灯光就能看到,
而materia
如果整个是靠texture
贴上去的,则需要光照才能看到它,最简单的是用环境光。
另外,对于一张图片,无论它有多大或多小,左下角是(0,0),右上角是(1,1),这就是uv,宽用u表示,高用v表示。
另外,无论一个物体形状有多复杂,其表面也可以分割成很多三角面。
下面使用的示例图片如下:
二、简单实例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}</style><script type="importmap">{"imports": {"three": "https://unpkg.com/three@0.159.0/build/three.module.js","three/addons/": "https://unpkg.com/three@0.159.0/examples/jsm/"}}</script>
</head><body><script type="module">import * as THREE from 'three';import { OrbitControls } from 'three/addons/controls/OrbitControls.js';let camera, scene, renderer;//基础对象camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);camera.position.set(50, 50, 50);camera.updateProjectionMatrix();renderer = new THREE.WebGLRenderer();renderer.setPixelRatio(window.devicePixelRatio);renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);const controls = new OrbitControls(camera, renderer.domElement);controls.minDistance = 5;controls.maxDistance = 300;controls.update()scene = new THREE.Scene();// 环境光const light = new THREE.AmbientLight(0x404040); // soft white lightscene.add(light);//坐标轴const axesHelper = new THREE.AxesHelper(5);scene.add(axesHelper);//准备geometry//点位var position = [10, 10, 0,10, 0, 0,0, 0, 0]//贴图var uvs = [1, 1,1, 0,0, 0,] //构造geometrylet geometry = new THREE.BufferGeometry();geometry.setAttribute('position', new THREE.Float32BufferAttribute(position, 3));geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));//加载贴图const texture = new THREE.TextureLoader().load('number.png');texture.wrapS = texture.wrapT = THREE.RepeatWrapping;texture.repeat.set(1, 1);//准备materialconst material = new THREE.MeshBasicMaterial({side: THREE.DoubleSide,map: texture,transparent: true,opacity: 0.7,});//组成meshconst mesh = new THREE.Mesh(geometry, material);scene.add(mesh);function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);}animate();</script>
</body></html>
效果如下:
三、探索贴图原理
先说上面示例:
- position 表达了三个点位的坐标和顺序(看向
-z
轴,逆时针),此时面的法方向是 (0,0,-1); - uv 表达了position每个点位在贴图上的点;
- 又因为,将material设为了透明和双面渲染,所以我们看向
-z
轴也是可以看到效果的(我们默认看到的效果其实是背面,可以将上面的side: THREE.DoubleSide,
注释掉试试);
这里是否有一个疑问:怎么知道贴图的正面是朝向哪的呢?为什么这里是朝向+z
轴,而不是-z
轴呢?
其实,因为position和uv,webgl的插值计算只能将贴图的正面朝向
+z
轴,如下图示意:
四、考虑index作用
上面只是3个点位,所以仅用position和uv即可表达,但如果有很多点位,再这么写的话position会很多,而且很多都是重复的,
比如:立方体有8个点位,如果每个面分成两个三角面,那么总共需要24 = 6*2*3
个点位坐标(每个3角面要3个点)。
此时使用index的写法:
position:8个点位
index: 列出每个三角面的点位序号, 共计 24 个元素
uv:和position一一对应
将上面示例中geometry部分改造如下:
//准备geometry
//点位
var position = [10, 10, 0,10, 0, 0,0, 0, 0,0, 10, 0,
]
//贴图
var uvs = [1, 1,1, 0,0, 0,0, 1,
]
//点位序号
var index = [0, 1, 2,0, 2, 3,
]
//构造geometry
let geometry = new THREE.BufferGeometry();
geometry.setIndex(index);
geometry.setAttribute('position', new THREE.Float32BufferAttribute(position, 3));
geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
此时,我们看到的效果:
可以看到,我们仅用了4个点位,便描述了两个3角面。
五、看一个特殊的示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}</style><script type="importmap">{"imports": {"three": "https://unpkg.com/three@0.159.0/build/three.module.js","three/addons/": "https://unpkg.com/three@0.159.0/examples/jsm/"}}</script>
</head><body><script type="module">import * as THREE from 'three';import { OrbitControls } from 'three/addons/controls/OrbitControls.js';let camera, scene, renderer;//基础对象camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);camera.position.set(50, 50, 50);camera.updateProjectionMatrix();renderer = new THREE.WebGLRenderer();renderer.setPixelRatio(window.devicePixelRatio);renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);const controls = new OrbitControls(camera, renderer.domElement);controls.minDistance = 5;controls.maxDistance = 300;controls.update()scene = new THREE.Scene();// 环境光const light = new THREE.AmbientLight(0x404040); // soft white lightscene.add(light);//坐标轴const axesHelper = new THREE.AxesHelper(5);scene.add(axesHelper);//准备geometry//点位var position = [10, 10, 0,10, 0, 0,0, 0, 0,]//贴图var uvs = [0, 1,1, 1,0, 0,]//点位序号var index = [0, 1, 2]//构造geometrylet geometry = new THREE.BufferGeometry();geometry.setIndex(index);geometry.setAttribute('position', new THREE.Float32BufferAttribute(position, 3));geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));//加载贴图const texture = new THREE.TextureLoader().load('number.png');texture.wrapS = texture.wrapT = THREE.RepeatWrapping;texture.repeat.set(1, 1);//准备materialconst material = new THREE.MeshBasicMaterial({side: THREE.DoubleSide,map: texture,transparent: true,opacity: 0.7,});//组成meshconst mesh = new THREE.Mesh(geometry, material);scene.add(mesh);function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);}animate();</script>
</body></html>
效果如下:
六、最后看一个用立方体实现全景图预览的效果
效果图如下:
代码下载请看博文顶部。。。
相关文章:

three.js 入门三:buffergeometry贴图属性(position、index和uvs)
环境: three.js 0.159.0 一、基础知识 geometry:决定物体的几何形状、轮廓;material:决定物体呈现的色彩、光影特性、贴图皮肤;mesh:场景中的物体,由geometry和materia组成;textu…...

Initial用法-FPGA入门3
Initial是什么 FPGA Initial是一种在FPGA中进行初始化的方法。在FPGA设备上,初始值决定了逻辑门的状态和寄存器的初始值。FPGA Initial可以通过设置初始值来控制电路在上电后的初始状态。 Initial的作用 2.1,控制电路启动时的初始状态 通过设置FPGA Ini…...

perl脚本中使用eval函数执行可能有异常的操作
perl脚本中有时候执行的操作可能会引发异常,为了直观的说明,这里举一个json反序列化的例子,脚本如下: #! /usr/bin/perl use v5.14; use JSON; use Data::Dumper;# 读取json字符串数据 my $json_str join(, <DATA>); # 反…...

『Redis』在Docker中快速部署Redis并进行数据持久化挂载
📣读完这篇文章里你能收获到 在Docke中快速部署Redis如何将Redis的数据进行持久化 文章目录 一、拉取镜像二、创建挂载目录1 宿主机与容器挂载映射2 挂载命令执行 三、创建容器—运行Redis四、查看运行情况 一、拉取镜像 版本号根据需要自己选择,这里以…...

ubuntu创建apt-mirror本地仓库
首先创建apt-mirror的服务端,也就是存储所有apt-get下载的文件和依赖。大约需要300G,预留400G左右空间就可以开始了。 安装ubuntu省略,用的是ubuntu202204 ubuntu挂载硬盘(不需要的可以跳过): #下载挂载工具 sudo apt…...
计算机网络 internet应用 (水
ARPA net ---Internet 前身 发展史: ARPA net 第一个主干网..美国军方NSFnet 美国国家科学基金会NSFANSnet 美国全国 (internet 叫法开始出现) 第二代互联网(现在() IP地址 IP地址 最高管理机构 - InterNIC IPV4 32位 IPV6 128位 域名 起名 解析 domain name sys…...

【ChatGLM3】第三代大语言模型多GPU部署指南
关于ChatGLM3 ChatGLM3是智谱AI与清华大学KEG实验室联合发布的新一代对话预训练模型。在第二代ChatGLM的基础之上, 更强大的基础模型: ChatGLM3-6B 的基础模型 ChatGLM3-6B-Base 采用了更多样的训练数据、更充分的训练步数和更合理的训练策略。在语义、…...
云原生Kubernetes系列 | Docker/Kubernetes的卷管理
云原生Kubernetes系列 | Docker/Kubernetes的卷管理 1. Docker卷管理2. Kubernetes卷管理2.1. 本地存储2.1.1. emptyDir2.1.2. hostPath2.2. 网络存储2.2.1. 使用NFS2.2.2. 使用ISCSI2.3. 持久化存储2.3.1. PV和PVC2.3.2. 访问模式2.3.3. 回收策略1. Docker卷管理...

Java实现快速排序算法
快速排序算法 (1)概念:快速排序是指通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序。整个排序过程可以递归进行&…...

MAC配置环境变量
1、配置 JAVA JDK 1.1、查看 JDK 安装目录 (1)可以在Android Studio中查看,复制该路径 (2)也可以在官网下载 Java JDK下载地址 mac中的安装地址是"资源库->Java->JavaVirtualMachines"中 1.2、…...

系列五、DQL
一、DQL 1.1、概述 DQL的英文全称为:Data Query Language,中文意思为:数据查询语言,用大白话讲就是查询数据。对于大多数系统来说,查询操作的频次是要远高于增删改的,当我们去访问企业官网、电商网站&…...

【智能家居】七、人脸识别 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)
一、翔云 人工智能开放平台 API文档开发示例下载 二、编译openSSL支持libcurl的https访问 安装SSL依赖库openSSL(使用工具wget)libcurl库重新配置,编译,安装运行(运行需添加动态库为环境变量) 三、编程实现人脸识别 四、Base6…...

基于node 安装express后端脚手架
1.首先创建文件件 2.在文件夹内打开终端 npm init 3.安装express: npm install -g express-generator注意的地方:这个时候安装特别慢,最后导致不成功 解决方法:npm config set registry http://registry.npm.taobao.org/ 4.依次执行 npm install -g ex…...

Mrdoc知识文档
MrDoc知识文档平台是一款基于Python开发的在线文档系统,适合作为个人和中小型团队的私有云文档、云笔记和知识管理工具,致力于成为优秀的私有化在线文档部署方案。我现在主要把markdown笔记放在上面,因为平时老是需要查询一些知识点ÿ…...
C语言中getchar函数
在 C 语言中,getchar() 是一个标准库函数,用于从标准输入(通常是键盘)读取单个字符。它的函数原型如下: int getchar(void);getchar() 函数的工作原理如下: 当调用 getchar() 函数时,它会等待…...
全栈开发组合
SpringBoot是什么? SpringBoot是一个基于Spring框架的开源框架,由Pivotal团队开发。它的设计目的是用来简化Spring应用的初始搭建以及开发过程。SpringBoot提供了丰富的Spring模块化支持,可以帮助开发者更轻松快捷地构建出企业级应用 Sprin…...

wpf TelerikUI使用DragDropManager
首先,我先创建事务对象ApplicationInfo,当暴露出一对属性当例子集合对于构成ListBoxes。这个类在例子中显示如下代码: public class ApplicationInfo { public Double Price { get; set; } public String IconPath { get; set; } public …...

Python+Appium自动化测试之元素等待方法与重新封装元素定位方法
在appium自动化测试脚本运行的过程中,因为网络不稳定、测试机或模拟器卡顿等原因,有时候会出现页面元素加载超时元素定位失败的情况,但实际这又不是bug,只是元素加载较慢,这个时候我们就会使用元素等待的方法来避免这种…...
详解Maven如何打包SpringBoot工程
目录 一、spring-boot-maven-plugin详解 1、添加spring-boot-maven-plugin插件到pom.xml 2、配置主类(Main Class) 3、配置打包的JAR文件名 4、包含或排除特定的资源文件 5、指定额外的依赖项 6、配置运行参数 7、自定义插件执行阶段 二、Maven打…...

PyQt6 QFrame分割线控件
锋哥原创的PyQt6视频教程: 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计46条视频,包括:2024版 PyQt6 Python桌面开发 视频教程(无废话版…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...