Three.js Unculled SkyBox

Я пытаюсь, чтобы на мой скайбокс не влиял параметр camera.far. Я хотел бы отобрать все другие объекты сцены с помощью этого, а не скайбокса.

Когда я устанавливаю skyBox.frustumCulled = false;, это не имеет значения. skyBox это, конечно же, сетка.

Это делается путем добавления еще одного прохода рендеринга? Если это так, мне понадобятся 2 разные камеры, одна с действительно высоким значением дальности, чтобы можно было просматривать скайбокс, верно? Как это можно сделать эффективно?

Для ясности вот фрагмент из моего кода объекта ландшафта, используемого для рисования скайбокса:

    shader = THREE.ShaderLib["cube"];
    shader.uniforms["tCube"].value = this.cubetexture;

    mat = new THREE.ShaderMaterial({
        uniforms: shader.uniforms,
        fragmentShader: shader.fragmentShader,
        vertexShader: shader.vertexShader,
        depthWrite: false,
        side: THREE.BackSide
    });

    geo = new THREE.BufferGeometry().fromGeometry(new THREE.BoxGeometry(1024, 1024, 1024));

    mesh = new THREE.Mesh(geo, mat);

    mesh.rotation.y += 90;

    mesh.scale.x = mesh.scale.y = mesh.scale.z = 50;

    mesh.frustumCulled = false;
    mesh.matrixAutoUpdate = false;
    mesh.rotationAutoUpdate = false;
    mesh.updateMatrix();

    this.skybox = mesh;

    scene.add(this.skybox);

person Hobbes    schedule 22.12.2014    source источник


Ответы (1)


Вы добавляете скайбокс в «основную» сцену. Лучшим способом создания купола неба было бы создание новой сцены. это будет «фоном» для вашей «основной» сцены. Также есть дискуссия о skydomes vs. скайбоксы, проще говоря, бокс экономит полисы, купол выглядит лучше. в этом примере я буду использовать купол/сферу.

var renderer = new THREE.WebGLRenderer( {alpha: true, antialias: true} );
var mainScene = new THREE.Scene();
var mainCamera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 20000 );

var skydome = {
    scene: new THREE.Scene(),
    camera: new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 20000 );
};

skydome.material = new THREE.MeshBasicMaterial({color: 0x0F0F0F}) //the material for the skydome, for sake of lazyness i took a MeshBasicMaterial.
skydome.mesh = new THREE.Mesh(new THREE.SphereGeometry(100, 20, 20), skydome.material);
skydome.scene.add(skydome.mesh);

теперь во время функции рендеринга вы настраиваете только вращение камеры skydome, а не положение.

var render = function(){
    requestAnimationFrame( render );
    skydome.camera.quaternion = mainCamera.quaternion;
    renderer.render(skydome.scene, skydome.camera); //first render the skydome
    renderer.render(mainScene, mainCamera);//then render the rest over the skydome
};
renderer.autoclear = false; //otherwise only the main scene will be rendered.
person Kevin Kuyl    schedule 24.12.2014
comment
Ух ты! Выглядит потрясающе, я не могу дождаться, чтобы попробовать это, когда я вернусь домой =] - person Hobbes; 24.12.2014
comment
Хм, отличный ответ, но по какой-то причине, реализовав ваш код, я обнаружил, что отображается только мой скайбокс :( - person Single Entity; 29.11.2015