当前位置:网站首页>用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);
展示效果:
實際上軌道控件還有很多屬性可以設置,但在本小例中沒有應用到,詳細的用法可參考官方文檔:點擊打開鏈接
边栏推荐
- Why does thread crash not cause JVM crash
- 复选框的使用:全选,全不选,选一部分
- What happens between entering the URL and displaying the page?
- Agile certification (professional scrum Master) simulation exercises
- The base value is too large (the error is marked as "08") [duplicate] - value too great for base (error token is'08') [duplicate]
- Idea format code idea set shortcut key format code
- The series of hyperbolic function in daily problem
- 将时间戳转为指定格式的时间
- 监听对象中值变化及访问
- [error record] the parameter 'can't have a value of' null 'because of its type, but the im
猜你喜欢
el-tree搜索方法使用
Hi3536C V100R001C02SPC040 交叉编译器安装
Nce detail of softmax approximation
UMI route interception (simple and rough)
LVGL使用心得
docker安装redis
Nasvit: neural architecture search of efficient visual converter with gradient conflict perception hypernetwork training
为什么线程崩溃不会导致 JVM 崩溃
MySql实战45讲【事务隔离】
VS 2019 配置tensorRT生成engine
随机推荐
[error record] the parameter 'can't have a value of' null 'because of its type, but the im
模型转换onnx2engine
The series of hyperbolic function in daily problem
Nce detail of softmax approximation
将时间戳转为指定格式的时间
node 开启服务器
Reset or clear NET MemoryStream - Reset or Clear . NET MemoryStream
MySQL practice 45 [global lock and table lock]
The calculation of stripe, kernel and padding in CNN
MySQL practice 45 lecture [transaction isolation]
VS 2019配置tensorRT
Installation and use of memory leak tool VLD
C#通用接口调用
Limit of one question per day
MySQL practice 45 lecture [row lock]
C# WebRequest POST模式 ,基于“Basic Auth”口令认证模式,使用multipart/form-data方式上传文件及提交其他数据
[combinatorics] number of solutions of indefinite equations (number of combinations of multiple sets R | number of non negative integer solutions of indefinite equations | number of integer solutions
模糊查询时报错Parameter index out of range (1 > number of parameters, which is 0)
Hi3536c v100r001c02spc040 cross compiler installation
Find the storage address of the elements in the two-dimensional array