保持物体注视相机

Keep objects looking at camera

伙计们,我知道这个问题已经被问过好几次,有几种不同的方式,但我可以让它发挥作用。基本上我有 2d clouds,但我希望相机围绕漂浮在云层上方的物体旋转。问题是,当我不看云的脸时,你可以看出它们是二维的。 Soooo 我希望云彩 "look" 在相机的任何地方。我相信我的问题源于如何将云几何体调用到平面上,但请看这里。我在我的动画函数中放置了一个 lookAt 函数。我希望你至少能给我指出正确的方向。

Three.js 转。 70...

container.appendChild(renderer.domElement);

    camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
    camera.position.set(0, 0, 100);

    scene.add(camera);

    controls = new THREE.OrbitControls( camera );
    controls.target.copy( new THREE.Vector3( 0, 0,475) );
    controls.minDistance = 50;
    controls.maxDistance = 200;
    controls.autoRotate = true;
    controls.autoRotateSpeed = .2; // 30 seconds per round when fps is 60
    controls.minPolarAngle = Math.PI/4; // radians
    controls.maxPolarAngle = Math.PI/2; // radians
    controls.enableDamping = true;
    controls.dampingFactor = 0.25;

    clock = new THREE.Clock();

    cloudGeometry = new THREE.Geometry();

    var texture = THREE.ImageUtils.loadTexture('img/cloud10.png', null, animate);
    texture.magFilter = THREE.LinearMipMapLinearFilter;
    texture.minFilter = THREE.LinearMipMapLinearFilter;

    var fog = new THREE.Fog(0x4584b4, -100, 3000);

    cloudMaterial = new THREE.ShaderMaterial({

        uniforms: {

            "map": {
                type: "t",
                value: texture
            },
            "fogColor": {
                type: "c",
                value: fog.color
            },
            "fogNear": {
                type: "f",
                value: fog.near
            },
            "fogFar": {
                type: "f",
                value: fog.far
            },

        },
        vertexShader: document.getElementById('vs').textContent,
        fragmentShader: document.getElementById('fs').textContent,
        depthWrite: false,
        depthTest: false,
        transparent: true

    });

    var plane = new THREE.Mesh(new THREE.PlaneGeometry(64, 64));

    for (var i = 0; i < 8000; i++) {

        plane.position.x = Math.random() * 1000 - 500;
        plane.position.y = -Math.random() * Math.random() * 200 - 15;
        plane.position.z = i;
        plane.rotation.z = Math.random() * Math.PI;
        plane.scale.x = plane.scale.y = Math.random() * Math.random() * 1.5 + 0.5;

        plane.updateMatrix();
        cloudGeometry.merge(plane.geometry, plane.matrix);

    }

    cloud = new THREE.Mesh(cloudGeometry, cloudMaterial);
    scene.add(cloud);

    cloud = new THREE.Mesh(cloudGeometry, cloudMaterial);
    cloud.position.z = -8000;
    scene.add(cloud);

    var radius = 100;
    var xSegments = 50;
    var ySegments = 50;
    var geo = new THREE.SphereGeometry(radius, xSegments, ySegments);

    var mat = new THREE.ShaderMaterial({
        uniforms: {
            lightPosition: {
                type: 'v3',
                value: light.position
            },
            textureMap: {
                type: 't',
                value: THREE.ImageUtils.loadTexture("img/maps/moon.jpg")
            },
            normalMap: {
                type: 't',
                value: THREE.ImageUtils.loadTexture("img/maps/normal.jpg")
            },
            uvScale: {
                type: 'v2',
                value: new THREE.Vector2(1.0, 1.0)

            }


        },
        vertexShader: document.getElementById('vertexShader').textContent,
        fragmentShader: document.getElementById('fragmentShader').textContent

    });

    mesh = new THREE.Mesh(geo, mat);
    mesh.geometry.computeTangents();
    mesh.position.set(0, 50, 0);
    mesh.rotation.set(0, 180, 0);
    scene.add(mesh);


}

function onWindowResize() {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
}

function animate() {
    requestAnimationFrame(animate);
    light.orbit(mesh.position, clock.getElapsedTime());
    cloud.lookAt( camera );
    controls.update(camera);
    renderer.render(scene, camera);

}
animate();

window.addEventListener('resize', onWindowResize, false);

只是初步猜测: lookAt 函数需要 Vector3 作为参数。尝试在动画函数中使用 camera.position。

cloud.lookAt( camera.position );

首先,要在始终面向相机的场景中构建 2D 对象,您应该使用 Sprite 对象,因此您无需执行任何操作即可获得此效果。 (并且有更好的表现:))

来自 THREE.org 的定义:Sprite - sprite 是 3d 场景中始终面向相机的平面。

var map = THREE.ImageUtils.loadTexture( "sprite.png" );
var material = new THREE.SpriteMaterial( { map: map, color: 0xffffff, fog: true } );
var sprite = new THREE.Sprite( material );
scene.add( sprite );

请检查这个例子:http://threejs.org/examples/#webgl_points_sprites

我绝对同意,我会使用 Sprite,甚至是 Points,但是,如果为其分配纹理,它会将其渲染为正方形。我的 sprite 是动画的,帧不能打包在方形块中,因为它会占用很多 space。我可能会制作一个网格并使用这个 lookAt 函数。