精灵没有显示

时间:2017-08-15 09:44:56

标签: three.js sprite

我在https://jsfiddle.net/72mnd2yt/1/处有一些代码,它们没有显示我想要绘制的精灵。我尝试在https://stemkoski.github.io/Three.js/Sprite-Text-Labels.html处遵循代码并逐行阅读,但我不确定我哪里出错了。有人会介意看看吗?

以下是一些相关代码:

// picture
var getPicture = function(message){
  var canvas = document.createElement('canvas');
  canvas.width = "100%";
  canvas.height = "100%";

  var context = canvas.getContext('2d');
  context.font = "10px";
  context.fillText(message, 0, 10);
  var picture = canvas.toDataURL();
  // return picture;
  return canvas;
};

// let there be light and so forth...
var getScene = function(){
  var scene = new THREE.Scene();
  var camera = new THREE.PerspectiveCamera(
    70, 
    $('body').width(), 
    $('body').height(),
    1,
    1000
  );

  var light = new THREE.PointLight(0xeeeeee);
  scene.add(camera);
  scene.add(light);

  var renderer = new THREE.WebGLRenderer();
  renderer.setClearColor(0xefefef);
  renderer.setSize($('body').width(), $('body').height());

  camera.position.z = -10;
  camera.lookAt(new THREE.Vector3(0, 0, 0));

  return [scene, renderer, camera];
};

// now for the meat
var getLabel = function(message){
  var texture = new THREE.Texture(getPicture(message));
  var spriteMaterial = new THREE.SpriteMaterial(
    {map: texture }
  );
  var sprite = new THREE.Sprite(spriteMaterial);
  //sprite.scale.set(100, 50, 1.0);
  return sprite
};

var setup = function(){
  var scene;
  var renderer;
  var camera;
  [scene, renderer, camera] = getScene();
  $('body').append(renderer.domElement);

  var label = getLabel("Hello, World!");
  scene.add(label);

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

  animate();
};


setup();

1 个答案:

答案 0 :(得分:2)

几点:

1)canvas.width = "100%"应为canvas.width = "100"(假设画布大小为px)。与canvas.height相同。

2)$('body').height()为0,因此渲染器画布不可见(您可以在开发工具中查看它,它在元素树中但是压缩到0px高)。我对jQuery一无所知,所以不确定为什么会这样,但我建议不要使用window.innerHeightwindow.innerWidth。所以renderer.setSize(window.innerWidth, window.innerHeight)。您还希望在相机初始化中进行此更改。

3)说到相机初始化,当只应该有宽高比参数时,你将宽度和高度作为单独的参数传递。 See the docs。所以
var camera = new THREE.PerspectiveCamera(70, window.innerWidth, window.innerHeight, 1, 1000)
成为
var camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 1, 1000)

4)因为假设纹理是静态的,所以你需要在这个部分添加一些东西:

var texture = new THREE.Texture(getPicture(message))
texture.needsUpdate = true // this signals that the texture has changed

这是一次性标志,因此如果您想要动态纹理,每次画布更改时都需要设置它。你不必每次都要制作一个新的THREE.Texture,只需在渲染循环中添加texture.needsUpdate(或者只在你希望纹理发生变化时触发的事件,如果你是这样的话)追求效率)。 See the docs.needsUpdate下。

此时,它应该工作。以下是一些需要考虑的事项:

5)您可以使用Texture代替CanvasTexture,而.needsUpdate可为您设置var texture = new THREE.CanvasTexture(getPicture(message)); // no needsUpdate necessary 。你发布的小提琴使用的是Three.js r71,它没有它,但更新的版本可以。这看起来像这样:

return picture

6)看起来你已经在这条路径上已经注释了getPicture,但你可以使用canvas元素,或者从画布生成的数据url作为纹理。如果var texture = new THREE.TextureLoader().load(getPicture(message)) 现在返回数据网址,请尝试以下操作:

Texture

您还可以间接使用var img = document.createElement('img') var img = new Image() img.src = getPicture(message) var texture = new THREE.Texture(img); texture.needsUpdate = true 的数据网址:

Texture

如果没有,只需坚持CanvasTextureTexture,两者都将采用画布元素。 src可以通过传入{{1}}设置为数据网址的图像元素来间接获取网址。

弄清楚概述的修正: https://jsfiddle.net/jbjw/x0uL1kbh/