简体   繁体   English

旋转相机后,Three.js Skybox似乎坏了

[英]Three.js skybox seems broken after rotating camera

js and I'm trying to create a simple skybox based on this demo. js,我正在尝试基于演示创建一个简单的skybox。 Everything seems ok so far except 1 thing when I rotate my camera (I'm using orbitControls.js) and the z value is not the minimum possible then textures act weird and seem broken. 到目前为止,一切似乎都不错,但当我旋转相机(我正在使用orbitControls.js)时只有一件事情,并且z值不是最小的可能,那么纹理表现得很奇怪并且看上去很破损。

Source: 资源:

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

You're adding a skybox in the 'main' scene. 您正在“主要”场景中添加一个天空盒。 A better way to accomplish a skydome would be to create a new scene. 完成天穹的更好方法是创建一个新场景。 this will be the 'background' to your 'main' scene. 这将是您“主要”场景的“背景”。 There's also a discussion about skydomes vs skyboxes, simply put, a box saves polys, a dome looks better. 简而言之,还有关于天穹与天窗的讨论,一个盒子可以保存多边形,一个圆顶看起来更好。 in this example i'll be using a dome/sphere. 在此示例中,我将使用圆顶/球形。

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

now, during the render function you adjust only the rotation of the skydome camera, not the position. 现在,在渲染功能期间,您仅调整天穹摄像机的旋转,而不调整位置。

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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM