当前位置:网站首页>用Three.js做一個簡單的3D場景
用Three.js做一個簡單的3D場景
2022-07-03 03:17:00 【抱緊北方】
Three.js是什麼
Three.js 是一款運行在瀏覽器中的 3D 引擎,我們可以用它來創造我們所需要的一系列3D動畫場景,簡而言之就是建在網頁上的3D模型。利用Three.js可以制作出很多酷炫的3D動畫,並且Three.js還可以通過鼠標、鍵盤、拖拽等事件形成交互,在頁面上增加一些3D動畫和3D交互可以產生更好的用戶體驗。
Three.js程序結構
主要分為三大結構:場景Scene 相機Camera 渲染器Renderer
程序整個運行的過程就是:先加載場景—— 然後相機——最後渲染器

從實際生活中拍照角度理解,立方體網格模型和光照組成了一個虛擬的三維場景類似你要拍攝的物體,相機對象就像你生活中使用的相機一樣可以拍照,只不過一個是拍攝真實的景物,一個是拍攝虛擬的景物,拍攝一個物體的時候相機的比特置和角度需要調整,虛擬的相機還需要設置投影方式,當你創建好一個三維場景,相機也設置好,就差一個動作“哢”,通過渲染器就可以執行拍照動作了
簡單理解了用Three.js做3D引擎的原理,那今天我們就來做一個簡單的3D立方體吧
立方體
首先我們要在html文件中引入three.js,就像引入其它.js文件一樣直接引入,它需要去官網下載
這裏,我用的是相對路徑

或者引用相對路徑
<!--絕對路徑遠程加載-->
<script src="http://www.yanhuangxueyuan.com/3D/example/three.js"></script>
<!-- 壓縮版本 -->
<script src="http://www.yanhuangxueyuan.com/3D/example/three.min.js"></script>然後,在body裏插入代碼段就可以了,具體代碼解釋如下:
<body>
<script>
// 創建場景對象Scene
var scene = new THREE.Scene();
//創建網格模型
// var geometry = new THREE.SphereGeometry(60, 40, 40); //創建一個球體幾何對象
var geometry = new THREE.BoxGeometry(100, 100, 100); //創建一個立方體幾何對象
var material = new THREE.MeshLambertMaterial({ //創建材質對象Material
color: 0x008080 //立方體的顏色
});
var mesh = new THREE.Mesh(geometry, material); //創建網格模型對象Mesh
scene.add(mesh); //將網格mesh模型添加到場景中
// 光源設置
//點光源
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300); //點光源的比特置
scene.add(point); //點光源添加到場景中
//環境光
var ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient);
// console.log(scene)
// console.log(scene.children)
// 相機設置
var width = window.innerWidth; //窗口寬度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口寬高比
var s = 200; //三維場景顯示範圍控制系數,系數越大,顯示的範圍越大
//創建相機對象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //設置相機比特置
camera.lookAt(scene.position); //設置相機方向(指向的場景對象)
// 創建渲染器對象
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);//設置渲染區域尺寸
renderer.setClearColor(0xb9d3ff, 1); //設置背景顏色
document.body.appendChild(renderer.domElement); //body元素中插入canvas對象
//執行渲染操作 指定場景、相機作為參數
renderer.render(scene, camera);
</script>
</body>展示效果:

旋轉動畫
做到這裏,只是在網頁上呈現一個不動的3D立方體,為了增加趣味性和操作性,我們可以將渲染操作封裝成一個函數,用setInterval讓它間隔20ms周期性地調用render()渲染函數、不斷地刷新
// 渲染函數
function render() {
renderer.render(scene,camera);//執行渲染操作
mesh.rotateY(0.01);//每次繞y軸旋轉0.01弧度
}
//間隔20ms周期性調用渲染函數render()
setInterval("render()",20);這裏的時間單比特是ms,20ms也就是刷新頻率為50FPS(1s/20ms),即1s內屏幕刷新50次(相信打遊戲的小夥伴都不陌生)
展示效果如下:

或者也可以通過requestAnimationFrame請求再次執行渲染函數render,渲染下一幀,這樣也可以達到不斷刷新,旋轉的效果
// 渲染函數
let T0 = new Date();//上次時間
function render() {
let T1 = new Date();//本次時間
let t = T1-T0;//時間差
console.log(t);//兩幀之間時間間隔 單比特:ms
T0 = T1;//把本次時間賦值給上次時間
renderer.render(scene,camera);//執行渲染操作
mesh.rotateY(0.01);//每次繞y軸旋轉0.01弧度
requestAnimationFrame(render);//請求再次執行渲染函數render,渲染下一幀
}
render();我們可以創建兩個臨時變量T1和T0去記錄本次執行渲染和上次執行渲染所需時間,再將他們相减,就得到了兩幀之間的時間間隔,發現穩定在17ms左右,58的fps,相較於我們自己設置的時間周期,它的fps更高,也沒有局限性
展示效果如下:

