我在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();
答案 0 :(得分:2)
几点:
1)canvas.width = "100%"
应为canvas.width = "100"
(假设画布大小为px)。与canvas.height
相同。
2)$('body').height()
为0,因此渲染器画布不可见(您可以在开发工具中查看它,它在元素树中但是压缩到0px高)。我对jQuery一无所知,所以不确定为什么会这样,但我建议不要使用window.innerHeight
和window.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
如果没有,只需坚持CanvasTexture
或Texture
,两者都将采用画布元素。 src
可以通过传入{{1}}设置为数据网址的图像元素来间接获取网址。
弄清楚概述的修正: https://jsfiddle.net/jbjw/x0uL1kbh/