我试图使用PerspectiveCamera在三维场景中使用恒定大小(无论相机距离)使用文本精灵。为了让非精灵有一个不变的大小,我让他们成为一个特殊的孩子#34;缩放"当相机到原点的距离发生变化时,调整其比例的对象(参见下面的代码)。这很适合保持一般对象大致相同的视觉大小,但是当我向缩放对象添加一个精灵时,精灵似乎忽略了它的父级缩放(因此当你缩小和缩小时它会越来越大) )。
有趣的是,当我们切换到正交相机(取消注释下面的相应线条)时,这个特殊比例的物体似乎不再影响儿童(即,儿童不能保持恒定的大小)。但是,由于我们有一个正交相机,精灵不再随着相机距离的变化而变化(因此它们保持恒定的大小),但这与缩放的物体无关。
我注意到其他一些类似的问题和答案,包括adjust the scale of the sprites themselves(将所有精灵添加到单个缩放对象似乎要容易得多),use an orthographic camera overlay to draw sprites(另请参阅this) (但我希望我的精灵在3D透视场景中。)
所以,我的问题是:为什么精灵在使用PerspectiveCamera时不会根据父母的比例使用比例?另外,为什么我的缩放对象不适用于正交相机?这些相机的缺陷或功能是什么?
谢谢!
var camera, scene, renderer, geometry, material, mesh, text, controls;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000); var scenescale=1;
//camera = new THREE.OrthographicCamera( -7,7,7,-7, 1, 20 );
camera.position.z = 10;
scene.add(camera);
scaled=new THREE.Object3D();
scene.add(scaled);
var textmaterial = new THREE.SpriteMaterial( {color: 'red', useScreenCoordinates: true, map: texttexture("hi")});
text = new THREE.Sprite( textmaterial );
text.position.set( 1, 1, 0);
scaled.add(text);
var geometry = new THREE.BoxGeometry( 1, 1,1 );
var material = new THREE.MeshLambertMaterial( { color: 0xffffff } );
mesh = new THREE.Mesh( geometry, material );
mesh.position.set(0,3,0);
scaled.add(mesh);
var light = new THREE.PointLight('green');
light.position.set(10,15,10);
camera.add(light);
light = new THREE.PointLight(0x333333);
light.position.set(-10,-15,-8);
camera.add(light);
renderer = new THREE.WebGLRenderer();
controls = new THREE.OrbitControls( camera, renderer.domElement );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
var scale = camera.position.length()/10;
scaled.scale.set(scale,scale,scale);
render();
}
function render() {
renderer.render(scene, camera);
}
function texttexture(string) {
var fontFace = "Arial"
var size = "50";
var color = "white"
var squareTexture = true;
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.height = size;
var font = "Normal " + size + "px " + fontFace;
context.font = font;
var metrics = context.measureText(string);
var textWidth = metrics.width;
canvas.width = textWidth;
if (squareTexture) {
canvas.height = canvas.width;
}
var aspect = canvas.width / canvas.height;
context.textAlign = "center";
context.textBaseline = "middle";
context.fillStyle = color;
// Must set the font again for the fillText call
context.font = font;
context.fillText(string, canvas.width / 2, canvas.height / 2);
var t = new THREE.Texture(canvas);
t.needsUpdate = true;
return t;
}
答案 0 :(得分:0)
如果您希望文字显示在3D场景上并且您不在乎它是否是静态的,那么为什么不尝试在场景上分层div呢?
这样可以节省图形带宽和内存,提高场景性能,并为您提供更好的灵活性。它也更容易做和维护。