2016-02-29 1 views
1

Сегодня я экспериментировал с созданием своего первого в истории skybox в three.js. Я прочитал много учебников, и код, который я закончил, основан на этом: http://learningthreejs.com/blog/2011/08/15/lets-do-a-sky/ Я сделал несколько изменений, чтобы сначала загружать изображения и сделать их совместимыми с версией of three.js, который я использую.three.js skybox: очевидные углы и множество искажений

Я преодолел множество мелких проблем, чтобы добраться до той точки, в которой я нахожусь, но не могу найти ответа на мою текущую проблему, несмотря на то, что вы довольно много искали. Моя проблема заключается в том, что, несмотря на использование специально созданных текстур skybox, загруженных из Интернета, совершенно очевидно, что мой skybox - это куб с углами и краями. Текстуры выглядят сильно искаженными и не совсем убедительными.

Вот скриншот того, как мой скайбокса выглядит: Here is a screenshot of my skybox

А вот ссылка на сайт, с которого я загружал изображения: http://www.humus.name/index.php?page=Cubemap&item=Yokohama3 Как вы можете видеть, в их предварительном просмотре он выглядит намного лучше ,

Я пробовал это с помощью нескольких различных загруженных текстур, и каждый раз, когда очень очевидно, что вы смотрите на кубик внутри.

Вот мой код (я в том числе все мой код, а не только раздел, который создает скайбокс):

var scene; 
    var camera; 
    var renderer; 

    function createRenderer() { 
     renderer = new THREE.WebGLRenderer(); 
     renderer.setClearColor(0x000000, 1.0) 
     renderer.setSize(window.innerWidth, window.innerHeight) 
     renderer.shadowMapEnabled = true; 
     //renderer.shadowCameraNear = 0.5; 
     //renderer.shadowCameraFar = 500; 
    } 

    function createCamera() { 
     camera = new THREE.PerspectiveCamera(
      45, 
      window.innerWidth/window.innerHeight, 
      0.1, 1000 
     ); 
     camera.position.x = 50; 
     camera.position.y = 30; 
     camera.position.z = 40; 
     camera.lookAt(scene.position); 
    } 

    function createPlane() { 
     var material = new THREE.MeshLambertMaterial({ 
      color: 0xcccccc, 
     }) 
     var geometry = new THREE.PlaneGeometry(40, 40) 

     var plane = new THREE.Mesh(geometry, material) 
     plane.receiveShadow = true; 
     plane.rotation.x = -Math.PI/2 
     plane.position.y = -6; 
     scene.add(plane) 
    } 

    function createLight() { 
     var spotLight = new THREE.DirectionalLight(0xffffff); 
     spotLight.position.set(0, 50, 20); 
     spotLight.shadowCameraVisible = true; 
     spotLight.shadowDarkness = 0.5 
     spotLight.shadowCameraNear = 0; 
     spotLight.shadowCameraFar = 100; 
     spotLight.shadowCameraLeft = -50; 
     spotLight.shadowCameraRight = 50; 
     spotLight.shadowCameraTop = 50; 
     spotLight.shadowCameraBottom = -50; 
     spotLight.castShadow = true; 
     scene.add(spotLight); 
    } 

    function createSkyboxAndSphere() { 

     var urlPrefix = "Yokohama3/"; 
     var urls = [ urlPrefix + "posx.jpg", urlPrefix + "negx.jpg", 
      urlPrefix + "posy.jpg", urlPrefix + "negy.jpg", 
      urlPrefix + "posz.jpg", urlPrefix + "negz.jpg" ]; 
     var textureCube = THREE.ImageUtils.loadTextureCube(urls , undefined, function() {; 

      var shader = THREE.ShaderLib["cube"]; 
      var uniforms = THREE.UniformsUtils.clone(shader.uniforms); 
      shader.uniforms['tCube'].value = textureCube; // textureCube has been init before 
      var material = new THREE.ShaderMaterial({ 
       fragmentShader : shader.fragmentShader, 
       vertexShader : shader.vertexShader, 
       uniforms : shader.uniforms, 
       depthWrite : false, 
       side: THREE.BackSide, 
      }); 


      var geometry = new THREE.BoxGeometry(100, 100, 100) 
      var skybox = new THREE.Mesh(geometry, material) 
      scene.add(skybox) 


      var material = new THREE.MeshPhongMaterial({ 
       color: "red", 
       envMap: textureCube, 
       reflectivity: 0.3, 
      }) 
      var geometry = new THREE.SphereGeometry(6, 30, 15) 

      var sphere = new THREE.Mesh(geometry, material) 
      sphere.castShadow = true; 
      sphere.receiveShadow = true; 
      scene.add(sphere) 

      }); 
    } 

    function init() { 

     scene = new THREE.Scene(); 
     createRenderer(); 
     createCamera(); 
     createLight(); 
     createPlane(); 
     createSkyboxAndSphere(); 

     document.getElementById("container").appendChild(renderer.domElement) 

     render() 
    } 

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

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

Я подозреваю, что я принципиально недоразумение что-то о том, как кубическая текстура и скайбоксы работать - я очень новый для этого, в частности, и javascript в целом, и я осознаю огромные пробелы в моих знаниях.

Приносим извинения, если ответ на это очевиден и/или вопрос был задан раньше, и упреждающее спасибо за вашу помощь!

ответ

3

Ваша камера должна находиться в центре небоскреба - или, по крайней мере, вблизи центра.

Так что либо переместите камеру очень близко к центру коробки, либо обновите положение коробки в каждом кадре в соответствии с положением камеры.

Или сделайте skybox намного больше относительно камеры, смещенной от источника.

Или поместите skybox в отдельную сцену и сделайте две камеры и два прохода визуализации, как в this example.

three.js r.74

Смежные вопросы