Three.js: текстуры листов, буферизация и совместимость с браузерами

Я работаю над проектом в HTML 5 холст. Для этого я использую библиотеку 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 (импортировать текстуру из 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?

Пытаться:

function rerender(){
    requestAnimFrame(rerender);

    renderer.render(scene, camera); 
}
Другие вопросы по тегам