使用Three.js + Blender構建在瀏覽器端顯示的3D模型(4)


 第四章 使用three.js加載以圖片為紋理的模型(上)

在前言中我們介紹過,我們一般不用three.js自帶的三維模型創建函數去拼湊我們想要的三維模型,而是使用類似Blender一樣的三維建模工具去定制三維模型,然后導出為three.js可以識別的jason格式,加載顯示。通過這種方式,我們可以構建較為原始的三維模型在瀏覽器端顯示,比如我們前面看到的馬克杯模型。如果單純依靠三維建模去逼近現實世界中的形體外觀是很難的,細節的修繕將給3D建模帶來巨大的工作量,同時也會導致模型的加載器計算量巨大,不僅對人還是機器都是巨大的挑戰。

好在我們可以另辟蹊徑,不去追求模型的精細度,而在模型的紋理上做文章,尤其當我們用真實物體的照片作為模型紋理的時候,3D模型的效果立刻就得到了極大的提高,比如這個箱體模型:

如果不考慮外表圖片紋理,它只是一個簡單的立方體模型。加上紋理之后,幾乎和我們在一些制作精良的3D游戲中見到的箱體所差無幾了。下面我們來分析它的代碼:

 1 //兼容各種瀏覽器的animation函數
 2 window.requestAnimFrame = (function(callback){
 3     return window.requestAnimationFrame ||
 4     window.webkitRequestAnimationFrame ||
 5     window.mozRequestAnimationFrame ||
 6     window.oRequestAnimationFrame ||
 7     window.msRequestAnimationFrame ||
 8     function(callback){
 9         window.setTimeout(callback, 1000 / 60);
10     };
11 })();
12 
13 // 實現旋轉的動畫函數
14 function animate(lastTime, angularSpeed, three){
15     // 動畫更新時以時間為基准
16     var date = new Date();
17     var time = date.getTime();
18     var timeDiff = time - lastTime;
19     // 角度以弧度為單位
20     var angleChange = angularSpeed * timeDiff * 2 * Math.PI / 1000;
21     three.cube.rotation.y += angleChange;
22     lastTime = time;
23 
24     // 重新渲染
25     three.renderer.render(three.scene, three.camera);
26 
27     // 角度參數在第一次調用時設定
28     requestAnimFrame(function(){
29         animate(lastTime, angularSpeed, three);
30     });
31 }
32 
33 window.onload = function(){
34     var angularSpeed = 0.2;
35     var lastTime = 0;
36 
37     // 渲染器
38     var renderer = new THREE.WebGLRenderer();
39     renderer.setSize(window.innerWidth, window.innerHeight);
40     document.body.appendChild(renderer.domElement);
41 
42     // 攝像機
43     var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
44     camera.position.z = 700;
45 
46     // 場景
47     var scene = new THREE.Scene();
48 
49     // 以圖片為紋理的材質,這是關鍵點
50     var material = new THREE.MeshLambertMaterial({
51         map: THREE.ImageUtils.loadTexture("crate.jpg")
52     });
53 
54     // 立方體模型
55     var cube = new THREE.Mesh(new THREE.CubeGeometry(300, 300, 300), material);
56     cube.overdraw = true;
57     scene.add(cube);
58 
59     // 加入環境光
60     var ambientLight = new THREE.AmbientLight(0x555555);
61     scene.add(ambientLight);
62 
63     // 加入方向光
64     var directionalLight = new THREE.DirectionalLight(0xffffff);
65     directionalLight.position.set(1, 1, 1).normalize();
66     scene.add(directionalLight);
67 
68     // 把以上創建3D模型的要素都包裝成一個對象
69     var three = {
70         renderer: renderer,
71         camera: camera,
72         scene: scene,
73         cube: cube
74     };
75 
76     // 使用onload回調函數啟動動畫,這樣能保證圖片被完全加載后才開始旋轉 
77     var textureImg = new Image();
78     textureImg.onload = function(){
79         animate(lastTime, angularSpeed, three, this);
80     };
81     textureImg.src = "crate.jpg";
82 };

與之對應的html代碼如下:

 1 <!DOCTYPE HTML>
 2 <html lang="en">
 3     <head>
 4         <style>
 5             body {
 6                 margin: 0px;
 7                 overflow: hidden;
 8             }
 9         </style>
10     </head>
11     <body>
12         <script src="http://mrdoob.github.com/three.js/build/three.min.js"></script>
13         <script src="LoadCrate.js"></script>
14     </body>
15 </html>

這個紋理圖片可以在這里下載:http://www.html5canvastutorials.com/demos/webgl/html5_canvas_webgl_texture/crate.jpg

這篇文章也參考自:http://www.html5canvastutorials.com/webgl/html5-canvas-webgl-texture-with-three-js/

作為一個系列中的一篇,相信這篇文章能夠讓初學者有效的向前推進一步,邁向three.js自由應用的大門!

在下一篇里,我們將分析如何給一個用Blender制作的,較為復雜的模型貼圖顯示在瀏覽器端。

 另外,實踐中我們發現,可以使用Chrome瀏覽器加載本地的WebGL模型中的素材,只需要在啟動Chrome的時候加上一下參數:--allow-file-access-from-files --disable-web-security

或許只加--allow-file-access-from-files就足夠了。方法如下圖所示:

這樣以來我們就可以隨意選擇自己偏愛的瀏覽器去調試three.js程序了。


免責聲明!

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



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