cross-browser - Three.js:平铺纹理、缓冲和浏览器兼容性

标签 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. 纹理当前在每个表面上拉伸(stretch)。我更喜欢平铺,但似乎无法让它发挥作用。上面的代码是我根据我在网站上找到的内容得出的最佳猜测(抱歉,无法以我当前的声誉分享更多链接)。它被注释掉是因为它根本停止了脚本的运行。

  2. 我曾经遇到过一些延迟问题。经过快速搜索后,我发现一个网站(抱歉,无法与我当前的声誉分享更多链接)告诉我必须在主循环中设置超时,并且我应该使用第二个 Canvas 进行缓冲。添加超时就像一个魅力,但我仍然对缓冲 Canvas 感到好奇。我不确定如何解决这个问题,因为我正在处理渲染器和 Canvas 。我什至不知道是否应该继续使用缓冲区,因为它现在看起来工作得很好,尽管将来当我尝试一次渲染更多网格时,情况可能会发生变化。

  3. 我的代码目前只能在 Firefox 中运行。 Chrome 和 Internet Explorer 都只显示空白屏幕。有什么想法我需要改变才能解决这个问题吗?

  4. 当我在 Firefox 中运行代码时,橱柜一开始是全黑的。当我移动它(完全)时,它会立即改变纹理。有任何想法吗?我可以想出一个肮脏的修复方法,将相机在设置中上下移动 1 像素,但我不愿意。

我尝试将代码上传到 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>

感谢您的浏览!希望您能回答我的任何问题。

最佳答案

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) 删除对 mousemove 事件内的 rerender 函数的调用

9) IE 和 WebGL?

关于cross-browser - Three.js:平铺纹理、缓冲和浏览器兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10674563/

相关文章:

javascript - 如何检查css规则是否存在

javascript - 三个 JS 从原始 javascript ArrayBuffer 加载纹理

opengl - 在两个应用程序之间共享 OpenGL 帧缓冲区/渲染缓冲区

python - python 中是否有用于写入文件的 COMMIT 模拟?

c - scanf 是否在读取输入数据后清空缓冲区(在 C 中)?

html - Firefox 窃取 mah 像素

html - 中间有单词的水平线的CSS技巧

flash - 在 Internet Explorer/Firefox/Chrome 中出于测试目的禁用闪存

c++ - OpenGL 乒乓球反馈纹理未完全清除自身。留下了足迹

php - 第0行的PHP缓冲错误<未知>