Пример Three.js неправильно отображается на Chromebook (но нормально на Windows и планшете)

Я только что начал читать книгу «Разработка игр с помощью Three.js» (https://www.packtpub.com/game-development/game-development-threejs)

Я построил пример (см. код ниже).

Он должен показывать городской пейзаж. Это прекрасно отображается при просмотре с помощью Chrome (версия 43.0.2357.124 m) на компьютере с Windows 7. Он также отлично отображается при использовании Chrome на планшете Android (версия 43.0.2357.93).

Однако, когда я пробую это с Chromebook (версия 43.0.2357.81 (стабильный канал)), я просто получаю черную страницу (и она черная, как в «нуар», а не пустая).

Может ли кто-нибудь предложить, как я могу заставить Chromebook отображать город?

Часть 1: HTML

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <script src="http://threejs.org/build/three.min.js"></script>
    <script src="city.js"></script>
</body>
</html>

Часть 2: JavaScript-код «city.js»

// GLOBALS ======================================================
var camera, scene, renderer;
// SETUP ========================================================
function animate() {
    draw();
    update();
    requestAnimationFrame( animate );
}

function setup() {
    document.body.style.backgroundColor = '#d7f0f7';
    setupThreeJS();
    setupWorld();
    requestAnimationFrame( animate );
}

function setupThreeJS() {
    scene = new THREE.Scene();
    scene.fog = new THREE.FogExp2(0x9db3b5, 0.002);

    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.y = 400;
    camera.position.z = 400;
    camera.rotation.x = -45 * Math.PI / 180;

    renderer = new THREE.WebGLRenderer({antialias: true});
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.shadowMapEnabled = true;
    document.body.appendChild( renderer.domElement );
}

function setupWorld() {
    var geo = new THREE.PlaneGeometry(2000, 2000, 40, 40);
    var mat = new THREE.MeshPhongMaterial({color: 0x9db3b5, overdraw: true});
    var floor = new THREE.Mesh(geo, mat);
    floor.rotation.x = -0.5 * Math.PI;
    floor.receiveShadow = true;
    scene.add(floor);
    var geometry = new THREE.CubeGeometry( 1, 1, 1 );
    geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, 0.5, 0 ) );
    var material = new THREE.MeshPhongMaterial({overdraw: true, color: 0xcccccc});

    var cityGeometry = new THREE.Geometry();
    for (var i = 0; i < 300; i++) {
        var building = new THREE.Mesh(geometry.clone());
        building.position.x = Math.floor( Math.random() * 200 - 100 ) * 4;
        building.position.z = Math.floor( Math.random() * 200 - 100 ) * 4;
        building.scale.x  = /**/Math.random()/*Math.pow(Math.random(), 2)/**/ * 50 + 10;
        building.scale.y  = /**/Math.random()/*Math.pow(Math.random(), 3)/**/ * building.scale.x * 8 + 8;
        building.scale.z  = building.scale.x;
        THREE.GeometryUtils.merge(cityGeometry, building);
}
    var city = new THREE.Mesh(cityGeometry, material);
    city.castShadow = true;
    city.receiveShadow = true;
    scene.add(city);

    var light = new THREE.DirectionalLight(0xf9f1c2, 1);
    light.position.set(500, 1500, 1000);
    light.castShadow = true;
    light.shadowMapWidth = 2048;
    light.shadowMapHeight = 2048;
    var d = 1000;
    light.shadowCameraLeft = d;
    light.shadowCameraRight = -d;
    light.shadowCameraTop = d;
    light.shadowCameraBottom = -d;
    light.shadowCameraFar = 2500;
    scene.add(light);
}

// DRAW =========================================================

function draw() {
    renderer.render( scene, camera );
}
// RUN ==========================================================

setup();

person Crush_157    schedule 22.06.2015    source источник
comment
консоль ничего не говорит?   -  person Atrahasis    schedule 22.06.2015
comment
Хороший вопрос, сэр! 1. Функция update(), вызываемая в animate, больше не существует (дох!). 2. Моя книга устарела - нужно было использовать BoxGeometry и PlaneBuffer, и... THREE.GeometryUtils.merge(cityGeometry, building); ...должно было быть заменено на... building.updateMatrix(); cityGeometry.merge(building.geometry, building.matrix) ОК, исправив это, консоль на ПК не показывает ошибок (только сообщение журнала THREE.WebGLRenderer 71).   -  person Crush_157    schedule 24.06.2015
comment
Однако на ChromeBook (для ясности, я просматриваю один и тот же URL-адрес в каждом случае, а html и js находятся на разных машинах) я получаю следующие ошибки: Three.WebGLShader: Shader не удалось скомпилировать Three.WebGLProgram: ошибка шейдера: 0 gl.VALIDATE_STATUS false gl.getPROgramInfoLog недопустимые шейдеры   -  person Crush_157    schedule 24.06.2015
comment
На самом деле, threeJS появился несколько лет назад, но скоро выйдет 72-я версия, поэтому книги по нему быстро устаревают. Что касается остальных ошибок, я их не знаю, но я настроен скептически, поскольку вы все еще пишете, что это работает на хроме, но не на хромбуке: вы уверены, что можете получить с ним материал webgl? Что касается вашего кода, последнее, что вы должны сделать, это заменить requestAnimationFrame(animate) в вашей функции setup только на animate(): requestAnimationFrame предназначен для вызова внутри функции, переданной в аргументе, и это может вызвать одну из этих ошибок.   -  person Atrahasis    schedule 25.06.2015
comment
@Astrak - Еще раз спасибо. Странно, что у меня разное поведение на ПК и ChromeBook. Все примеры, которые я пробовал с веб-сайта Three.js, работают нормально на CB, поэтому я думаю, что буду использовать книгу для идей, но основывать свой код Three.js на примерах/документах с веб-сайта.   -  person Crush_157    schedule 26.06.2015
comment
Да это странно. Одна вещь, которую вы можете сделать, это прокомментировать все детали в вашем коде и попытаться запустить его на своем Chromebook. Если это работает, раскомментируйте часть за частью, пока не появится ошибка, чтобы вы поняли, откуда возникла проблема.   -  person Atrahasis    schedule 26.06.2015


Ответы (1)


@ Crush_157 Я столкнулся с похожей проблемой. Я использую шейдеры из ShaderLib. В любом случае, в моем случае у меня на сцене 2 DirectionalLight. Все отлично работает в большинстве браузеров/устройств, кроме chromeOS. И угадайте, что если я удалю один из DirectionalLight, мои объекты начнут появляться :). Не уверен, почему

person Ravi Gidwani    schedule 16.07.2015