1. 程式人生 > >Threejs 三大元件 -- 場景、相機、渲染器

Threejs 三大元件 -- 場景、相機、渲染器

Three.js 中,要渲染物體到網頁中,必備3個元件:場景 scene、相機 camera、渲染器 renderer

場景 scene

場景是所有物體的容器。在Threejs中,場景只有一種,用 THREE.Scene 表示,構建場景如下:

var scene = new THREE.Scene();

場景元件包括:

相機 — 決定哪些東西要渲染到螢幕上

光源 — 對材質如何顯示,及陰影生成產生影響

物體 — Mesh物件,在相機視圖裡主要的渲染物件,如方塊、球體等

注:Mesh物件 是區分相機和光源物件的方法。--> if( lastObject instanceof THREE.Mesh )

場景的兩個屬性 -- fog 霧化 和 overrideMaterial 材質覆蓋

//霧化效果 
//1-線性霧,密度隨著距離的增加呈線性增長。引數為:霧的顏色,開始的地方,濃度的加深程度。
scene.fog = new THREE.Fog(0xffffff, 0.015, 100); 
//2-指數霧,密度隨距離呈指數級增長。引數為:霧的顏色,濃度
scene.fog = new THREE.Fog(0xffffff, 100); 

//材質覆蓋:所有物體設定為同樣的材質
scene.overrideMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});

場景函式

變數
scene.children.length; //場景中物體的個數

函式
scene.add(obj);	//向場景中新增物體
scene.remove(obj); //刪除場景中的物體
scene.children();	//獲取場景中的所有子物件
scene.getChildByName(name);	//通過名稱獲取場景中的物體物件
scene.traverse(function (e){});	//遍歷場景中的每個物體,對物體進行操作

相機 camera

相機決定了場景中哪個角度的景色會被渲染出來。

在Threejs中用 THREE.Camera( ) 表示相機,它是相機的抽象基類。

屬性:

.matrixWorldInverse — matrixWorld的逆矩陣。matrixWorld包含相機的世界變換矩陣。

.projectionMatrix — 投影變換矩陣。

方法

.getWorldDirection( vector ) — 引數可選,返回代表相機方向的一個在世界空間中的向量。

.lookAt( vector ) — vector為觀察點,設定相機在全域性空間中的位置。

.clone( camera ) — 返回一個相機的克隆。

注:camera 的 position、up、lookAt的區別:position表示相機的位置,up表示相機以哪個方向為上方,lookAt表示相機看向哪個座標。

Threejs提供的相機有正交相機 OrthographicCamera、透視相機 PerspectiveCamera、全景相機 CubeCamera 和 3D相機 StereoCamera。主要介紹正交相機和透視相機。

正交相機 OrthographicCamera

正交相機重在表現物體的實際尺寸,沒有近大遠小的效果;一般是用在製圖、建模上面。

建構函式:

var camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);

引數:

left — 可被渲染空間的左平面,比這個左側邊界更遠的物件不會被渲染

right — 可被渲染空間的右平面

top — 可被渲染空間的最上面

bottom — 可被渲染空間的最下面

near — 基於相機所在的位置,從這一點開始渲染場景

far — 基於相機所在的位置,一直渲染到場景中的這一點


這六個引數分別代表正交相機拍攝到的空間的六個面的位置,這六個面圍成一個長方體,我們稱為視景體 (Frustum)。只有在視景體內部的物體才可能顯示在螢幕上,而視景體外的物體會在顯示之前被裁減掉。

屬性

.zoom — 獲取和設定相機縮放因子。

.left, .right, .top, .bottom, .near, .far — 相機視椎體左面,右面,上面,下面,前面,後面。

方法

.setViewOffset( fullWidth, fullHeight, x, y, width, height )

     fullWidth — 多檢視設定的全寬

     fullHeight — 多檢視設定的全高

     x — 副攝像頭的水平偏移

     y — 副攝像頭的垂直偏移

     width — 副攝像頭的寬度

     height — 副攝像頭的高度

 該方法用於在一個較大的視椎體中設定檢視偏移。這對於多視窗或多監視器/多機設定是有用的。

 比如,有一組3x2顯示屏,每個螢幕解析度為 1920x1080,顯示屏位於一個網格中,如下:

  

 然後對於每個顯示屏,可以如下呼叫:

