threejs第五篇【一條龍測試之四 threejs 給obj模型貼圖】
由於OBJ沒有紋理資訊, 需要threejs來載入外部貼圖,來指定給模型!
//模型需要紋理Texture
var texture = new THREE.Texture();
var loader = new THREE.ImageLoader( manager );
loader.load( 'knotTex.png', function ( image ) {
texture.image = image;
texture.needsUpdate = true;
} );
//obj載入的類如圖:
//obj載入,建構函式的引數是LoadingManager
var loader = new THREE.OBJLoader(manager);
//載入方法有4個引數,分別是obj檔案路徑,載入完畢回撥,載入進度回撥,錯誤回撥。
//我們先把幾個回撥寫好
//載入完畢回撥如下,載入完畢,我們做的就是把模型載入到場景中
var onLoad = function(object){
//載入模型如何指定Texture呢?
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material.map = texture;
}
} );
scene.add( object);
}
我們給個載入進度吧,
使用CSS做2個塊樣式,頁面頂部div progress,顯示載入進度百分比。
<style type="text/css">
#progress{
margin:0;
line-height:40px;
font-weight:bold;
color:#fff;
text-align:center;
background-color:#ff0000;
}
</style>
主體視窗div canvas3d 顯示3D場景
<style type="text/css">
#canvas3d{
margin:0;
/*border:1px solid red;*/
width:100%;
height:600px;
}
</style>
另外,網頁視窗變化,3D場景比例也要適配:
//視窗變化時,3D視窗也會動態適配
window.onresize = function(){
var w = document.getElementById("canvas3d").clientWidth;
var h = document.getElementById("canvas3d").clientHeight;
camera.aspect = w/h;
camera.updateProjectionMatrix();
renderer.setSize(w,h);
}
完整程式碼:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<script src="../build/three.js" type="text/javascript" ></script>
<script src="../examples/js/Detector.js" type="text/javascript" ></script>
<script src="../examples/js/loaders/OBJLoader.js" type="text/javascript" ></script>
<style type="text/css">
#canvas3d{
margin:0;
/*border:1px solid red;*/
width:100%;
height:600px;
}
</style>
<style type="text/css">
#progress{
margin:0;
line-height:40px;
font-weight:bold;
color:#fff;
text-align:center;
background-color:#ff0000;
}
</style>
</head>
<body>
<div id="canvas3d">
<div id = "progress">
<p></p>
</div>
</div>
<script type="text/javascript">
if(Detector.webgl){
//alert('瀏覽器支援');
//瀏覽器支援,我們就做初始化工作。不然js處理半天,瀏覽器不支援也白搭
init();
animate();
}else{
alert('瀏覽器不支援');
}
var scene,camera,renderer;
//初始化
function init(){
var w = document.getElementById("canvas3d").clientWidth;
var h = document.getElementById("canvas3d").clientHeight;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45,w/h,0.1,1000);
camera.position.z= 250;
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0, 1 );
scene.add( directionalLight );
renderer = new THREE.WebGLRenderer();
//下面setSize()可以不寫,畫面也會顯示預設指定300*150的大小,很小。所以肯定要手動設定一下大小
renderer.setSize(w,h);
renderer.setClearColor(0xf0f0f0);
//別忘記了這個要寫滴...不然就真看不見畫面。
document.getElementById('canvas3d').appendChild(renderer.domElement);
//開始模型匯入的一些工作
//我們看看官方提供的OBJLoad.js指令碼的建構函式
//建構函式的引數是一個manager,這是什麼呀?看到圖中他是整合自THREE.DefaultLoadingManager,
//
//然後我們去three.js裡面DefaultLoadingManager看看是什麼?看到了,是LoadingManager物件;
//
//裡面搜了一遍,沒有找到LoadingManager的類,我們再看看three.module.js
//在這裡發現了function LoadingManager( onLoad, onProgress, onError ) {...}
//這個管理器有
//接下來我們宣告一個LoadingManager
var manager = new THREE.LoadingManager();
//模型需要紋理Texture
var texture = new THREE.Texture();
var loader = new THREE.ImageLoader( manager );
loader.load( 'knotTex.png', function ( image ) {
texture.image = image;
texture.needsUpdate = true;
} );
//obj載入的類如圖:
//obj載入,建構函式的引數是LoadingManager
var loader = new THREE.OBJLoader(manager);
//載入方法有4個引數,分別是obj檔案路徑,載入完畢回撥,載入進度回撥,錯誤回撥。
//我們先把幾個回撥寫好
//載入完畢回撥如下,載入完畢,我們做的就是把模型載入到場景中
var onLoad = function(object){
//載入模型如何指定Texture呢?
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material.map = texture;
}
} );
scene.add( object);
}
//載入過程,可以顯示進度值
var onProgress = function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( Math.round(percentComplete, 2) + '% downloaded' );
document.getElementById('progress').innerText= Math.round(percentComplete, 2) + '%下載' ;
}
};
//錯誤回撥,因為網頁除錯有報錯,這裡可以不做處理
var onError = function ( xhr ) {
};
//回撥寫好了,現在可以用載入的方法載入模型了。
loader.load('knot.obj',onLoad,onProgress,onError);
}
//視窗變化時,3D視窗也會動態適配
window.onresize = function(){
var w = document.getElementById("canvas3d").clientWidth;
var h = document.getElementById("canvas3d").clientHeight;
camera.aspect = w/h;
camera.updateProjectionMatrix();
renderer.setSize(w,h);
}
// 渲染
function render(){
renderer.render(scene,camera);
}
//迴圈渲染
function animate() {
requestAnimationFrame( animate );
render();
}
</script>
</body>
</html>