精灵不显示
Sprite not showing
我在 https://jsfiddle.net/72mnd2yt/1/ that doesn't display the sprite I'm trying to draw. I tried to follow the code over at 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 大小假定为 px)。与 canvas.height
.
相同
2) $('body').height()
为 0,因此渲染器 canvas 不可见(您可以在开发工具中查看它,它在元素树中但被压缩到 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
这是一次性标志,因此如果您想要动态纹理,则需要在每次 canvas 更改时设置它。您不必每次都创建一个新的 THREE.Texture ,只需在渲染循环中添加 texture.needsUpdate
(或者在仅在您想要更改纹理时触发的事件中,如果您要效率)。 See the docs,在 .needsUpdate
.
下
此时,它应该可以工作了。以下是一些需要考虑的其他事项:
5) 您可以使用 CanvasTexture
而不是 Texture
,它会为您设置 .needsUpdate
。您发布的 fiddle 使用的是 Three.js r71,它没有,但较新的版本有。看起来像这样:
var texture = new THREE.CanvasTexture(getPicture(message));
// no needsUpdate necessary
6) 根据注释掉的 return picture
,您似乎已经在这条路径上了,但您可以使用 canvas 元素,或从 url 生成的数据canvas 用于纹理。如果getPicture
现在returns一个数据url,试试这个:
var texture = new THREE.TextureLoader().load(getPicture(message))
您也可以间接使用数据 url 和 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
,两者都需要一个 canvas 元素。 Texture
可以通过传入 src
设置为数据 url.
的图像元素来间接获取 url
Fiddle 以及概述的修复:
https://jsfiddle.net/jbjw/x0uL1kbh/
我在 https://jsfiddle.net/72mnd2yt/1/ that doesn't display the sprite I'm trying to draw. I tried to follow the code over at 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 大小假定为 px)。与 canvas.height
.
2) $('body').height()
为 0,因此渲染器 canvas 不可见(您可以在开发工具中查看它,它在元素树中但被压缩到 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
这是一次性标志,因此如果您想要动态纹理,则需要在每次 canvas 更改时设置它。您不必每次都创建一个新的 THREE.Texture ,只需在渲染循环中添加 texture.needsUpdate
(或者在仅在您想要更改纹理时触发的事件中,如果您要效率)。 See the docs,在 .needsUpdate
.
此时,它应该可以工作了。以下是一些需要考虑的其他事项:
5) 您可以使用 CanvasTexture
而不是 Texture
,它会为您设置 .needsUpdate
。您发布的 fiddle 使用的是 Three.js r71,它没有,但较新的版本有。看起来像这样:
var texture = new THREE.CanvasTexture(getPicture(message));
// no needsUpdate necessary
6) 根据注释掉的 return picture
,您似乎已经在这条路径上了,但您可以使用 canvas 元素,或从 url 生成的数据canvas 用于纹理。如果getPicture
现在returns一个数据url,试试这个:
var texture = new THREE.TextureLoader().load(getPicture(message))
您也可以间接使用数据 url 和 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
,两者都需要一个 canvas 元素。 Texture
可以通过传入 src
设置为数据 url.
Fiddle 以及概述的修复: https://jsfiddle.net/jbjw/x0uL1kbh/