Three.js 是一個(gè)開(kāi)源的 JS 3D 圖形庫(kù),用于創(chuàng)建和展示高性能、交互式的 3D 圖形場(chǎng)景。它建立在 WebGL 技術(shù)之上,并提供了豐富的功能和工具,使開(kāi)發(fā)者可以輕松地構(gòu)建令人驚嘆的 3D 可視化效果。
Three.js 提供了一套完整的工具和 API,用于創(chuàng)建和管理 3D 場(chǎng)景、幾何體、紋理、光照、材質(zhì)和相機(jī)等方面。它具有強(qiáng)大的渲染引擎,可以處理復(fù)雜的渲染任務(wù),如陰影、透明度、反射和折射等效果。該庫(kù)還支持動(dòng)畫(huà)、骨骼動(dòng)畫(huà)、粒子系統(tǒng)和物理模擬,可以實(shí)現(xiàn)流暢的動(dòng)態(tài)效果和交互行為。它提供了豐富的控制器和用戶(hù)交互工具,如旋轉(zhuǎn)、縮放、平移和點(diǎn)擊等操作。
Three.js 還支持加載和導(dǎo)入各種文件格式,如 OBJ、STL、FBX 和 glTF 等,以便使用外部工具創(chuàng)建和編輯 3D 模型。它還可以與音頻、視頻和其他 Web 技術(shù)進(jìn)行集成,實(shí)現(xiàn)更豐富的應(yīng)用場(chǎng)景。
接下來(lái)我們依次介紹three的三大件,渲染器(Renderer),場(chǎng)景(Scene),照相機(jī)(Camera),這三個(gè)展開(kāi)說(shuō)每一個(gè)都能單開(kāi)一篇,這里簡(jiǎn)單介紹下概念,我們主要從案例中學(xué)習(xí)具體知識(shí),感興趣的朋友可以看這個(gè)鏈接Three.js學(xué)習(xí),介紹的比較詳細(xì)
渲染器(Renderer)
當(dāng)我們?cè)诠俜轿臋n搜索WebGL時(shí)會(huì)顯示七個(gè)類(lèi)渲染器
WebGLMultipleRenderTargets
WebGLRenderer
WebGL1Renderer
WebGLRenderTarget
WebGL3DRenderTarget
WebGLArrayRenderTarget
WebGLCubeRenderTarget
暫時(shí)我們只聚焦于WebGLRenderer,其實(shí)真正經(jīng)常用到的也是它。
WebGL1Renderer
three在 r118(包含此版本)后,自動(dòng)使用WebGL 2 渲染上下文,如果您沒(méi)有時(shí)間升級(jí)代碼,但仍想使用最新版本,可以使用WebGL1Render。此版本的渲染器將強(qiáng)制執(zhí)行WebGL 1渲染上下文。
WebGLRenderer
下面是一個(gè)基礎(chǔ)的WebGLRenderer應(yīng)用
var renderer;
var width,height;
function initThree() {
width = document.getElementById("box").clientWidth;
height = document.getElementById("box").clientHeight;
// 生成渲染器對(duì)象(屬性antialias:抗鋸齒效果為設(shè)置有效)
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(width,height);
document.getElementById("box").appendChild(renderer.domElement);
// 設(shè)置canvas背景色(clearColor)和背景色透明度(clearAlpha)
renderer.setClearColor(0xFFFFFF, 1.0);
}
場(chǎng)景(Scene)
three.js添加的模型都添加到了場(chǎng)景中,其初始化很簡(jiǎn)單
var scene;
function initScene(){
scene = new THREE.Scene();
// 場(chǎng)景的背景色
scene.background = new THREE.Color( 0xf0f0f0 );
}
// 添加一個(gè)物體 mesh是什么后面會(huì)說(shuō)明
scene.add(mesh);
照相機(jī)(Camera)
你可以把相機(jī)想象為我們的眼睛,它決定了場(chǎng)景中哪個(gè)角度的景色會(huì)顯示出來(lái) ,就是我們所看到的,人站在不同位置,抬頭或者低頭都能夠看到不同的景色 ,默認(rèn)的照相機(jī)與加載進(jìn)來(lái)的模型都處于坐標(biāo)原點(diǎn),為了能夠看到模型,需要將照相機(jī)位置偏移。
經(jīng)常用到相機(jī)分為:
CubeCamera
此相機(jī)適配 WebGLCubeRenderTarget
正交相機(jī)-OrthographicCamera
在此投影模式下,無(wú)論對(duì)象與攝影機(jī)的距離如何,其在渲染圖像中的大小都保持不變。這對(duì)于渲染2D場(chǎng)景和UI元素等非常有用。
透視相機(jī)-PerspectiveCamera
這種投影模式是為了模仿人眼的視覺(jué)方式而設(shè)計(jì)的。它是用于渲染三維場(chǎng)景的最常見(jiàn)的投影模式。
我所有案例three版本是 three-155
先看效果圖
上代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
width: 100%;
height: 100%;
}
* {
margin: 0;
padding: 0;
}
.label {
font-size: 20px;
color: #fff;
font-weight: 700;
}
</style>
</head>
<body>
<div id="container"></div>
<script type="importmap">
{
"imports": {
"three": "../three-155/build/three.module.js",
"three/addons/": "../three-155/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import Stats from 'three/addons/libs/stats.module.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
let stats, labelRenderer;
let camera, scene, renderer, mesh, target, controls;
const group = new THREE.Group();
init();
initHelp();
initLight();
axesHelperWord();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 10, 2000 );
camera.position.set(0, 500, 500);
camera.up.set(0, 1, 0);
camera.lookAt(0, 0, 0);
scene = new THREE.Scene();
scene.background = new THREE.Color( '#ccc' );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
labelRenderer = new CSS2DRenderer();
labelRenderer.setSize( window.innerWidth, window.innerHeight );
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0px';
labelRenderer.domElement.style.pointerEvents = 'none';
document.getElementById( 'container' ).appendChild( labelRenderer.domElement );
window.addEventListener( 'resize', onWindowResize );
controls = new OrbitControls( camera, renderer.domElement );
controls.minDistance = 10;
controls.maxDistance = 1000;
// 設(shè)置為true可啟用阻尼(慣性),可用于為控件提供重量感。默認(rèn)值為false。
// 請(qǐng)注意,如果啟用了此選項(xiàng),則必須在動(dòng)畫(huà)循環(huán)中調(diào)用.update()。
controls.enableDamping = false;
controls.screenSpacePanning = false; // 定義平移時(shí)如何平移相機(jī)的位置 控制不上下移動(dòng)
stats = new Stats();
stats.setMode(1); // 0: fps, 1: ms
document.body.appendChild( stats.dom );
scene.add( group );
}
function initLight() {
const light = new THREE.DirectionalLight(new THREE.Color('rgb(253,253,253)'));
light.position.set(100, 100, -10);
light.intensity = 3; // 光線(xiàn)強(qiáng)度
const AmbientLight = new THREE.AmbientLight(new THREE.Color('rgb(255,255,255)'));
scene.add( light );
scene.add( AmbientLight );
}
function initHelp() {
const size = 1000;
const divisions = 20;
const gridHelper = new THREE.GridHelper( size, divisions );
scene.add( gridHelper );
// The X axis is red. The Y axis is green. The Z axis is blue.
const axesHelper = new THREE.AxesHelper( 500 );
scene.add( axesHelper );
}
function axesHelperWord() {
let xP = addWord('X軸');
let yP = addWord('Y軸');
let zP = addWord('Z軸');
xP.position.set(200, 0, 0);
yP.position.set(0, 200, 0);
zP.position.set(0, 0, 200);
}
function addWord(word) {
let name = `<span>${word}</span>`;
let moonDiv = document.createElement( 'div' );
moonDiv.className = 'label';
// moonDiv.textContent = 'Moon';
// moonDiv.style.marginTop = '-1em';
moonDiv.innerHTML = name;
const label = new CSS2DObject( moonDiv );
group.add( label );
return label;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
stats.update();
controls.update();
labelRenderer.render( scene, camera );
renderer.render( scene, camera );
}
</script>
</body>
</html>
這是一個(gè)簡(jiǎn)單的3D場(chǎng)景,除了之前介紹的三大件,renderer,camera、scene,
stats.js
左上角是一個(gè) Three.js 開(kāi)發(fā)的輔助庫(kù),主要用于檢測(cè)動(dòng)畫(huà)運(yùn)行時(shí)的幀數(shù)。
stats.setMode(1); // 0: fps, 1: ms
設(shè)置為 0:檢測(cè)的是畫(huà)面每秒傳輸幀數(shù)(fps)
設(shè)置為 1:檢測(cè)的是畫(huà)面渲染的時(shí)間
OrbitControls.js
動(dòng)態(tài)觀察控件允許攝影機(jī)圍繞目標(biāo)動(dòng)態(tài)觀察。
GridHelper
是一個(gè)用于定義網(wǎng)格的對(duì)象。網(wǎng)格是二維的線(xiàn)陣列。這也是個(gè)輔助工具,幫我們看清3D場(chǎng)景
AxesHelper
一個(gè)軸對(duì)象,以一種簡(jiǎn)單的方式顯示3個(gè)軸。X軸為紅色,Y軸為綠色。Z軸為藍(lán)色。這也是個(gè)輔助工具,可以清晰的讓我們?cè)?D場(chǎng)景中看清方向也就是 X、Y、Z軸在哪
CSS2DRenderer
圖中的文案用到了CSS2DRenderer,當(dāng)然對(duì)應(yīng)的還有CSS3DRenderer,這兩者的主要區(qū)別就是CSS2DRenderer會(huì)永遠(yuǎn)面向相機(jī),且大小不會(huì)隨意相機(jī)移動(dòng)而變化。非常適合輔助AxesHelper指明X、Y、Z軸
light
當(dāng)然還有一個(gè)非常重要的光源,這里用到了DirectionalLight 和 AmbientLight,其實(shí)還有一些比如:PointLight、SpotLight、RectAreaLight后面我們會(huì)介紹到
AmbientLight
該燈光在全局范圍內(nèi)平等地照亮場(chǎng)景中的所有對(duì)象。
該燈光不能用于投射陰影,因?yàn)樗鼪](méi)有方向。
DirectionalLight
向特定方向發(fā)射的光。這種光的行為就像它是無(wú)限遙遠(yuǎn)的,并且從它產(chǎn)生的光線(xiàn)都是平行的。這方面的常見(jiàn)用例是模擬日光;太陽(yáng)離得足夠遠(yuǎn),它的位置可以被認(rèn)為是無(wú)限的,所有來(lái)自它的光線(xiàn)都是平行的。
此燈光可以投射陰影
具體用法參數(shù)大家可以官網(wǎng)查看下three官網(wǎng)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-731708.html
大家會(huì)發(fā)現(xiàn)現(xiàn)在3D場(chǎng)景中,除了一些輔助方法,就沒(méi)別的了,其實(shí)這就是我經(jīng)常用到的標(biāo)準(zhǔn)模版,有了它當(dāng)我們需要測(cè)試或者學(xué)習(xí)某些效果時(shí),這個(gè)就可以直接拿來(lái)用,然后我們往里添加需要的效果即可,后面案例中我會(huì)一一介紹。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-731708.html
到了這里,關(guān)于ThreeJS-3D教學(xué)一:基礎(chǔ)場(chǎng)景創(chuàng)建的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!