92国产精品视频_亚洲a级在线观看_国产精品电影观看_国产精品免费观看在线_精品伊人久久97_亚洲人成在线观_尤物九九久久国产精品的特点_成人激情在线播放_成人黄色大片在线免费观看_亚洲成人精品久久久_久久免费视频在线观看_久久精品国产一区_国产一区二区三区18_亚洲欧美中文字幕在线一区_日韩美女中文字幕_日韩视频免费在线

THREE.JS實現看房自由(VR看房)

2023-2-1    前端達人


一、前言

概述:基于WebGL的三維引擎,目前是國內資料最多、使用最廣泛的三維引擎,可以制作一些3D可視化項目

在這里插入圖片描述

目前隨著元宇宙概念的爆火,THREE技術已經深入到了物聯網、VR、游戲、數據可視化等多個平臺,今天我們主要基于THREE實現一個三維的VR看房小項目

二、基礎知識

在這里插入圖片描述

Three.js一般分為三個部分:場景、相機、渲染器,這三個主要的分支就構成了THREE.JS的主要功能區,這三大部分還有許多細小的分支,這些留到我們后續抽出一些章節專門講解一下。

在這里插入圖片描述

工作流程:場景——相機——渲染器

實際生活中拍照角度立方體網格模型和光照組成了一個虛擬的三維場景,相機對象就像你生活中使用的相機一樣可以拍照,只不過一個是拍攝真實的景物,一個是拍攝虛擬的景物。拍攝一個物體的時候相機的位置和角度需要設置,虛擬的相機還需要設置投影方式,當你創建好一個三維場景,相機也設置好,就差一個動作“咔”,通過渲染器就可以執行拍照動作。

三、場景

概述:場景主要由網絡模型與光照組成,網絡模型分為幾何體與材質

3.1 網絡模型

幾何體就像我們小時候學我們就知道點線面體四種概念,點動成線,線動成面,面動成體,而材質就像是是幾何體上面的涂鴉,有不同的顏色、圖案…

例子如下:

在這里插入圖片描述