var w = 1920;
var h = 1080;
var fullWidth = w * 3;
var fullHeight = h * 2;

// A
camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
// B
camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
// C
camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
// D
camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
// E
camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
// F
camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
 注意,沒有任何理由在一個網格中的顯示屏必須具備同樣的尺寸。

.clearViewOffset( ) — 清除檢視偏移。

.updateProjectionMatrix( ) — 更新相機投影矩陣,必須在引數發生變化後呼叫。

.clone( ) — 返回一個 OrthographicCamera 物件的克隆。

.toJSON( ) — 把相機資料轉換成JSON格式。

透視相機 PerspectiveCamera

透視相機更接近人眼的觀看效果,有“近大遠小”的效果。應用比較廣泛,只要不是正交的應用,基本上使用透視相機就可以了。

建構函式:

var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
引數:

fov 視角 — 人差不多有180度的視角,但計算機顯示器一般會選擇一塊兒較小的區域。對於遊戲來說,大多數情況下會用60-90度左右的視角。推薦預設值:45。

aspect 長寬比 — 渲染區域的長寬比。一般會使用整個視窗作為輸出介面。推薦預設值:window.innerWidth/window.innerHeight。

near 近面 — 相機開始渲染場景的地方,通常會設一個很小的值,從而可以看到所有物體。推薦預設值:0.1。

far 遠面 — 相機結束渲染場景的地方,如果值太低,場景中的一部分可能不會被渲染;如果值太高,某些情況下會影響渲染效率。推薦預設值:1000。


屬性:

.fov — 相機視椎體垂直視角,從下到上的觀察角度。

.zoom — 獲取或設定相機縮放因子。

.near, .far — 相機視椎體近裁剪面,遠裁剪面。

.focus — 焦點,用於立體視覺和場深度效果的目標距離。

.aspect — 相機視椎體寬高比。

.view — 視椎體視窗規格或null。

.filmGauge — 用於較大座標軸的膠片尺寸。預設為35毫米。

.filmOffset — 水平偏離中心偏移量。和 .filmGauge 同單位。

方法

.getEffectiveFOV( )  — 返回考慮了縮放係數 .zoom 的當前視角,單位為角度。

.getFocalLength( ) — 返回當前和 .filmGauge 有關的 .fov 的焦距。

.getFilmWidth( ) — 返回膠片上影象的寬度。如果 .aspect >= 1(景觀格式 landscape format),結果等於 .filmGauge。

.getFilmHeight( ) — 返回膠片上影象的高度。如果 .aspect <=1(肖像格式 portrait format),結果等於 .filmGauge。

.setFocalLength( focalLength ) — 設定當前和 .filmGauge 有關的 .fov 的焦距。預設為35mm。

.setViewOffset( fullWidth, fullHeight, x, y, width, height ) — 同 OrthographicCamera。

.clearViewOffset( ), .updateProjectionMatrix( ), .clone( ), .toJSON — 同 OrthographicCamera。

渲染器 renderer

渲染器決定了渲染的結果應該畫在元素的什麼元素上面,並且以怎樣的方式來繪製。

Threejs中提供了很多的渲染方式,主要介紹 CanvasRenderer 、WebGLRenderer兩種。

注:CanvasRenderer 和 WebGLRenderer 都是使用HTML5的 <canvas> 直接內嵌在網頁中。Cavas渲染器中的“Canvas”表示使用Canvas 2d而不是WebGL。

WebGLRenderer

WebGL渲染器使用WebGL來繪製場景(如果裝置支援),使用WebGL能夠利用GPU硬體加速從而提高渲染效能。

建構函式:

var renderer = new THREE.WebGLRenderer(parameters);
引數

parameters — 是一個可選物件,包含用來定義渲染器行為的屬性。沒有設定該引數時,使用預設值。

parameters物件裡可包含以下屬性:

  antialias — Boolean,預設為false。是否開啟反鋸齒。

  precision — highp/mediump/lowp,預設為highp。著色器的精度。

  alpha — Boolean,預設為false。是否可以設定背景色透明。

  premultipliedAlpha — Boolean,預設為true。是否允許渲染器中的顏色具有alpha預乘的效果。

  preserveDrawingBuffer — Boolean,預設為false。是否儲存繪圖緩衝,直到手動清除或覆蓋。

  stencil — Boolean,預設為true。繪圖緩衝區是否具有至少8位的模板緩衝區。

  depth — Boolean,預設為true。繪圖緩衝區是否具有至少16位的深度緩衝區。

  logarithmicDepthBuffer — Boolean,預設為false。是否使用對數深度緩衝區。

