2016-04-13 5 views
0

Я работаю над созданием 3D-ландшафта с использованием функций Three.js и ImprovedNoise.js. Используя примеры на сайте Three.js, мне удалось создать то, что кажется рельефом, но оно 2D (не расширяющееся на ось z).Как мне получить «ландшафт» в Three.js для отображения 3D?

При попытке создать эту сцену я столкнулся с ошибками в примере кода. Некоторые вещи, которые я должен был изменить немного, чтобы получить его работу, например:

geometry.rotateX (-Math.PI)

я изменил

geometry.rotateX = -Math.PI

, но одна вещь, которая бросала ошибку, заключалась в том, что THREE.CanvasTexture не является функцией. CanvasTexture появляется в каждом примере three.js, который я могу найти, и я не могу найти документацию об изменении. Но CanvasTexture не находится в документации на сайте three.js, поэтому я предполагаю, что он устарел или что-то в этом роде.

В любом случае, теперь проблема заключается в том, что пока я еще не понял свою проблему, я попытался скопировать и вставить примерный код дословно, чтобы я мог работать назад, пытаясь лучше понять код, но даже пример кода из на сайте three.js выходит 2D, когда он запускается на моем компьютере.

Ниже приведен пример кода (немного изменен, чтобы избежать вышеупомянутых ошибок):

Если кто-нибудь может сказать мне, если это работает для них, или то, что я пропускаю это было бы весьма признателен.

Спасибо

Я использую эти библиотеки:

<script src="js/three.min.js"></script> 
    <script src="js/PointerLockControls.js"></script> 
    <script src="js/OrbitControls.js"></script> 
    <script src="js/ImprovedNoise.js"></script> 
    <script src="js/FirstPersonControls.js"></script> 
    <script src="js/Detector.js"></script> 

А вот ЯШ: (единственное, что я изменился, что я не включил в библиотеку статистику так соответствующий код прокомментирован ниже)

 var container, stats; 
     var camera, controls, scene, renderer; 
     var mesh, texture; 
     var worldWidth = 256, worldDepth = 256, 
     worldHalfWidth = worldWidth/2, worldHalfDepth = worldDepth/2; 
     var clock = new THREE.Clock(); 
     var helper; 
     var raycaster = new THREE.Raycaster(); 
     var mouse = new THREE.Vector2(); 
     init(); 
     animate(); 
     function init() { 
      container = document.getElementById('blocker'); 
      camera = new THREE.PerspectiveCamera(60, window.innerWidth/window.innerHeight, 1, 20000); 
      scene = new THREE.Scene(); 
      controls = new THREE.OrbitControls(camera); 
      controls.center.set(0.0, 100.0, 0.0); 
      controls.userPanSpeed = 100; 
      data = generateHeight(worldWidth, worldDepth); 
      controls.center.y = data[ worldHalfWidth + worldHalfDepth * worldWidth ] + 500; 
      camera.position.y = controls.center.y + 2000; 
      camera.position.x = 2000; 
      var geometry = new THREE.PlaneBufferGeometry(7500, 7500, worldWidth - 1, worldDepth - 1); 
      geometry.rotateX = - Math.PI/2 ; 
      var vertices = geometry.attributes.position.array; 
      for (var i = 0, j = 0, l = vertices.length; i < l; i ++, j += 3) { 
       vertices[ j + 1 ] = data[ i ] * 10; 
      } 
      geometry.computeFaceNormals(); 
      texture = new THREE.Texture(generateTexture(data, worldWidth, worldDepth)); 
      texture.wrapS = THREE.ClampToEdgeWrapping; 
      texture.wrapT = THREE.ClampToEdgeWrapping; 
      mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ map: texture })); 
      scene.add(mesh); 
      var geometry = new THREE.CylinderGeometry(0, 20, 100, 3); 
      geometry.translate = 0, 50, 0 ; 
      geometry.rotateX = Math.PI/2 ; 
      helper = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial()); 
      scene.add(helper); 
      renderer = new THREE.WebGLRenderer(); 
      renderer.setClearColor(0xbfd1e5); 
      renderer.setPixelRatio(window.devicePixelRatio); 
      renderer.setSize(window.innerWidth, window.innerHeight); 
      container.innerHTML = ""; 
      container.appendChild(renderer.domElement); 
      container.addEventListener('mousemove', onMouseMove, false); 
      //stats = new Stats(); 
      //stats.domElement.style.position = 'absolute'; 
      //stats.domElement.style.top = '0px'; 
      //container.appendChild(stats.domElement); 
      // 
      window.addEventListener('resize', onWindowResize, false); 
     } 
     function onWindowResize() { 
      camera.aspect = window.innerWidth/window.innerHeight; 
      camera.updateProjectionMatrix(); 
      renderer.setSize(window.innerWidth, window.innerHeight); 
     } 
     function generateHeight(width, height) { 
      var size = width * height, data = new Uint8Array(size), 
      perlin = new ImprovedNoise(), quality = 1, z = Math.random() * 100; 
      for (var j = 0; j < 4; j ++) { 
       for (var i = 0; i < size; i ++) { 
        var x = i % width, y = ~~ (i/width); 
        data[ i ] += Math.abs(perlin.noise(x/quality, y/quality, z) * quality * 1.75); 
       } 
       quality *= 5; 
      } 
      return data; 
     } 
     function generateTexture(data, width, height) { 
      var canvas, canvasScaled, context, image, imageData, 
      level, diff, vector3, sun, shade; 
      vector3 = new THREE.Vector3(0, 0, 0); 
      sun = new THREE.Vector3(1, 1, 1); 
      sun.normalize(); 
      canvas = document.createElement('canvas'); 
      canvas.width = width; 
      canvas.height = height; 
      context = canvas.getContext('2d'); 
      context.fillStyle = '#000'; 
      context.fillRect(0, 0, width, height); 
      image = context.getImageData(0, 0, canvas.width, canvas.height); 
      imageData = image.data; 
      for (var i = 0, j = 0, l = imageData.length; i < l; i += 4, j ++) { 
       vector3.x = data[ j - 2 ] - data[ j + 2 ]; 
       vector3.y = 2; 
       vector3.z = data[ j - width * 2 ] - data[ j + width * 2 ]; 
       vector3.normalize(); 
       shade = vector3.dot(sun); 
       imageData[ i ] = (96 + shade * 128) * (0.5 + data[ j ] * 0.007); 
       imageData[ i + 1 ] = (32 + shade * 96) * (0.5 + data[ j ] * 0.007); 
       imageData[ i + 2 ] = (shade * 96) * (0.5 + data[ j ] * 0.007); 
      } 
      context.putImageData(image, 0, 0); 
      // Scaled 4x 
      canvasScaled = document.createElement('canvas'); 
      canvasScaled.width = width * 4; 
      canvasScaled.height = height * 4; 
      context = canvasScaled.getContext('2d'); 
      context.scale(4, 4); 
      context.drawImage(canvas, 0, 0); 
      image = context.getImageData(0, 0, canvasScaled.width, canvasScaled.height); 
      imageData = image.data; 
      for (var i = 0, l = imageData.length; i < l; i += 4) { 
       var v = ~~ (Math.random() * 5); 
       imageData[ i ] += v; 
       imageData[ i + 1 ] += v; 
       imageData[ i + 2 ] += v; 
      } 
      context.putImageData(image, 0, 0); 
      return canvasScaled; 
     } 
     // 
     function animate() { 
      requestAnimationFrame(animate); 
      render(); 
      //stats.update(); 
     } 
     function render() { 
      controls.update(clock.getDelta()); 
      renderer.render(scene, camera); 
     } 
     function onMouseMove(event) { 
      mouse.x = (event.clientX/renderer.domElement.clientWidth) * 2 - 1; 
      mouse.y = - (event.clientY/renderer.domElement.clientHeight) * 2 + 1; 
      raycaster.setFromCamera(mouse, camera); 
      // See if the ray from the camera into the world hits one of our meshes 
      var intersects = raycaster.intersectObject(mesh); 
      // Toggle rotation bool for meshes that we clicked 
      if (intersects.length > 0) { 
       helper.position.set(0, 0, 0); 
       helper.lookAt(intersects[ 0 ].face.normal); 
       helper.position.copy(intersects[ 0 ].point); 
      } 
     } 

ответ

0

похоже, ваш data массива, просто имеют данные по высоте (то есть значения у-оси). Он также должен содержать значения оси x и z, которые соответствуют значению высоты.

В generateHeight() что такое j для цикла? Похоже, что вы перезаписываете массив data 4 раза.

+0

Я не слишком уверен, что он делает. Я понимаю, о чем вы говорите, и я соглашусь с вами. Опять же, это пример кода из three.js, и я не могу заставить его работать, как показано на их сайте, поэтому я не могу возиться с ним, чтобы понять его дальше. – user4839968

+0

В каком примере вы имеете в виду? – gaitat

+0

Примером является: http://threejs.org/examples/#webgl_geometry_terrain_raycast и ссылка на код: https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_terrain_raycast.html – user4839968