//打造酷炫三角形 for (let i = 0; i < 50; i++) { const geometry = new THREE.BufferGeometry(); const arr = new Float32Array(9); for (let j = 0; j < 9; j++) { arr[j] = Math.random() * 5; } geometry.setAttribute('position', new THREE.BufferAttribute(arr, 3)); let randomColor = new THREE.Color(Math.random(), Math.random(), Math.random()); const material = new THREE.MeshBasicMaterial({ color: randomColor, transparent: true, opacity:0.5, }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); } 
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-UlBSgxKr-1666681292595)(https://gitee.com/riskbaby/picgo/raw/master/blog/202209211037215.png#pic_center)]

const geometry = new THREE.BoxGeometry(100, 100, 100); const material = new THREE.MeshStandardMaterial({ color: 0x0000ff }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); 
        
  • 1
  • 2
  • 3
  • 4

在這里插入圖片描述

const geometry = new THREE.ConeGeometry(5, 15, 32);//底面半徑 高 側邊三角分段 const material = new THREE.MeshStandardMaterial({ color: 0x0000ff }); const clone = new THREE.Mesh(geometry, material); scene.add(clone); 
        
  • 1
  • 2
  • 3
  • 4

3.2 光照

3.2.1 環境光

概念:光照對three.js的物體全表面進行光照測試,有可能會發生光照融合

在這里插入圖片描述

//環境光 const ambient = new THREE.AmbientLight(0x404040); scene.add(ambient); 
        
  • 1
  • 2
  • 3

3.2.2 平行光

概念:向特定方向發射的光,太陽光也視作平行的一種,和上面比較,物體變亮了

//平行光  顏色 強度 const directionalLight = new THREE.DirectionalLight(0xffffff, 1); directionalLight.position.set(100, 100, 100);//光源位置 directionalLight.target = cube;//光源目標 默認 0 0 0 scene.add(directionalLight); 
        
  • 1
  • 2
  • 3
  • 4
  • 5

3.2.3 點光源

概念:由中間向四周發射光、強度比平行光小

在這里插入圖片描述

// 顏色 強度 距離 衰退量(默認1) const pointLight = new THREE.PointLight(0xff0000, 1, 100, 1); pointLight.position.set(50, 50, 50); scene.add(pointLight); 
        
  • 1
  • 2
  • 3
  • 4
  • 5

3.2.4 聚光燈

概念:家里面的節能燈泡,強度較好

在這里插入圖片描述

//聚光燈 const spotLigth = new THREE.PointLight(0xffffff); spotLigth.position.set(50, 50, 50); spotLigth.target = cube; spotLigth.angle = Math.PI / 6; scene.add(spotLigth); 
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.2.5 半球光

概念:光源直接放置于場景之上,光照顏色從天空光線顏色漸變到地面光線顏色

在這里插入圖片描述

//半球光 const light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);//天空 場景  scene.add(light); 
        
  • 1
  • 2
  • 3

四、相機

4.1 正交相機

在這里插入圖片描述

參數(屬性) 含義
left 渲染空間的左邊界
right 渲染空間的右邊界
top 渲染空間的上邊界
bottom 渲染空間的下邊界
near near屬性表示的是從距離相機多遠的位置開始渲染,一般情況會設置一個很小的值。 默認值0.1
far far屬性表示的是距離相機多遠的位置截止渲染,如果設置的值偏小小,會有部分場景看不到。 默認值1000
let width = window.innerWidth; let height = window.innerHeight; const camera = new THREE.OrthographicCamera(width / - 2, width / 2, height / 2, height / - 2, 1, 1000); scene.add(camera); camera.position.set(100, 200, 100); 
        
  • 1
  • 2
  • 3
  • 4
  • 5

4.2 透視相機

在這里插入圖片描述

參數 含義 默認值
fov fov表示視場,所謂視場就是能夠看到的角度范圍,人的眼睛大約能夠看到180度的視場,視角大小設置要根據具體應用,一般游戲會設置60~90度 45
aspect aspect表示渲染窗口的長寬比,如果一個網頁上只有一個全屏的canvas畫布且畫布上只有一個窗口,那么aspect的值就是網頁窗口客戶區的寬高比 window.innerWidth/window.innerHeight
near near屬性表示的是從距離相機多遠的位置開始渲染,一般情況會設置一個很小的值。 0.1
far far屬性表示的是距離相機多遠的位置截止渲染,如果設置的值偏小,會有部分場景看不到 1000
let width = window.innerWidth; let height = window.innerHeight; const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000); camera.position.set(150, 100, 300); camera.lookAt(scene.position); 
        
  • 1
  • 2
  • 3
  • 4
  • 5

五、渲染器

概述:從WEBGL的角度來看,three就是對它的進一步封裝,想要進一步了解渲染器這方面的知識點還需要了解一下WEBGL,這里我們就不做過多介紹了。

六、貼圖紋理

6.1 基礎介紹

概述:這部分對于我們是否能夠給別人呈現一個真實的渲染場景來說,很重要,比如下面一個普普通通的正方體,我們只要一加上貼圖,立馬不一樣了。

以前

在這里插入圖片描述

之后

在這里插入圖片描述

6.2 環境貼圖

概述:目前有許許多多的貼圖,比如基礎、透明、環境、法線、金屬、粗糙、置換等等,今天我們呢主要講解一下環境和一點 HDR處理

THREE的世界里面,坐標抽x、y、z的位置關系圖如下所示:

2

紅、綠、藍分別代表x、z、y,我們的貼圖就是在px nx py ny pz nz這六個方向防止一張圖片,其中p就代表坐標軸的正方向

CubeTextureLoader:加載CubeTexture的一個類。 內部使用ImageLoader來加載文件。

//場景貼圖 const sphereTexture = new THREE.CubeTextureLoader().setPath('./textures/course/environmentMaps/0/'); const envTexture= sphereTexture.load([ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ]); //場景添加背景 scene.background = envTexture; //場景的物體添加環境貼圖(無默認情況使用) scene.environment = envTexture; const sphereGeometry = new THREE.SphereGeometry(5, 30, 30); const sphereMaterial = new THREE.MeshStandardMaterial({ roughness: 0,//設置粗糙程度 metalness: 1,//金屬度 envMap:envTexture, }); const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); scene.add(sphere); 
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

