three.js 入门三:buffergeometry贴图属性(position、index和uvs)

news2024/11/24 19:07:33

环境:

  • three.js 0.159.0

一、基础知识

  • geometry:决定物体的几何形状、轮廓;
  • material:决定物体呈现的色彩、光影特性、贴图皮肤;
  • mesh:场景中的物体,由geometrymateria组成;
  • 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 light
        scene.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,
        ]        
        //构造geometry
        let 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);
        //准备material
        const material = new THREE.MeshBasicMaterial({
            side: THREE.DoubleSide,
            map: texture,
            transparent: true,
            opacity: 0.7,
        });
        //组成mesh
        const 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 light
        scene.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
        ]
        //构造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));

        //加载贴图
        const texture = new THREE.TextureLoader().load('number.png');
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.set(1, 1);
        //准备material
        const material = new THREE.MeshBasicMaterial({
            side: THREE.DoubleSide,
            map: texture,
            transparent: true,
            opacity: 0.7,
        });
        //组成mesh
        const mesh = new THREE.Mesh(geometry, material);
        scene.add(mesh);

        function animate() {
            requestAnimationFrame(animate);
            renderer.render(scene, camera);
        }
        animate();
    </script>
</body>

</html>

效果如下:
在这里插入图片描述

六、最后看一个用立方体实现全景图预览的效果

效果图如下:
在这里插入图片描述

代码下载请看博文顶部。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1297121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虹科Pico汽车示波器 | 汽车免拆检修 | 2018款东风风神AX7车发动机怠速抖动、加速无力

一、故障现象 一辆2018款东风风神AX7车&#xff0c;搭载10UF01发动机&#xff0c;累计行驶里程约为5.3万km。该车因发动机怠速抖动、加速无力及发动机故障灯异常点亮而进厂维修&#xff0c;维修人员用故障检测仪检测&#xff0c;提示气缸3失火&#xff1b;与其他气缸对调点火线…

Shell变量的奇妙用法,让你的Shell脚本更简洁高效

当涉及到命令行工具和脚本编写时&#xff0c;Shell变量是一个非常重要的概念。利用Shell变量的一些奇妙用法&#xff0c;我们可以用一个简单的表达式实现复杂操作&#xff0c;使我们的命令更加简洁高效。 本文将介绍一些常用的Shell变量操作符&#xff0c;包括字符串操作、数组…

SAP UI5 walkthrough step5 Controllers

在这个章节&#xff0c;我们要做的是&#xff0c;将之前的text文本展示为一个按钮&#xff0c;并将声明绑定在点击按钮事件。 因为改的是外观&#xff0c;所以我们修改的是view.XML webapp/view/App.view.xml <mvc:ViewcontrollerName"ui5.walkthrough.controller.A…

Nacos注册中心客户端容灾

目前Nacos客户端有一个FailoverReactor来进行容灾文件的管理&#xff0c;可以通过在指定磁盘文件里写入容灾数据来进行客户端使用数据的覆盖。FailoverReactor目前会拦截Nacos客户端查询接口调用&#xff0c;以getAllInstances接口为例&#xff0c;目前FailoverReactor的工作流…

uni-app实现安卓原生态调用身份证阅读器读卡库读身份证和社保卡、银行卡、IC卡等功能

DONSEE系列多功能读写器Android Uniapp API接口规范V1.0.0 本项目Uniapp调用了身份证读卡器的库文件&#xff1a;DonseeDeviceLib-debug.aar&#xff0c;该库放到nativeplugins\donsee-card\android&#xff0c;然后会自动加载。SDK会自动检查是否拥有USB设备权限&#xff0c;…

2023五岳杯量子计算挑战赛数学建模思路+模型+代码+论文

赛题思路&#xff1a;12月6日晚开赛后第一时间更新&#xff0c;获取见文末名片 “五岳杯”量子计算挑战赛&#xff0c;是国内专业的量子计算大赛&#xff0c;也是玻色量子首次联合移动云、南方科技大学共同发起的一场“企校联名”的国际竞赛&#xff0c;旨在深度融合“量子计算…

人工智能教程(三):更多有用的 Python 库

目录 前言 推荐 JupyterLab 入门 复杂的矩阵运算 其它人工智能和机器学习的 Python 库 前言 在本系列的上一篇人工智能教程&#xff08;二&#xff09;&#xff1a;人工智能的历史以及再探矩阵中&#xff0c;我们回顾了人工智能的历史&#xff0c;然后详细地讨论了矩阵。在…

二维数组附近遍历所有值

二维数组附近遍历所有值 假如以56点为中心&#xff0c;上下左右近距离遍历附近值&#xff0c;看代码&#xff0c;代码把思路写出来了&#xff0c;边界问题暂不处理。 #include<iostream> using namespace std;void FindNearPos(int (*int_arr)[10] , int p_row , int …

Linux centos8安装JDK1.8、tomcat

