2016-09-02 68 views
0

我正在使用three.js ocean scene 3D canvas text。 3D文本假設替換球的位置,但文本不會出現。 當我檢查元素時,我只注意到背景渲染的畫布。兩種畫布(背景和3D文字)如何出現?我怎樣才能在另一個畫布上疊加? 在3D文本中沒有使用畫布或canvasrenderer.js的情況下,在水面上顯示3D文字的另一種方法是什麼?Threejs:WebGL 3D文本到three.js海洋場景

爲畫布3D文字

原始代碼:https://github.com/mrdoob/three.js/blob/master/examples/canvas_geometry_text.html

JavaScript以兩個元素結合:

var container, stats; 
     var camera, scene, renderer; 

     var parameters = { 
      width: 2000, 
      height: 2000, 
      widthSegments: 250, 
      heightSegments: 250, 
      depth: 1500, 
      param: 4, 
      filterparam: 1 
     }; 
     var waterNormals; 
     var group; 

     var targetRotation = 0; 
     var targetRotationOnMouseDown = 0; 

     var loader = new THREE.FontLoader(); 
     loader.load('fonts/helvetiker_regular.typeface.json', function (font) { 

     }); 
     init(); 
     animate(); 
     function init(font) { 

      container = document.createElement('div'); 
      document.body.appendChild(container); 



      camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 1000); 
      camera.position.set(0, 150, 500); 

      scene = new THREE.Scene(); 

      // Get text from hash 

      var theText = "three.js"; 

      var hash = document.location.hash.substr(1); 

      if (hash.length !== 0) { 

       theText = hash; 

      } 

      var geometry0 = new THREE.TextGeometry(theText, { 

       font: font, 
       size: 80, 
       height: 20, 
       curveSegments: 2 

      }); 

      geometry.computeBoundingBox(); 

      var centerOffset = -0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x); 

      var material0 = new THREE.MultiMaterial([ 
       new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff, overdraw: 0.5 }), 
       new THREE.MeshBasicMaterial({ color: 0x000000, overdraw: 0.5 }) 
      ]); 

      var mesh = new THREE.Mesh(geometry0, material0); 

      mesh.position.x = centerOffset; 
      mesh.position.y = 100; 
      mesh.position.z = 50; 



      group = new THREE.Group(); 
      group.add(mesh); 

      scene.add(group); 

      renderer = new THREE.CanvasRenderer(); 
      renderer.setClearColor(0xf0f0f0); 
      renderer.setPixelRatio(window.devicePixelRatio); 
      renderer.setSize(window.innerWidth, window.innerHeight); 
      container.appendChild(renderer.domElement); 

      stats = new Stats(); 
      container.appendChild(stats.dom); 

      // 

      window.addEventListener('resize', onWindowResize, false); 

     } 
     function onWindowResize() { 

      camera.aspect = window.innerWidth/window.innerHeight; 
      camera.updateProjectionMatrix(); 

      renderer.setSize(window.innerWidth, window.innerHeight); 

     } 
     function init() { 
      container = document.createElement('div'); 
      document.body.appendChild(container); 
      renderer = new THREE.WebGLRenderer(); 
      renderer.setPixelRatio(window.devicePixelRatio); 
      renderer.setSize(window.innerWidth, window.innerHeight); 
      container.appendChild(renderer.domElement); 
      scene = new THREE.Scene(); 
      camera = new THREE.PerspectiveCamera(55, window.innerWidth/window.innerHeight, 0.5, 3000000); 
      camera.position.set(2000, 750, 2000); 
      controls = new THREE.OrbitControls(camera, renderer.domElement); 
      controls.enablePan = false; 
      controls.minDistance = 1000.0; 
      controls.maxDistance = 5000.0; 
      controls.maxPolarAngle = Math.PI * 0.495; 
      controls.target.set(0, 500, 0); 
      scene.add(new THREE.AmbientLight(0x444444)); 
      var light = new THREE.DirectionalLight(0xffffbb, 1); 
      light.position.set(- 1, 1, - 1); 
      scene.add(light); 
      waterNormals = new THREE.TextureLoader().load('textures/waternormals.jpg'); 
      waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping; 
      water = new THREE.Water(renderer, camera, scene, { 
       textureWidth: 512, 
       textureHeight: 512, 
       waterNormals: waterNormals, 
       alpha: 1.0, 
       sunDirection: light.position.clone().normalize(), 
       sunColor: 0xffffff, 
       waterColor: 0x001e0f, 
       distortionScale: 50.0, 
      }); 
      mirrorMesh = new THREE.Mesh(
       new THREE.PlaneBufferGeometry(parameters.width * 500, parameters.height * 500), 
       water.material 
      ); 
      mirrorMesh.add(water); 
      mirrorMesh.rotation.x = - Math.PI * 0.5; 
      scene.add(mirrorMesh); 
      // load skybox 
      var cubeMap = new THREE.CubeTexture([]); 
      cubeMap.format = THREE.RGBFormat; 
      var loader = new THREE.ImageLoader(); 
      loader.load('textures/skyboxsun25degtest.png', function (image) { 
       var getSide = function (x, y) { 
        var size = 1024; 
        var canvas = document.createElement('canvas'); 
        canvas.width = size; 
        canvas.height = size; 
        var context = canvas.getContext('2d'); 
        context.drawImage(image, - x * size, - y * size); 
        return canvas; 
       }; 
       cubeMap.images[ 0 ] = getSide(2, 1); // px 
       cubeMap.images[ 1 ] = getSide(0, 1); // nx 
       cubeMap.images[ 2 ] = getSide(1, 0); // py 
       cubeMap.images[ 3 ] = getSide(1, 2); // ny 
       cubeMap.images[ 4 ] = getSide(1, 1); // pz 
       cubeMap.images[ 5 ] = getSide(3, 1); // nz 
       cubeMap.needsUpdate = true; 
      }); 
      var cubeShader = THREE.ShaderLib[ 'cube' ]; 
      cubeShader.uniforms[ 'tCube' ].value = cubeMap; 
      var skyBoxMaterial = new THREE.ShaderMaterial({ 
       fragmentShader: cubeShader.fragmentShader, 
       vertexShader: cubeShader.vertexShader, 
       uniforms: cubeShader.uniforms, 
       depthWrite: false, 
       side: THREE.BackSide 
      }); 
      var skyBox = new THREE.Mesh(
       new THREE.BoxGeometry(1000000, 1000000, 1000000), 
       skyBoxMaterial 
      ); 
      scene.add(skyBox); 
      var geometry = new THREE.IcosahedronGeometry(400, 4); 
      for (var i = 0, j = geometry.faces.length; i < j; i ++) { 
       geometry.faces[ i ].color.setHex(Math.random() * 0xffffff); 
      } 
      var material = new THREE.MeshPhongMaterial({ 
       vertexColors: THREE.FaceColors, 
       shininess: 100, 
       envMap: cubeMap 
      }); 

     } 
     // 
     function animate() { 
      requestAnimationFrame(animate); 
      render(); 
     } 
     function render() { 


      water.material.uniforms.time.value += 1.0/60.0; 
      controls.update(); 
      water.render(); 
      renderer.render(scene, camera); 
     } 

