threejs深入紋理,立體場景cubeResolution(四)


 

在這個課程里主要完成講解兩個demo:

一個是電視牆:用視頻做紋理

一,用視頻做紋理

首先我們用video標簽把視頻源引入:

<video id="video" autoplay loop style="display:none">
    <source src="http://10.1.26.29:84/assets/video/sintel_trailer-480p.ogv" type="video/ogg">
    <source src="http://10.1.26.29:84/assets/video/sintel_trailer-480p.mp4" type="video/mp4">
    <source src="http://10.1.26.29:84/assets/video/sintel_trailer-480p.webm" type="video/webm">
</video>  

  設置視頻紋理

在這里引入一個概念mipmap:一個mipmap是一組紋理圖片,每個圖片的尺寸都是前一張圖片的一半。這些圖片實在加載紋理時創建的,可以生成較平滑的過濾效果。

注意:
1.由於我們的視頻不是正方形,所以要保證材質不會生成mipmap。
2.由於材質變化得很頻繁,所以我們需要設置簡單高效的過濾器。LinearFilter 線性過濾

var video = document.getElementById('video');   //獲取頁面dom元素

videoTexture = new THREE.Texture(video);

//minFilter屬性:指定紋理如何縮小。默認值:THREE.LinearMipMapLinearFilter
videoTexture.minFilter = THREE.LinearFilter;
//magFilter屬性:指定紋理如何放大。默認值:THREE.LinearFilter
videoTexture.magFilter = THREE.LinearFilter;

videoTexture.format = THREE.RGBFormat;
videoTexture.generateMipmaps = false;

THREE.Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy )

Image:這是一個圖片類型,基本上它有ImageUtils來加載,如下代碼
var image = THREE.ImageUtils.loadTexture(url); // url 是一個http://xxxx/aaa.jpg 的類似地址,javascript沒有從本地加載數據的能力,所以沒有辦法從您電腦的C盤加載數據。

Mapping:是一個THREE.UVMapping()類型,它表示的是紋理坐標。下一節,我們將說說紋理坐標。

wrapS:表示x軸的紋理的回環方式,就是當紋理的寬度小於需要貼圖的平面的寬度的時候,平面剩下的部分應該p以何種方式貼圖的問題。

wrapT:表示y軸的紋理回環方式。

magFilterminFilter表示過濾的方式,這是OpenGL的基本概念。當您不設置的時候,它會取默認值。

format:表示加載的圖片的格式,這個參數可以取值THREE.RGBAFormat,RGBFormat等。THREE.RGBAFormat表示每個像素點要使用四個分量表示,分別是紅、綠、藍、透明來表示。RGBFormat則不使用透明,也就是說紋理不會有透明的效果。

type:表示存儲紋理的內存的每一個字節的格式,是有符號,還是沒有符號,是整形,還是浮點型。不過這里默認是無符號型(THREE.UnsignedByteType)。暫時就解釋到這里,有需要時,我們在仔細分析,或者給作者留言詢問。

anisotropy:各向異性過濾。使用各向異性過濾能夠使紋理的效果更好,但是會消耗更多的內存、CPU、GPU時間。

 

 添加一個長方體作為電視牆,設置紋理時,我們采用兩種紋理,有四面是純色的,有兩面是視頻紋理,我們這里用數組materials存放六個面的紋理,然后通過THREE.MeshFaceMaterial()設置每個面的紋理,你也可以自己設置,六個面都是視頻紋理

var cubeGeometry = new THREE.BoxGeometry(1, 10, 20);
var cubeMaterial = new THREE.MeshBasicMaterial({map: videoTexture});

var materials = [];
materials.push(cubeMaterial);
materials.push(cubeMaterial);
for (var i = 1; i < 5; i++) {
    materials.push(new THREE.MeshLambertMaterial({color: 0xff0000}));
}
//MeshFaceMaterial這是一種容器,可以在該容器中為物體的各個表面上設置不同的顏色
var cube = new THREE.Mesh(cubeGeometry, new THREE.MeshFaceMaterial(materials));
cube.position.set(-10.05,0,0);
cube.rotation.x = -0.3;
cube.rotation.y = 23.5;
cube.name = 'cube';
scene.add(cube);

MeshFaceMaterial方法根據參數materials創建mesh(網格)的復合材質類型,參數material是一個Material類型的數組對象,網格中的三角面屬性materialindex定義了該三角面使用的參數material中材質對象的索引號. 

添加控制器:

  我們之前已經使用過一個可以縮放的控制器,這里我們使用一個可以旋轉的控制器

  用script標簽引入一個庫文件 OrbitControls.js

  創建一個實例對象,就可以使用了。

orbit = new THREE.OrbitControls(camera);

   完整代碼下載:github(threejs-five)  如果你覺得我寫的對你有幫助的話,請給個star,謝謝

 

二,玻璃質感反射一個空間環境

