2012-05-20 30 views
2

我正在使用html 5 canvas的項目。爲此,我使用three.js庫以簡單櫥櫃的形式繪製一些簡單的立方體。我已經添加了環境照明,消除鋸齒和紋理。如果一切順利,它會呈現櫥櫃,您可以使用鼠標移動它。Three.js:拼貼紋理,緩衝和瀏覽器兼容性

當前的問題:

var textureMap = map: THREE.ImageUtils.loadTexture("wood1.jpg") 
textureMap.wrapS = THREE.RepeatWrapping; 
textureMap.wrapT = THREE.RepeatWrapping; 
textureMap.repeat.x = 100; 
textureMap.repeat.y = 100; 
material = new THREE.MeshLambertMaterial(textureMap); 
  1. 紋理目前伸過來的每個面。我更喜歡平鋪,但似乎無法得到它的工作。上面的代碼是我根據我在網站上找到的內容推出的最佳猜測(對不起,無法與我當前的聲望共享更多鏈接)。它被註釋掉了,因爲它會停止腳本運行。

  2. 我曾經有一些滯後問題。快速搜索後,我發現一個網站(抱歉,無法與我當前的聲望共享更多鏈接)告訴我,我必須在主循環中放置一個超時,並且我應該使用第二個畫布進行緩衝。增加超時功能就像一個魅力,但我仍然對緩衝畫布感到好奇。因爲我正在處理渲染器和畫布,所以我不確定如何處理這個問題。我甚至不知道是否應該繼續使用緩衝區,因爲它似乎現在工作得很好,儘管在將來我嘗試渲染更多網格時,這可能會發生變化。

  3. 我的代碼目前只能在Firefox中運行。 Chrome和Internet Explorer都顯示空白屏幕。任何想法,我需要改變以解決這個問題?

  4. 當我在firefox中運行代碼時,櫥櫃首先是完全黑色的。當我移動它(完全)時,它立即變爲紋理。有任何想法嗎?我可以想出一個骯髒的修復方法,可以使相機在設置中上下移動1個像素,但我寧願不要。

我試着上傳代碼jsfiddle(進口texture從tinypic),但是,這並不那麼好走。要麼導入紋理錯誤或jsfiddle只是不喜歡它,當我使用外部圖片。但是,如果您下載紋理並將其放在與代碼相同的文件夾中,應該可以在Firefox中打開它(僅適用於firefox(請參閱問題4))。所以,如果你想看看發生了什麼:將代碼複製到一個.html文件並下載紋理。

<!DOCTYPE HTML> 
<html> 
<head> 
<title>Canvas demo</title> 
<script type="text/javascript" src="http://www.html5canvastutorials.com/libraries/Three.js"></script> 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 
</head> 
<body> 
<script type="text/javascript"> 

//three.js vars 
var camera; 
var scene; 
var renderer; 
var material; 
var directionalLight; 

//input vars 
var lastX = 0; 
var lastY = 450; 
var clickX; 
var clickY; 
var mousedown; 


function rerender(){ 
    //draw 
    renderer.render(scene, camera); 
    //redraw after 25 ms (the 25 ms delay reduces lag) 
    setTimeOut(requestAnimFrame(function(){rerender()}), 25);  
} 

