雪碧没有显示
我在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)canvas.width = "100%"
应canvas.width = "100"
(画布大小被认为是像素)。与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
。你发布的小提琴是使用Three.js r71,它没有它,但新版本。这将是这样的:
var texture = new THREE.CanvasTexture(getPicture(message));
// no needsUpdate necessary
6)看起来你已经根据注释掉return picture
这条道路上,但你可以使用从画布产生任何canvas元素,或数据网址纹理。如果getPicture
现在返回一个数据的网址,试试这个:
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
设置为数据url的图像元素来间接获取url。