屬性

.domElement — 用來繪製輸出的Canvas物件。通過建構函式中的渲染器自動建立,新增到網頁中即可。

.context — 從HTML5 canvas 中獲取的用來繪圖的WebGL渲染上下文。

.autoClear — 定義渲染器是否應該在渲染之前自動清除其輸出。

.autoClearColor — 如果autoClear為true,該屬性用來定義渲染器是否需要清除顏色快取,預設為true。

.autoClearDepth — 如果autoClear為true,該屬性用來定義渲染器是否需要清除深度快取,預設為true。

.autoClearStencil — 如果autoClear為true,該屬性用來定義渲染器是否需要清除模板快取,預設為true。

.sortObjects — 定義渲染器是否需要物件排序,預設為true。

  注:排序是用來試圖正確的渲染具有一定程度透明度的物件。根據定義,排序物件可能在所有情況下都不工作。根據應用程式的需要,可能需要關閉該排序功能,使用其他方法處理透明渲染,比如手動確定物體的繪製順序。  

.clippingPlanes — 使用者定義的在世界空間中的裁剪平面物件。這些平面是全域性範圍可用的。空間中的點和該平面的點積為負的將被裁剪掉。預設為[]。

.localClippingEnabled — 定義渲染器是否考慮物件級別的裁剪平面。預設為false。

.gammaInput — 所有紋理和顏色是否使用預乘的gamma值來輸入。預設為false。

.gammaOutput — 所有紋理和顏色是否使用預乘的gamma值來輸出。預設為false。

.shadowMap — 實現陰影貼圖(或陰影對映)的元件的引用。

.shadowMap.enabled — 是否啟用在場景中的陰影貼圖。預設為false。

.shadowMap.type — 陰影貼圖型別定義(未經過濾,百分比接近過濾,帶著色器雙線性過濾的百分比接近過濾)。

   — 可選值:THREE.BasicShadowMap,THREE.PCFShadowMap,THREE.PCFSoftShadowMap。

   — 預設為THREE.PCFShadowMap。

.shadowMap.renderReverseSided — 預設為true。是否將材質所指定的反面渲染到陰影貼圖中。如果禁用,必須在表面光源上設定適當的shadow.bias,可以同時投射和接收陰影以正確渲染。

.shadowMap.renderSingleSided — 預設為true。是否將指定的材料視為雙面,而在渲染陰影貼圖時使用正面(front-side)。如果禁用,必須在表面光源上設定適當的shadow.bias,可以同時投射和接受陰影以正確渲染。

.maxMorphTargets — 預設為8。著色器中允許的最大MorphTargets數量。標準材料只允許8個MorphTargets。

.maxMorphNormals — 預設為4。著色器中允許的最大MorphNormals數量。標準材料只允許8個MorphNormals。

.info — 關於顯示卡記憶體和渲染過程統計資訊的物件。便於除錯和分析。該物件包含以下欄位:memory(geometries、textures)、render(calls、vertices、faces、points)、programs。

方法

.getContext( ) — 返回WebGL渲染上下文。

.getContextAttributes — 返回描述WebGL上下文建立時所設定屬性的物件。

.supportsVertexTextures( ) — 返回Boolean值,如果該上下文支援頂點紋理,則為true。

.getPixelRatio( ) — 返回當前裝置的畫素比。

.setPixelRatio( value ) — 設定裝置畫素比。通常用於HiDPI裝置防止模糊輸出canvas。

.getSize( ) — 返回包含渲染器輸出canvas寬高的物件,以畫素為單位。

.setSize( width,height,updateStyle ) — 調整輸出canvas尺寸,要考慮裝置畫素比,並設定視口匹配該尺寸。如果設定updateStyle為true,則顯示新增畫素到輸出canvas的樣式中。

.setViewport( x,y,width,height ) — 設定視口,從(x,y)到(x+width,y+height)。

.setScissor( x,y,width,height) — 設定剪裁區域,從(x,y)到(x+width,y+height)。

