在使用PerspectiveCamera时,three.js sprite似乎忽略了父级的比例

时间:2014-10-03 14:54:39

标签: three.js sprite scale

我试图使用PerspectiveCamera在三维场景中使用恒定大小(无论相机距离)使用文本精灵。为了让非精灵有一个不变的大小,我让他们成为一个特殊的孩子#34;缩放"当相机到原点的距离发生变化时,调整其比例的对象(参见下面的代码)。这很适合保持一般对象大致相同的视觉大小,但是当我向缩放对象添加一个精灵时,精灵似乎忽略了它的父级缩放(因此当你缩小和缩小时它会越来越大) )。

有趣的是,当我们切换到正交相机(取消注释下面的相应线条)时,这个特殊比例的物体似乎不再影响儿童(即,儿童不能保持恒定的大小)。但是,由于我们有一个正交相机,精灵不再随着相机距离的变化而变化(因此它们保持恒定的大小),但这与缩放的物体无关。

我注意到其他一些类似的问题和答案,包括adjust the scale of the sprites themselves(将所有精灵添加到单个缩放对象似乎要容易得多),use an orthographic camera overlay to draw sprites(另请参阅this) (但我希望我的精灵在3D透视场景中。)

所以,我的问题是:为什么精灵在使用PerspectiveCamera时不会根据父母的比例使用比例?另外,为什么我的缩放对象不适用于正交相机?这些相机的缺陷或功能是什么?

谢谢!

http://jsfiddle.net/LLbcs/8/

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;
}

1 个答案:

答案 0 :(得分:0)

如果您希望文字显示在3D场景上并且您不在乎它是否是静态的,那么为什么不尝试在场景上分层div呢?

这样可以节省图形带宽和内存,提高场景性能,并为您提供更好的灵活性。它也更容易做和维护。