$(document).ready(function() { 
    //initialize renderer 
    renderer = new THREE.WebGLRenderer({antialias : true}); 
    renderer.setSize(window.innerWidth, window.innerHeight); 
    renderer.domElement.id = "visiblecanvas"; 
    document.body.appendChild(renderer.domElement); 

    //camera 
    camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 1000); 
    camera.position.y = -450; 
    camera.position.z = 400; 
    camera.rotation.x = 45.2; 

    //scene 
    scene = new THREE.Scene(); 

    //material 

    //non-working tiled texture 
    /* 
    var textureMap = map: THREE.ImageUtils.loadTexture("wood1.jpg") 
    textureMap.wrapS = THREE.RepeatWrapping; 
    textureMap.wrapT = THREE.RepeatWrapping; 
    textureMap.repeat.x = 100; 
    textureMap.repeat.y = 100; 
    */ 

    //workingg stretched texture 
    material = new THREE.MeshLambertMaterial({map: THREE.ImageUtils.loadTexture("wood1.jpg")}); 

    //the cupboard 

    //cube 
    var cube1 = new THREE.Mesh(new THREE.CubeGeometry(300,50,10), material); 
    cube1.overdraw = true; 
    scene.add(cube1); 

    //cube 
    var cube2 = new THREE.Mesh(new THREE.CubeGeometry(300,10,300), material); 
    cube2.overdraw = true; 
    cube2.position.z += 150; 
    cube2.position.y += 20; 
    scene.add(cube2); 

    //cube 
    var cube3 = new THREE.Mesh(new THREE.CubeGeometry(10,50,300), material); 
    cube3.overdraw = true; 
    cube3.position.z += 150; 
    cube3.position.x += 145; 
    scene.add(cube3); 

    //cube 
    var cube4 = new THREE.Mesh(new THREE.CubeGeometry(10,50,300), material); 
    cube4.overdraw = true; 
    cube4.position.z += 150;  
    cube4.position.x -= 145; 
    scene.add(cube4); 

    //cube 
    var cube5 = new THREE.Mesh(new THREE.CubeGeometry(300,50,10), material); 
    cube5.overdraw = true; 
    cube5.position.z += 300; 
    scene.add(cube5); 

    // add subtle ambient lighting 
    var ambientLight = new THREE.AmbientLight(0x555555); 
    scene.add(ambientLight); 

    // add directional light source 
    directionalLight = new THREE.DirectionalLight(0xffffff); 
    directionalLight.position.set(1, 1, 1).normalize(); 
    scene.add(directionalLight); 

    //mousedown event 
    $('#visiblecanvas').mousedown(function(e){ 
     clickX = e.pageX - this.offsetLeft + lastX;  
     clickY = e.pageY - this.offsetLeft + lastY; 
     mousedown = true; 
    }); 

    //mousemove event, act if mousedown 
    $('#visiblecanvas').mousemove(function(e){ 
     if(mousedown) { 
      var xDiff = e.pageX - this.offsetLeft - clickX; 
      var yDiff = e.pageY - this.offsetLeft - clickY; 

      lastX = -xDiff; 
      lastY = -yDiff; 

      camera.position.x = lastX; 
      camera.position.y = -lastY; 

      rerender(); 
     } 
     delay(5); 
    }); 

    //mouseup event 
    $('#visiblecanvas').mouseup(function(e){ 
     mousedown = false; 
    }); 

    //mouseleave event (mouse leaves canvas, stop moving cupboard) 
    $('#visiblecanvas').mouseleave(function(e){ 
     mousedown = false; 
    });   
    rerender(); 
}); 

//request new frame 
window.requestAnimFrame = (function (callback){ 
     return window.requestAnimationFrame || 
     window.webkitRequestAnimationFrame || 
     window.mozRequestAnimationFrame || 
     window.oRequestAnimationFrame || 
     window.msRequestAnimationFrame || 
     function(callback){ 
      window.setTimeout(callback, 1000/60); 
     }; 
})(); 

</script> 
</body> 
</html> 

感謝您的關注!希望你能回答我的任何問題。

回答

2

1)使用JavaScript控制檯調試代碼。

2)jsfiddle缺少jQuery。

3)這條線:

var textureMap = map: THREE.ImageUtils.loadTexture("wood1.jpg") 

必須是:

var textureMap = THREE.ImageUtils.loadTexture("wood1.jpg"); 

見額外map:和缺少分號。

4)repeat紋理參數太大。默認值是1,重複紋理一次。嘗試將該值更改爲2,3,...等等。

5)delay功能是未定義的,將其刪除

6)setTimeOut函數是未定義的(setTimeout,JavaScript是區分大小寫)

7)重寫rendererer函數將此:

function rerender(){ 
    requestAnimFrame(rerender); 

    renderer.render(scene, camera); 
} 

看一看這個:http://paulirish.com/2011/requestanimationframe-for-smart-animating/

8)移除rerender函數在mousemove事件中的調用

9)IE和WebGL?

0

嘗試:

function rerender(){ 
    requestAnimFrame(rerender); 

    renderer.render(scene, camera); 
} 
+2

護理一些評論添加到您的代碼?它如何解決OP問題?它是如何工作的? – Yaroslav