一、安装jdk 1.如果之前安装过jdk&#xff0c;先卸载掉旧的 rpm -qa | grep -i jdk 2.检查yum中有没有java1.8的包 yum list java-1.8* 3.yum安装jdk yum install java-1.8.0-openjdk* -y 4.验证 二、安装tomcat Index of /tomcat 可以在这里选择你想要安装的tomcat版本…

【vtkWidgetRepresentation】第七期 vtkImplicitPlaneRepresentation

很高兴在雪易的CSDN遇见你 前言 本文分享vtkImplicitPlaneRepresentation源码剖析&#xff0c;及相关的实例&#xff0c;该接口主要用于切割交互&#xff0c;希望对各位小伙伴有所帮助&#xff01; 感谢各位小伙伴的点赞关注&#xff0c;小易会继续努力分享&#xff0c;一起…

线上盲盒小程序,开启互联网盲盒时代

近年来&#xff0c;盲盒经济在国内非常火爆&#xff0c;各类盲盒品牌层出不穷&#xff0c;深受国内外年轻人、消费者的喜爱。 目前&#xff0c;根据数据显示&#xff0c;盲盒市场不仅在线下异常火热&#xff0c;线上盲盒也是成为了大众的新选择。各类电商平台中盲盒的成交额更…

C++ Qt开发:Qt的安装与配置

Qt是一种C编程框架&#xff0c;用于构建图形用户界面&#xff08;GUI&#xff09;应用程序和嵌入式系统。Qt由Qt公司&#xff08;前身为Nokia&#xff09;开发&#xff0c;提供了一套跨平台的工具和类库&#xff0c;使开发者能够轻松地创建高效、美观、可扩展的应用程序。其被广…

元宇宙vr党建云上实景展馆扩大党的影响力

随着科技的飞速发展&#xff0c;VR虚拟现实技术已经逐渐融入我们的日常生活&#xff0c;尤其在党建领域&#xff0c;VR数字党建展馆更是成为引领红色教育新风尚的重要载体。今天&#xff0c;就让我们一起探讨VR数字党建展馆如何提供沉浸式体验&#xff0c;助力党建工作创新升级…

无头浏览器与Selenium:探索无界爬虫的奇妙世界

selenium设置无头浏览器 背景 ​ 我们之前的selenium都是浏览器驱动自动打开一个网页&#xff0c;执行相关操作&#xff0c;其实也可以让其后台显示&#xff0c;不用在前台显示。 ​ 要设置无头浏览器&#xff0c;可以使用Selenium的Headless模式。在Headless模式下&#xf…

解读 | 阿里通义千问模型全尺寸开源 “诚意满满“背后的名与利

大家好&#xff0c;我是极智视界&#xff0c;欢迎关注我的公众号&#xff0c;获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」&#xff0c;星球内有超多好玩的项目实战源码和资源下载&#xff0c;链接&#xff1a;https://t.zsxq.com/0aiNxERDq 12 月 1 日阿里开源…

【深度挖掘Java性能调优】「底层技术原理体系」深入挖掘和分析如何提升服务的性能以及执行效率(性能三大定律)

深入挖掘和分析如何提升服务的性能以及执行效率 前提介绍知识要点 性能概述教你看懂程序的性能案例介绍性能指标性能的参考指标性能瓶颈&#xff08;木桶原理&#xff09; 性能分析三大定律Amdahl定律计算公式参数解释案例分析定律总结 Gustafson定律与Amdahl定律相对立Gustafs…

Postman和Apifox针对不同环境、全局变量的使用与比较

文章目录 一、Postman1、配置环境和全局变量2、验证3、存在问题分析 二、Apifox1、配置环境和全局参数2、创建公共脚本3、测试 总结 一、Postman 1、配置环境和全局变量 在Postman的界面中&#xff0c;点击"Environment"&#xff0c;添加我们需要的环境&#xff0c…

基于Python+WaveNet+MFCC+Tensorflow智能方言分类—深度学习算法应用(含全部工程源码)(二)

目录 前言引言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据预处理1&#xff09;数据介绍2&#xff09;数据测试3&#xff09;数据处理 相关其它博客工程源代码下载其它资料下载 前言 博主前段时间发布了一篇有关方言识别和分类模型训练的博客&#xff0c;在读者…

10 大 Android 手机系统修复软件深度评测

您的新 Android 手机可能因其令人兴奋的性能而印象深刻。然而&#xff0c;随着时间的推移&#xff0c;您可能会发现系统有些地方与以前不太一样。您可能会遇到屏幕无响应、 Android应用程序崩溃、连接问题、电池耗尽等现象。 10 大 Android 手机系统修复软件 好吧&#xff0c;…

伦茨科技宣布ST17H6x芯片已通过Apple Find My「查找」认证

深圳市伦茨科技有限公司&#xff08;以下简称“伦茨科技”&#xff09;发布ST17H6x Soc平台。成为继Nordic之后全球第二家取得Apple Find My「查找」认证的芯片厂家&#xff0c;该平台提供可通过Apple Find My认证的Apple查找&#xff08;Find My&#xff09;功能集成解决方案。…