gif圖片有點大上傳不了,我就截了幾張圖

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

請添加圖片描述

請添加圖片描述

6.3 HDR處理

概述:高動態范圍圖像,相比普通的圖像,能夠提供更多的動態范圍和圖像細節,一般被運用于電視顯示產品以及圖片視頻拍攝制作當中。

在這里插入圖片描述

import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader; const rgbeLoader = new RGBELoader().setPath('./textures/course/hdr/'); //異步加載 rgbeLoader.loadAsync('002.hdr').then((texture) => { //設置加載方式 等距圓柱投影的環境貼圖 texture.mapping = THREE.EquirectangularReflectionMapping; scene.background = texture; }) 
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

七、拓展

7.1 坐標系

概述:坐標軸能夠更好的反饋物體的位置信息,紅、綠、藍分別代表x、z、y

在這里插入圖片描述

const axesHelper = new THREE.AxesHelper(20);//里面的數字代表坐標抽長度 scene.add(axesHelper); 
        
  • 1
  • 2

7.2 控制器

概述:通過鼠標控制物體和相機的移動、旋轉、縮放

導包

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' 
        
  • 1

應用

const controls = new OrbitControls(camera, renderer.domElement) 
        
  • 1

自旋轉

在這里插入圖片描述

controls.autoRotate = true 
        
  • 1

必須在render函數調用update實時更新才奏效

7.3 自適應

概述:根據屏幕大小自適應場景
在這里插入圖片描述

//自適應屏幕 window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) renderer.setPixelRatio(window.devicePixelRatio) }) 
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

設置相機的寬高比、重新更新渲染相機、渲染器的渲染大小、設備的像素比

7.4 全屏響應

概述:雙擊進入全屏,再次雙擊/ESC退出全屏

在這里插入圖片描述

window.addEventListener('dblclick', () => { let isFullScreen = document.fullscreenElement if (!isFullScreen) { renderer.domElement.requestFullscreen() } else { document.exitFullscreen() } }) 
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

7.5 信息面板

概述;通過操作面板完成界面的移動物體的相關應用

鏈接:https://www.npmjs.com/package/dat.gui

//安裝npm npm install --save dat.gui //如果出現...標記錯誤,安裝到開發依賴就可以了 npm i --save-dev @types/dat.gui 
        
  • 1
  • 2
  • 3
  • 4

1

//界面操作 const gui = new dat.GUI(); //操作物體位置 gui .add(cube.position, 'x') .min(0) .max(10) .step(0.1) .name('X軸移動') .onChange((value) => { console.log('修改的值為' + value); }) .onFinishChange((value) => { console.log('完全停止' + value); }); //操作物體顏色 const colors = { color: '#0000ff', }; gui .addColor(colors, 'color') .onChange((value) => { //修改物體顏色 cube.material.color.set(value); }); 
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

7.6 頻率檢測

概述:檢測幀率

導包

import Stats from 'three/addons/libs/stats.module.js'; 
        
  • 1

應用

const stats = new Stats(); document.body.appendChild(stats.dom); 
        
  • 1
  • 2

自變化

20221021_110002

stats.update() 
        
  • 1

必須在render函數調用update實時更新才奏效

7.7 導航網格

概述:底部二維平面的網格化,幫助我們更好的創建場景

在這里插入圖片描述

const gridHelper = new THREE.GridHelper(10, 20)//網格大小、細分次數 scene.add(gridHelper) 
        
  • 1
  • 2

八、源碼

