2014-11-08 95 views
1

js我試圖根據this演示創建一個簡單的天空盒。除了當我旋轉我的相機(我使用orbitControls.js)和z值不是最小可能,然後紋理行爲奇怪,似乎破碎一切似乎一切都好。旋轉相機後,Three.js天空盒似乎損壞

來源:

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

回答

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.