鼠標操作三維場景旋轉縮放
我們已經實現了讓立方體機械性的動了起來,那可不可以通過鼠標來操控,讓它可以轉到任意我們想要的角度和比特置呢
首先,我們還需要引入一個新的Threejs擴展控件——OrbitControls.js,它叫軌道控件,用它可以實現場景用鼠標交互,讓場景動起來,控制場景的旋轉、平移和縮放
<!-- 引入軌道控件OrbitControls.js -->
<!-- 相對路徑 -->
<script src="./OrbitControls.js"></script>
<!-- 絕對路徑 -->
<script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js"></script>這裏,軌道控件提供了一個構造函數,我們創建一個新的構造函數,再添加一個鼠標監聽事件,鼠標有所動作,觸發渲染函數,立方體會執行相應的效果
// 渲染函數
function render() {
renderer.render(scene, camera); //執行渲染操作
}
render();
//創建控件對象 相機對象camera作為參數 控件可以監聽鼠標的變化,改變相機對象的屬性
var controls = new THREE.OrbitControls(camera,renderer.domElement);
//監聽鼠標事件,觸發渲染函數,更新canvas畫布渲染效果
controls.addEventListener('change', render);展示效果:

實際上軌道控件還有很多屬性可以設置,但在本小例中沒有應用到,詳細的用法可參考官方文檔:點擊打開鏈接
边栏推荐
- How to limit the size of the dictionary- How to limit the size of a dictionary?
- C programming learning notes [edited by Mr. Tan Haoqiang] (Chapter III sequence programming) 05 data input and output
- Find the storage address of the elements in the two-dimensional array
- Lvgl usage experience
- Stop using system Currenttimemillis() takes too long to count. It's too low. Stopwatch is easy to use!
- C#通用接口调用
- 模型转换onnx2engine
- open file in 'w' mode: IOError: [Errno 2] No such file or directory
- [error record] the parameter 'can't have a value of' null 'because of its type, but the im
- 销毁Session和清空指定的属性
猜你喜欢

Stop using system Currenttimemillis() takes too long to count. It's too low. Stopwatch is easy to use!

The idea setting code is in UTF-8 idea Properties configuration file Chinese garbled
![MySQL practice 45 [global lock and table lock]](/img/23/fd58c185ae49ed6c04f1a696f10ff4.png)
MySQL practice 45 [global lock and table lock]

Hi3536C V100R001C02SPC040 交叉编译器安装

900W+ 数据,从 17s 到 300ms,如何操作
![[pyg] understand the messagepassing process, GCN demo details](/img/8b/8490aac98fd2753e661f74e284f43d.png)
[pyg] understand the messagepassing process, GCN demo details
![[shutter] monitor the transparency gradient of the scrolling action control component (remove the blank of the top status bar | frame layout component | transparency component | monitor the scrolling](/img/c3/b9a614001f80345a5c1cb3c68ab27c.jpg)
[shutter] monitor the transparency gradient of the scrolling action control component (remove the blank of the top status bar | frame layout component | transparency component | monitor the scrolling
![MySQL practice 45 lecture [row lock]](/img/71/344daddee537a96f0d38241e6896e1.png)
MySQL practice 45 lecture [row lock]

力扣------网格中的最小路径代价
![Learning notes of C programming [compiled by Mr. Tan Haoqiang] (Chapter III sequence programming) 04 C sentence](/img/60/bae0e8d92a53bcd2b2de3fb22b3b99.jpg)
Learning notes of C programming [compiled by Mr. Tan Haoqiang] (Chapter III sequence programming) 04 C sentence
随机推荐
com. fasterxml. jackson. databind. Exc.invalidformatexception problem
VS 2019 配置tensorRT生成engine
docker安装redis
Parameter index out of range (1 > number of parameters, which is 0)
MySQL practice 45 lecture [transaction isolation]
Converts a timestamp to a time in the specified format
45 lectures on MySQL [index]
Summary of determinant knowledge points in Chapter 1 of Linear Algebra (Jeff's self perception)
Spark on yarn resource optimization ideas notes
Vs 2019 configuration tensorrt
Pat class B "1104 forever" DFS optimization idea
MySql实战45讲【行锁】
Réglez la hauteur et lancez le système. Currenttimemillis catton
Installation and use of memory leak tool VLD
Docker install redis
Do you really understand relays?
为什么线程崩溃不会导致 JVM 崩溃
@Accessors注解作用指定前缀遵守驼峰命名
Change and access of median value of listening object
Variable declarations following if statements