//導入包 import * as THREE from 'three'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; import * as dat from 'dat.gui'; import Stats from 'three/addons/libs/stats.module.js'; let scene,camera,renderer //場景 scene = new THREE.Scene(); //坐標抽 const axesHelper = new THREE.AxesHelper(20); scene.add(axesHelper); //場景貼圖 const sphereTexture = new THREE.CubeTextureLoader().setPath('./textures/course/environmentMaps/0/'); const envTexture= sphereTexture.load([ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ]); //場景添加背景 scene.background = envTexture; //場景的物體添加環境貼圖(無默認情況使用) scene.environment = envTexture; const sphereGeometry = new THREE.SphereGeometry(5, 30, 30); const sphereMaterial = new THREE.MeshStandardMaterial({ roughness: 0,//設置粗糙程度 metalness: 1,//金屬度 envMap:envTexture, }); const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); scene.add(sphere); //光照 const ambient = new THREE.AmbientLight(0xffffff); scene.add(ambient); const directionalLight = new THREE.DirectionalLight(0xffffff, 0.05); directionalLight.position.set(10,10,10); directionalLight.lookAt(scene.position); scene.add( directionalLight ); //相機 camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000, ); camera.position.set(10,10,20); camera.lookAt(scene.position); scene.add(camera); //渲染器 renderer = new THREE.WebGLRenderer({ //防止鋸齒 antialias: true, }); renderer.setSize(window.innerWidth, window.innerHeight); // renderer.setClearColor(0xb9d3ff, 1); document.body.appendChild(renderer.domElement); //鼠標控制器 const controls = new OrbitControls(camera, renderer.domElement); //阻尼 必須在 render函數調用  controls.update(); controls.dampingFactor = true; controls.autoRotate=true const stats=new Stats() document.body.appendChild(stats.dom); function render () { renderer.render(scene, camera); requestAnimationFrame(render); controls.update();//調用 stats.update() } render(); //全屏操作 window.addEventListener('dblclick', () => { //查詢是否全屏 let isFullScene = document.fullscreenElement; console.log(isFullScene); if (!isFullScene) { renderer.domElement.requestFullscreen(); } else { document.exitFullscreen(); } }) //自適應 window.addEventListener('resize', () => { //寬高比 camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio);//設置像素比 }) //界面操作 const gui = new dat.GUI(); //操作物體位置 gui .add(sphere.position, 'x') .min(0) .max(10) .step(0.1) .name('X軸移動') .onChange((value) => { console.log('修改的值為' + value); }) .onFinishChange((value) => { console.log('完全停止' + value); }); //操作物體顏色 const colors = { color: '#0000ff', }; gui .addColor(colors, 'color') .onChange((value) => { //修改物體顏色 sphere.material.color.set(value); }); 
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143

日歷

鏈接

個人資料

藍藍設計的小編 http://www.skdbbs.com

存檔