首先我們從原理上進行分析,這種可以表現立體空間環境的實現,實際上是構造了一個大的正方體,(skybox)正方體的六個面的背景是符合實際場景的六張圖片,在這個demo里,就是汽車內部的前后左右上下,然后我們在正方體的內部進行觀看,從而達到立體環繞的效果;

 使用ShaderMaterial(共享材質)實現漫光反射,根據參數parameters創建為自定義着色器創建材質類型,這樣的材質對象讓用戶擴充材質類型,有了無限的可能. 

參數的格式:
parameters = { 
   defines: { "label" : "value" }, 
   uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } }, 
  
   fragmentShader: <string>, 
   vertexShader: <string>, 
  
   shading: THREE.SmoothShading, 
   blending: THREE.NormalBlending, 
   depthTest: <bool>, 
   depthWrite: <bool>, 
  
   wireframe: <boolean>, 
   wireframeLinewidth: <float>, 
  
   lights: <bool>, 
  
   vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, 
  
   skinning: <bool>, 
   morphTargets: <bool>, 
   morphNormals: <bool>, 
  
   fog: <bool> 
  } 

 接下來我們從代碼進行分析:

首先我們先引入正方體六個面的圖片,依然是異步引入

var urls = [
            'http://10.1.26.29:84/assets/cubemap/car/right.png',
            'http://10.1.26.29:84/assets/cubemap/car/left.png',
            'http://10.1.26.29:84/assets/cubemap/car/top.png',
            'http://10.1.26.29:84/assets/cubemap/car/bottom.png',
            'http://10.1.26.29:84/assets/cubemap/car/front.png',
            'http://10.1.26.29:84/assets/cubemap/car/back.png'
        ];

 用THREE.ImageUtils.loadTextureCube()方法載入紋理

   定義一個着色器,基於THREE.ShaderLib來創建自定義的ShaderMaterial材質

var cubemap = THREE.ImageUtils.loadTextureCube(urls);
     cubemap.format = THREE.RGBFormat;
     //一個特別的着色器(Three.ShaderLib[“cube”]),結合THREE.ShaderMaterial類,我們可以基於CubeMap對象創建一個環境
     var shader = THREE.ShaderLib["cube"];
     shader.uniforms["tCube"].value = cubemap;
  //ShaderMaterial創建自己的着色器,要使用ShaderMaterial,必須傳入兩個着色器:fragmentShader,vertexShader var material = new THREE.ShaderMaterial({ fragmentShader: shader.fragmentShader, //定義每個傳入的像素的顏色 vertexShader: shader.vertexShader, //允許你修改每一個傳入的頂點的位置 uniforms: shader.uniforms, //該屬性可以向你的着色器發送消息,將同樣的消息發送到每個頂點和片段 depthWrite: false, side: THREE.DoubleSide         //實現一個立體雙面的效果 });  

接下來,我們就可以創建天空盒子

var skybox = new THREE.Mesh(new THREE.BoxGeometry(10000, 10000, 10000), material);
scene.add(skybox);

 

CubeCamera方法根據 near, far ,cubeResolution 生成立方體相機.CubeCamera對象的功能函數采用 定義構造的函數原型對象來實現. CubeCamera經常用來創建天空盒子.由六張圖片拼接成一個場景. 

near 指明相對於深度剪切面的近的距離,必須為正數,可選參數,如果未指定,初始化為0.1

far 指明相對於深度剪切面的遠的距離,必須為正數,可選參數,如果未指定,初始化為2000

cubeResolution 設置立方體的寬度

Matrix4 返回PerspectiveCamera,透視投影相機

cubeCamera = new THREE.CubeCamera(0.1, 20000, 256);
cubeCamera.renderTarget.minFilter = THREE.LinearMipMapLinearFilter;
scene.add(cubeCamera);

  接下來,我們可以創建鏡面反射的立體圖形

 先以球體為例,

我們用立體相機的渲染目標,cubeCamera.renderTarget,也就是整個環境

var sphereGeometry = new THREE.SphereGeometry(4, 15, 15);
////envMap 設置環境貼圖,默認是null var dynamicEnvMaterial = new THREE.MeshBasicMaterial({envMap: cubeCamera.renderTarget, side: THREE.DoubleSide}); sphere = new THREE.Mesh(sphereGeometry, dynamicEnvMaterial); sphere.name = 'sphere'; scene.add(sphere);

  再添加一個旋轉立方體,可以顯示變化的環境

 用 cubemap作為紋理貼圖,就是上面加載的六張圖片

var cubeGeometry = new THREE.BoxGeometry(5, 5, 5);
var envMaterial = new THREE.MeshBasicMaterial({envMap: cubemap, side: THREE.DoubleSide});
var cube = new THREE.Mesh(cubeGeometry, envMaterial);
cube.name = 'cube';
scene.add(cube);
cube.position.set(-10, 0, 0);

 最后,同樣使用上面提到的控制器:OrbitControls

orbit = new THREE.OrbitControls(camera);

  

完整代碼下載: github(threejs-six)  如果你覺得我寫的對你有幫助的話,請給我個star,

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM