2016-04-13 9 views
0

私はThree.jsとImprovedNoise.jsを使って3D地形を作成しようとしています。 Three.jsサイトの例を使用して、地形のように見えるものを作成することができましたが、それは2D(z軸には拡張されません)です。Three.jsの「地形」を3Dにするにはどうすればよいですか?

このシーンを作成しようとしているうちに、サンプルコードでエラーが発生しました。以下のような私はそれが動作を取得するために、わずかに変更しなければならなかったいくつかのもの、:

geometry.rotateX(-Math.PI)

は私が

geometry.rotateX = -Math.PI

に変更しました

しかし、エラーを投げていたことの1つは、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> 

そして、ここでは、JSです::私は変更 (唯一の他の事はので、私は統計ライブラリが含まれていなかったということでした

は、私はこれらのライブラリを使用しているあなたに

ありがとうございました対応するコードは、ちょうど高さ情報(すなわち、y軸の値)が、

 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