Three.js Unculled SkyBox

时间:2014-12-22 21:55:44

标签: three.js culling 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);

1 个答案:

答案 0 :(得分:1)

您正在“主要”场景中添加天空盒。完成天幕的更好方法是创建一个新场景。这将是你“主要”场景的“背景”。还有关于skydomes v.s.的讨论。天空盒,简单地说,一个盒子保存多边形,圆顶看起来更好。在这个例子中,我将使用圆顶/球体。

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);

现在,在渲染功能期间,您只调整天幕相机的旋转,而不是位置。

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.