three.js 入門三:buffergeometry貼圖屬性(position、index和uvs)

環境:

  • 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 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>

效果如下:
在這里插入圖片描述

六、最后看一個用立方體實現全景圖預覽的效果

效果圖如下:
在這里插入圖片描述

代碼下載請看博文頂部。。。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/206643.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/206643.shtml
英文地址,請注明出處:http://en.pswp.cn/news/206643.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

十五、機器學習進階知識:K-Means聚類算法

文章目錄 1、聚類概述2、K-Means聚類算法原理3、K-Means聚類實現3.1 基于SKlearn實現K-Means聚類3.2 自編寫方式實現K-Means聚類 4、算法不足與解決思路4.1 存在的問題4.2 常見K值確定方法4.3 算法評估優化思路 1、聚類概述 聚類&#xff08;Clustering&#xff09;是指將不同…

淺談WPF之控件拖拽與拖動

使用過office的visio軟件畫圖的小伙伴都知道&#xff0c;畫圖軟件分為兩部分&#xff0c;左側圖形庫&#xff0c;存放各種圖標&#xff0c;右側是一個畫布&#xff0c;將左側圖形庫的圖標控件拖拽到右側畫布&#xff0c;就會生成一個新的控件&#xff0c;并且可以自由拖動。那如…

Python---面向對象其他特性

1、類屬性 Python中&#xff0c;屬性可以分為實例屬性和類屬性。 類屬性就是 類對象中定義的屬性&#xff0c;它被該類的所有實例對象所共有。通常用來記錄 與這類相關 的特征&#xff0c;類屬性 不會用于記錄 具體對象的特征。 在Python中&#xff0c;一切皆對象。類也是一…

1 接口測試介紹

在軟件測試工作中&#xff0c;接口測試是必不可少的。接口測試一般是發生在單元測試之后&#xff0c;系統測試之前。當開發人員輸出API文檔后&#xff0c;測試人員就可以開始編寫接口測試用例了。接口測試可以讓測試人員更早的介入&#xff0c;不需要等待前后端聯調完成才開始測…

銀行卡二要素API的應用案例:從在線購物到金融投資

引言 隨著互聯網技術的不斷發展&#xff0c;人們的金融需求也在不斷增加。隨之而來的是各種新型金融服務的涌現&#xff0c;讓用戶的金融體驗更加便利快捷。其中&#xff0c;銀行卡二要素API的應用&#xff0c;則為用戶的金融體驗和安全性提供了極大的保障。 銀行卡二要素API…

知識蒸餾的蒸餾損失方法代碼總結(包括:基于logits的方法:KLDiv,dist,dkd等,基于中間層提示的方法:)

有兩種知識蒸餾方法&#xff1a;一種利用教師模型的輸出概率&#xff08;基于logits的方法&#xff09;[15,14,11]&#xff0c;另一種利用教師模型的中間表示&#xff08;基于提示的方法&#xff09;[12,13,18,17]。基于logits的方法利用教師的輸出作為輔助信號來訓練一個較小的…

VBA語法結構及編程思想

VBA&#xff08;Visual Basic for Applications&#xff09;是一種編程語言&#xff0c;它被用于Microsoft Office應用程序的自動化&#xff0c;允許用戶編寫宏來執行常規任務。VBA是基于Microsoft的Visual Basic語言&#xff0c;但專為Office應用程序定制。 VBA語法格式 VBA的…

【STM32】TIM定時器輸出比較

1 輸出比較 1.1 輸出比較簡介 OC&#xff08;Output Compare&#xff09;輸出比較&#xff1b;IC&#xff08;Input Capture&#xff09;輸入捕獲&#xff1b;CC&#xff08;Capture/Compare&#xff09;輸入捕獲和輸出比較的單元輸出比較可以通過比較CNT與CCR寄存器值&#…

JavaWeb-HTTP協議

1. 什么是HTTP協議 HTTP超文本傳輸協(Hyper Text transfer protocol)&#xff0c;是一種用于用于分布式、協作式和超媒體信息系統的應用層協議。它于1990年提出&#xff0c;經過十幾年的使用與發展&#xff0c;得到不斷地完善和擴展。HTTP 是為 Web 瀏覽器與 Web 服務器之間的…

AI自動生成代碼工具

AI自動生成代碼工具是一種利用人工智能技術來輔助或自動化軟件開發過程中的編碼任務的工具。這些工具使用機器學習和自然語言處理等技術&#xff0c;根據開發者的需求生成相應的源代碼。以下是一些常見的AI自動生成代碼工具&#xff0c;希望對大家有所幫助。北京木奇移動技術有…