回答

1

我注意到的第一件事是,你調用init();動畫();函數在加載器有機會加載字體之前(因爲你沒有將字體傳遞到像canvas_geometry_text例子那樣的init函數中)。

我從下面的海洋示例中粘貼了代碼(有關如何修改它以使用canvas_geometry_text示例中的代碼的註釋)。我已經測試過這個,它能正常工作

 var container, stats; 
     var camera, scene, renderer; 
     var sphere; 

     var parameters = { 
      width: 2000, 
      height: 2000, 
      widthSegments: 250, 
      heightSegments: 250, 
      depth: 1500, 
      param: 4, 
      filterparam: 1 
     }; 

     var waterNormals; 

     // 1. 
     // copy+paste this code from the canvas_geometry_text file 
     var loader = new THREE.FontLoader(); 
     loader.load('fonts/helvetiker_regular.typeface.json', function (font) { 

      init(font); 
      animate(); 

     }); 

     // 2. 
     // comment out these calls to init() and animate() 
     // these will be called in the loader's callback above instead 
     // init(); 
     // animate(); 

     // add 'font' parameter to init 
     function init(font) { 

      container = document.createElement('div'); 
      document.body.appendChild(container); 

      renderer = new THREE.WebGLRenderer(); 
      renderer.setPixelRatio(window.devicePixelRatio); 
      renderer.setSize(window.innerWidth, window.innerHeight); 
      container.appendChild(renderer.domElement); 

      scene = new THREE.Scene(); 

      camera = new THREE.PerspectiveCamera(55, window.innerWidth/window.innerHeight, 0.5, 3000000); 
      camera.position.set(2000, 750, 2000); 

      controls = new THREE.OrbitControls(camera, renderer.domElement); 
      controls.enablePan = false; 
      controls.minDistance = 1000.0; 
      controls.maxDistance = 5000.0; 
      controls.maxPolarAngle = Math.PI * 0.495; 
      controls.target.set(0, 500, 0); 

      scene.add(new THREE.AmbientLight(0x444444)); 

      var light = new THREE.DirectionalLight(0xffffbb, 1); 
      light.position.set(- 1, 1, - 1); 
      scene.add(light); 


      waterNormals = new THREE.TextureLoader().load('textures/waternormals.jpg'); 
      waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping; 

      water = new THREE.Water(renderer, camera, scene, { 
       textureWidth: 512, 
       textureHeight: 512, 
       waterNormals: waterNormals, 
       alpha: 1.0, 
       sunDirection: light.position.clone().normalize(), 
       sunColor: 0xffffff, 
       waterColor: 0x001e0f, 
       distortionScale: 50.0, 
      }); 


      mirrorMesh = new THREE.Mesh(
       new THREE.PlaneBufferGeometry(parameters.width * 500, parameters.height * 500), 
       water.material 
      ); 

      mirrorMesh.add(water); 
      mirrorMesh.rotation.x = - Math.PI * 0.5; 
      scene.add(mirrorMesh); 


      // load skybox 

      var cubeMap = new THREE.CubeTexture([]); 
      cubeMap.format = THREE.RGBFormat; 

      var loader = new THREE.ImageLoader(); 
      loader.load('textures/skyboxsun25degtest.png', function (image) { 

       var getSide = function (x, y) { 

        var size = 1024; 

        var canvas = document.createElement('canvas'); 
        canvas.width = size; 
        canvas.height = size; 

        var context = canvas.getContext('2d'); 
        context.drawImage(image, - x * size, - y * size); 

        return canvas; 

       }; 

       cubeMap.images[ 0 ] = getSide(2, 1); // px 
       cubeMap.images[ 1 ] = getSide(0, 1); // nx 
       cubeMap.images[ 2 ] = getSide(1, 0); // py 
       cubeMap.images[ 3 ] = getSide(1, 2); // ny 
       cubeMap.images[ 4 ] = getSide(1, 1); // pz 
       cubeMap.images[ 5 ] = getSide(3, 1); // nz 
       cubeMap.needsUpdate = true; 

      }); 

      var cubeShader = THREE.ShaderLib[ 'cube' ]; 
      cubeShader.uniforms[ 'tCube' ].value = cubeMap; 

      var skyBoxMaterial = new THREE.ShaderMaterial({ 
       fragmentShader: cubeShader.fragmentShader, 
       vertexShader: cubeShader.vertexShader, 
       uniforms: cubeShader.uniforms, 
       depthWrite: false, 
       side: THREE.BackSide 
      }); 

      var skyBox = new THREE.Mesh(
       new THREE.BoxGeometry(1000000, 1000000, 1000000), 
       skyBoxMaterial 
      ); 

      scene.add(skyBox); 

      // 3. 
      // comment out all the sphere mesh code 

      // var geometry = new THREE.IcosahedronGeometry(400, 4); 

      // for (var i = 0, j = geometry.faces.length; i < j; i ++) { 

      // geometry.faces[ i ].color.setHex(Math.random() * 0xffffff); 

      // } 

      // var material = new THREE.MeshPhongMaterial({ 
      // vertexColors: THREE.FaceColors, 
      // shininess: 100, 
      // envMap: cubeMap 
      // }); 

      // sphere = new THREE.Mesh(geometry, material); 
      // scene.add(sphere); 

      // 4. 
      // copy+paste the text mesh code from canvas_geometry_text 

      var theText = "Hello three.js! :)"; 

      var hash = document.location.hash.substr(1); 

      if (hash.length !== 0) { 

       theText = hash; 

      } 

      var geometry = new THREE.TextGeometry(theText, { 

       font: font, 
       size: 80, 
       height: 20, 
       curveSegments: 2 

      }); 

      geometry.computeBoundingBox(); 

      var centerOffset = -0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x); 

      var material = new THREE.MultiMaterial([ 
       new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff, overdraw: 0.5 }), 
       new THREE.MeshBasicMaterial({ color: 0x000000, overdraw: 0.5 }) 
      ]); 

      var mesh = new THREE.Mesh(geometry, material); 

      mesh.position.x = centerOffset; 
      mesh.position.y = 100; 
      mesh.position.z = 0; 

      mesh.rotation.x = 0; 
      mesh.rotation.y = Math.PI * 2; 

      group = new THREE.Group(); 
      group.add(mesh); 

      scene.add(group); 
     } 

     // 

     function animate() { 

      requestAnimationFrame(animate); 
      render(); 

     } 

     function render() { 

      var time = performance.now() * 0.001; 

      // 6. 
      // comment out the sphere animation code 

      // sphere.position.y = Math.sin(time) * 500 + 250; 
      // sphere.rotation.x = time * 0.5; 
      // sphere.rotation.z = time * 0.51; 

      // 7. 
      // copy+paste the sphere animation code above 
      // but replace 'sphere' with 'group' 

      group.position.y = Math.sin(time) * 500 + 250; 
      group.rotation.x = time * 0.5; 
      group.rotation.z = time * 0.51; 

      water.material.uniforms.time.value += 1.0/60.0; 
      controls.update(); 
      water.render(); 
      renderer.render(scene, camera); 

     } 
+0

我該如何使用點擊功能改變文本? – redfelix

+0

這是與此處詢問的問題不同的問題。如果這回答了您的問題,您應該接受它(通過點擊複選標記),並將其作爲一個新問題。 (在這裏留下一個新問題的鏈接,我也可以回答這個問題) – Nick

+0

好的。謝謝。 – redfelix