92国产精品视频_亚洲a级在线观看_国产精品电影观看_国产精品免费观看在线_精品伊人久久97_亚洲人成在线观_尤物九九久久国产精品的特点_成人激情在线播放_成人黄色大片在线免费观看_亚洲成人精品久久久_久久免费视频在线观看_久久精品国产一区_国产一区二区三区18_亚洲欧美中文字幕在线一区_日韩美女中文字幕_日韩视频免费在线
亚洲精品99久久久久中文字幕| 正在播放欧美一区| 北条麻妃99精品青青久久| 欧美视频中文字幕在线| 亚洲第一级黄色片| 久久久天堂国产精品女人| 日韩大陆毛片av| 亚洲电影在线看| 欧美日韩一区二区免费在线观看| 精品调教chinesegay| 性视频1819p久久| 国内成人精品一区| 日韩黄色高清视频| 久久精品夜夜夜夜夜久久| xxav国产精品美女主播| 国产69精品久久久久9| 国产精品视频区| 欧美日韩国产麻豆| 国产91网红主播在线观看| 欧美精品久久久久a| 国产成人精品免高潮在线观看| 亚洲香蕉成人av网站在线观看| 欧美成人午夜影院| 亚洲精品国产精品国自产观看浪潮| 久久久免费精品| 日韩久久免费视频| 亚洲精品资源美女情侣酒店| 欧美专区中文字幕| 国产精品美腿一区在线看| 国产精品亚洲一区二区三区| 91po在线观看91精品国产性色| 在线观看国产精品日韩av| 欧美黄色www| 亚洲在线免费视频| 日韩欧美国产免费播放| 8x海外华人永久免费日韩内陆视频| 青青青国产精品一区二区| 欧美激情国产精品| 日韩在线www| 福利二区91精品bt7086| 国产精品久久久久久搜索| 国产精品久久久久不卡| 欧美黑人国产人伦爽爽爽| 欧美高清在线播放| 欧美在线激情网| 欧美黄色成人网| 日韩av综合网| 日韩中文视频免费在线观看| 日韩在线观看高清| 久久久久久亚洲精品中文字幕| 亚洲免费福利视频| 欧美日韩国产限制| 国产美女久久精品| 欧美大片大片在线播放| 91精品久久久久久久久| 日韩av色在线| 亚洲综合小说区| 亚洲精品国产精品国产自| 一区二区成人精品| 欧美性猛交xxxx黑人| 久久久久久久久电影| 最新91在线视频| 国产精品羞羞答答| 在线播放精品一区二区三区| 51午夜精品视频| 国产成+人+综合+亚洲欧美丁香花| 日本久久久久久久| 91九色单男在线观看| 欧美巨猛xxxx猛交黑人97人| 97在线免费观看| 在线观看精品自拍私拍| 欧美另类极品videosbest最新版本| 91在线观看免费网站| 欧美一区视频在线| 日韩精品在线视频| 欧美大秀在线观看| 中文日韩在线观看| 亚洲精品av在线播放| 亚洲激情在线观看| 日韩欧美在线视频日韩欧美在线视频| 欧美情侣性视频| 粗暴蹂躏中文一区二区三区| 久久久久国产一区二区三区| 久久精品国产91精品亚洲| 欧美色视频日本版| 琪琪第一精品导航| 91日韩在线播放| 欧美性xxxxhd| 欧美高清在线播放| 在线观看欧美日韩| 欧美激情一二区| 亚洲福利在线播放| 久久久国产一区二区| 亚洲伊人一本大道中文字幕| 欧美色视频日本高清在线观看| 97激碰免费视频| 精品在线观看国产| 国产精品96久久久久久又黄又硬| 另类美女黄大片| 欧美激情一区二区三级高清视频| 91成人福利在线| 日本成人精品在线| 成人444kkkk在线观看| 色久欧美在线视频观看| 国产精品久久久久久久久久免费| 国产日韩精品入口| 国产精品成人观看视频国产奇米| 91久久精品国产91性色| 成人免费福利视频| 日韩在线观看高清| 蜜臀久久99精品久久久久久宅男| 午夜精品久久久久久99热| 欧美国产高跟鞋裸体秀xxxhd| 青青草国产精品一区二区| 欧美性受xxxx黑人猛交| 亚洲第一免费播放区| 久久久久久国产精品三级玉女聊斋| 国产精品永久免费在线| 91夜夜未满十八勿入爽爽影院| 亚洲欧美在线播放| 欧美日韩福利电影| 久久久亚洲成人| 不卡av电影在线观看| 亚洲美女性生活视频| 国产成人综合精品| 91av成人在线| 欧美激情免费在线| 国产在线拍揄自揄视频不卡99| 国产mv免费观看入口亚洲| 久久精品国产精品亚洲| 国产偷亚洲偷欧美偷精品| 在线色欧美三级视频| 国产v综合ⅴ日韩v欧美大片| 国产成人精品优优av| 日韩电影中文字幕一区| 5252色成人免费视频| 日韩av影院在线观看| 日韩黄色在线免费观看| 日本久久中文字幕| 91精品国产综合久久香蕉最新版| 91禁外国网站| 国产精品白嫩初高中害羞小美女| 国产一区二区三区视频| 午夜精品久久17c| 国产一区二区动漫| 动漫精品一区二区| 欧美成人手机在线| 亚洲精品一区二区三区不| 97国产成人精品视频| 九九精品在线观看| 一区二区中文字幕| 亚洲精品www| 国产精品无码专区在线观看| 91视频免费网站| 日韩高清电影好看的电视剧电影| 国产精品精品久久久久久| 国产成人精品最新| 福利视频一区二区| 国产不卡精品视男人的天堂| 欧美在线视频播放| 亚洲大胆人体在线| 欧美日韩国产va另类| 日本精品免费观看| 亚洲国模精品私拍|