2014-11-08 3 views
1

js и я пытаюсь создать простой skybox на основе this demo. Кажется, пока все хорошо, кроме 1 вещи, когда я поворачиваю свою камеру (я использую orbitControls.js), и значение z не является минимальным возможным, тогда текстуры действуют странно и кажутся разбитыми.Three.js skybox кажется сломанным после поворота камеры

Источник:

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

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

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. 
Смежные вопросы