Three.js:平铺纹理,缓冲和浏览器兼容性

时间:2012-05-20 15:03:43

标签: cross-browser textures buffering three.js tiling

我正在使用html 5 canvas进行项目。为此,我使用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个像素,但我宁愿不这样做。

  5. 我尝试将代码上传到jsfiddle(从tinypic导入texture)但这样做并不顺利。无论是我输入的纹理错误还是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 个答案:

答案 0 :(得分:3)

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?

答案 1 :(得分:0)

尝试:

function rerender(){
    requestAnimFrame(rerender);

    renderer.render(scene, camera); 
}