旋转相机后,Three.js天空箱似乎坏了

时间:2014-11-08 02:49:24

标签: javascript three.js

js和我正在尝试基于this demo创建一个简单的天空盒。到目前为止一切似乎都不错,除了旋转相机的一件事(我正在使用orbitControls.js)并且z值不是最小可能然后纹理很奇怪而且看起来很破碎。

来源:

var camera, scene, renderer, controls, skybox;

var toRadians = function(deg) {
    return deg * Math.PI / 180
}

var toDegrees = function(radians) {
    return radians * (180 / Math.PI);
}

var init = function() {

    // scene
    scene = new THREE.Scene();
    scene.fog = new THREE.FogExp2( 0xffffff, 0.00010);

    // camera
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 20000 );
    camera.position.z = 5000;
    scene.add( camera );


    // skydome
    var urlPrefix = "http://three.dev/skybox/textures/";
    var urls = [urlPrefix + "px.png", urlPrefix + "nx.png",
                urlPrefix + "py.png", urlPrefix + "ny.png",
                urlPrefix + "pz.png", urlPrefix + "nz.png"];
    var textureCube = THREE.ImageUtils.loadTextureCube( urls );

    var shader = THREE.ShaderLib[ "cube" ];
    shader.uniforms[ "tCube" ].value = textureCube;

    var material = new THREE.ShaderMaterial( {

        fragmentShader: shader.fragmentShader,
        vertexShader: shader.vertexShader,
        uniforms: shader.uniforms,
        depthWrite: false,
        side: THREE.BackSide

    } ),

    skybox = new THREE.Mesh( new THREE.BoxGeometry( 10000, 10000, 10000 ), material );
    scene.add( skybox );

    //var texture = THREE.ImageUtils.loadTexture( 'http://three.dev/skybox/textures/wood.jpg')
    //var paintMaterial = new THREE.MeshBasicMaterial({map: textureCube})

    // var lightAmb = new THREE.AmbientLight(0x333333); 
    // lightAmb.position.set( 0,0,0 );
    // scene.add(lightAmb);


    // var directionalLightTop = new THREE.DirectionalLight( 0xffffff, 1 );
    // directionalLightTop.position.set( 0, 0, 0 ).normalize();
    // scene.add( directionalLightTop );    

    // var color = new THREE.Color("rgb(255,0,0)");
    // var pointLightRed = new THREE.PointLight(color, 1, 8000);
    //  pointLightRed.position.set( 0, 0, 0);
    //  camera.add( pointLightRed );        


    // renderer
    renderer = new THREE.WebGLRenderer( {alpha: true, antialias: true} );
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setClearColor( 0xffffff, 1 );
    renderer.autoClear = false;

    controls = new THREE.OrbitControls( camera, renderer.domElement );
    controls.rotateSpeed = 0.5;
    controls.minDistance = 500;
    controls.maxDistance = 6000;

    document.body.appendChild( renderer.domElement );

    window.addEventListener( 'resize', onWindowResize, false );

    // start rendering
    render();

}

function onWindowResize() {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize( window.innerWidth, window.innerHeight );

  render();

}

var update = function() {

}

var render = function() {
    update();
    controls.update();

    requestAnimationFrame( render );
    renderer.render(scene, camera);
}

window.onload = function(){
    init();
}

1 个答案:

答案 0 :(得分:0)

您正在'主要'添加天空盒。现场。完成天幕的更好方法是创建一个新场景。这将是'背景'到你的主要'现场。还有关于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.