Redisson的基本使用

Redisson官網描述&#xff1a;Redisson 是一個在 Redis 的基礎上實現的 Java 駐內存數據網格客戶端&#xff08;In-Memory Data Grid&#xff09;。它不僅提供了一系列的 redis 常用數據結構命令服務&#xff0c;還提供了許多分布式服務&#xff0c;例如分布式鎖、分布式對象、…

HCIP —— BGP 基礎 (上)

BGP --- 邊界網關協議 &#xff08;路徑矢量協議&#xff09; IGP --- 內部網關協議 --- OSPF RIP ISIS EGP --- 外部網關協議 --- EGP BGP AS --- 自治系統 由單一的組織或者機構獨立維護的網絡設備以及網絡資源的集合。 因 網絡范圍太大 需 自治 。 為區分不同的AS&#…

vim常見操作

vim常見操作 文章目錄 vim常見操作1. 回退/前進2. 搜索3. 刪除4. 定位到50行5. 顯示行號6. 復制粘貼7. 剪貼8. 替換9. vim打開文件的時候出現 1. 回退/前進 1.esc進入命令模式 2.ctrlr 前進 u 回退2. 搜索 1&#xff09; esc進入命令模式 2&#xff09; /text  查找text&am…

Docker load 命令

docker load &#xff1a;導入使用docker save命令導出的鏡像。 語法 docker load [OPTIONS]OPTIONS 說明&#xff1a; --input , -i &#xff1a;指定導入的文件&#xff0c;代替STDIN。 --quiet , -q &#xff1a;精簡輸出信息。 實例&#xff1a; 導入鏡像&#xff1a…

【STM32】TIM定時器輸入捕獲

1 輸入捕獲 1.1 輸入捕獲簡介 IC&#xff08;Input Capture&#xff09;輸入捕獲 輸入捕獲模式下&#xff0c;當通道輸入引腳出現指定電平跳變時&#xff08;上升沿/下降沿&#xff09;&#xff0c;當前CNT的值將被鎖存到CCR中&#xff08;把CNT的值讀出來&#xff0c;寫入到…

ubuntu16.04安裝ROS+Gazebo

ubuntu16.04安裝ROS參考文章 ros安裝&#xff08;一鍵最簡安裝&#xff0c;吹爆魚香ROS&#xff0c;請叫我魚吹&#xff09; ROS篇——Ubuntu快速一鍵安裝ROS或ROS2&#xff08;通用&#xff09; ubuntu安裝ROS melodic(最新、超詳細圖文教程) 配置ubuntu以及安裝ros2必要環…

類風濕性關節炎口腔黏膜破裂引發抗瓜氨酸細菌和人蛋白抗體反應

今天給同學們分享一篇實驗文章“Oral mucosal breaks trigger anti-citrullinated bacterial and human protein antibody responses in rheumatoid arthritis”&#xff0c;這篇文章發表在Sci Transl Med期刊上&#xff0c;影響因子為17.1。 結果解讀&#xff1a; 口腔黏膜破…

Redis主從復制的配置和實現原理

Redis的持久化功能在一定程度上保證了數據的安全性&#xff0c;即便是服務器宕機的情況下&#xff0c;也可以保證數據的丟失非常少。通常&#xff0c;為了避免服務的單點故障&#xff0c;會把數據復制到多個副本放在不同的服務器上&#xff0c;且這些擁有數據副本的服務器可以用…

如何快速構建知識服務平臺,打造個人或企業私域流量

隨著互聯網的快速發展&#xff0c;傳統的知識付費平臺已經不能滿足用戶的需求。而SaaS知識付費小程序平臺則是一種新型的知識付費方式&#xff0c;具有靈活、便捷、高效等特點&#xff0c;為用戶提供了更加優質的付費知識服務。本文將介紹如何搭建自己的SaaS知識付費小程序平臺…

如何掌握構建 LMS 網站的藝術

目錄 什么是學習管理系統 (LMS) 在線課程和 LMS 網站的好處 為什么 WordPress 對于 LMS 網站很重要 統一學習中心 多功能性和可擴展性 提高教育參與度 簡化管理和監控 節省時間和費用 技能評估和績效監督 持續學習和技能提升 使用 WordPress 插件構建成功的 LMS 課程 專注于您的…