注:setViewport 和 setScissor 方法中的(x,y)是該區域的左下角。該區域被定義從左到右的寬度,以及從底部到頂部的高度。該垂直方向的定義和HTML canvas元素的填充方向相反。

.setScissorTest( ) — Boolean,啟用或禁用裁剪測試。被啟用時,只有裁剪區域內的畫素會被進一步的渲染行為所影響。

.setClearColor( color,alpha ) — 設定清除的顏色和透明度。

.getClearColor( ) — 返回使用當前清除顏色的THREE.Color例項。

.getClearAlpha( ) — 返回使用當前清除透明度的float。範圍 0-1。

.clear( color,depth,stencil ) — 使渲染器來清除其顏色、深度和模板繪製緩衝。該方法初始化顏色緩衝區為當前清除顏色值。

.renderBufferImmediate( object,program,shading ) — 渲染一個即時緩衝區。被renderImmediateObject所呼叫。

object — 3D物件例項(Object3D)

program — 著色器程式例項(shaderProgram)

shading — 材料例項(Material)

.renderBufferDirect( camera,lights,fog,material,geometryGroup,object ) — 使用相機和正確的材料渲染緩衝模型組。

.renderBuffer(camera,lights,fog,material,geometryGroup,object) — 使用相機和正確的材料渲染模型組。

.render( scene,camera,renderTarget,forceClear ) — 使用相機渲染一個場景。

— 如果指定了renderTarget,則渲染到上面,否則渲染到通常的canvas上。

— 如果forceClear為true,顏色、深度和模板繪製緩衝將在渲染前被清除,即使渲染器的autoclear屬性為false。

— 即使forceClear 設為true,仍然可以通過設定 .autoClearColor, .autoClearStencil, .autoClearDepth 屬性為false來阻止特定的快取被清除。

.readRenderTargetPixels( renderTarget,x,y,width,height,buffer ) — 從渲染目標中讀取畫素資料到給定的緩衝區中。快取應該是一個js Uint8Array物件,通過new Uint8Array( renderTargetWidth * renderTargetWidth * 4 )來例項化,考慮大小和顏色資訊。

.renderImmediateObject( camera,lights,fog,material,object ) — 使用相機渲染即時物件。

.setFaceCulling( cullFace,frontFace ) — 用於設定GPU中gl的fontFace和cullFace狀態,從而啟用或禁用渲染時的面剔除。

cullFace — back / front / front_and_back / false

frontFace — ccw / cw

.setTexture( texture,slot ) — 設定正確的紋理為webgl著色器的正確插槽。插槽可以作為一個值的均勻的取樣。

texture — 需要設定的texture

slot — 紋理所要使用的槽slot編號。

.setRenderTarget( renderTarget ) — 設定當前渲染目標。如果引數被忽略,設定繪製的canvas為當前渲染目標。

.supportsCompressedTextureS3TC( ) — 如果WebGL支援S3TC格式的紋理壓縮,返回true。

.getMaxAnisotropy( ) — 返回紋理的各向異性水平。

.getPrecision( ) — 獲取著色器作用精度,返回 highp / mediump / lowp。

.clearTarget( renderTarget,color,depth,stencil ) — 清除渲染目標。

renderTarget — 需要被清除的renderTarget。

color — 如果設定,顏色被清除。

depth — 如果設定,深度被清除。

stencil —如果設定,模板被清除。

CanvasRenderer

Canvas渲染器不使用WebGL來繪製場景,使用相對較慢的Canvas 2D Context API。

建構函式:

var renderer = new THREE.CanvasRenderer();

在不確定瀏覽器是否支援WebGL渲染器的時候,可以通過以下程式碼來實現渲染器的選擇:

function webglAvailable() {
    try {
	var canvas = document.createElement( 'canvas' );
	return !!( window.WebGLRenderingContext && (canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ));
    } catch ( e ) {
	return false;
    }
}
if ( webglAvailable() ) {
    renderer = new THREE.WebGLRenderer();
} else {
    renderer = new THREE.CanvasRenderer();
}
注:WebGLRenderer 和 CanvasRenderer 都是使用HTML5中的 <canvas>直接內嵌在網頁中。Canvas渲染器中的“Canvas”表明其使用Canvas 2D 而不是 WebGL。

Okay,Threejs 必備的3個元件總結完畢。