尽管相机不靠近

时间:2017-05-17 01:30:07

标签: three.js webgl

切换到Three.js中的对数深度缓冲区后,我遇到了一个问题。除了附近的剔除地面外,一切都运行良好,如下图所示:

enter image description here

enter image description here

如您所见,相机显着高于地面。显示的字符框大约离地面2个单位,我的相机设置如下:

  var WIDTH = window.innerWidth
    , HEIGHT = window.innerHeight;
  var VIEW_ANGLE = 70
    , ASPECT = WIDTH / HEIGHT
    , NEAR = 1e-6
    , FAR = 9000;
  var aspect = WIDTH / HEIGHT;
  var camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
  camera.rotation.order = 'YXZ';  

所以我的NEAR参数远不及2,即相机与地面之间的距离。您可以在第二张图片中看到我甚至使用我的PointerLockControls向上移动相机并仍然遇到问题。

任何人都可以诊断我的问题吗?

我还通过查看静态相机是否发生此错误来测试我的问题。确实如此。

此外,此问题仅发生在对数深度缓冲区中,因为默认深度缓冲区不会发生此问题。

我的相机是controls对象的孩子,其定义如下:

controls = new THREE.PointerLockControls(camera);
controls.getObject().position.set(strtx, 50, strtz);
scene.add(controls.getObject());
camera.position.z += 2;
camera.position.y += .1;  

这是PointerLockControls的相关代码:

var pitchObject, yawObject;
var v = new THREE.Vector3(0, 0, -1);


THREE.PointerLockControls = function(camera){

    var scope = this;

    camera.rotation.set(0, 0, 0);

    pitchObject = new THREE.Object3D();
    pitchObject.rotation.x -= 0.3;
    pitchObject.add(camera);


    yawObject = new THREE.Object3D();
    yawObject.position.y = 10;
    yawObject.add(pitchObject);


    var PI_2 = Math.PI / 2;

    var onMouseMove = function(event){

        if (scope.enabled === false) return;

        var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
        var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;

        yawObject.rotation.y -= movementX * 0.002;
        pitchObject.rotation.x -= movementY * 0.002;

        pitchObject.rotation.x = Math.max( - PI_2, Math.min( PI_2, pitchObject.rotation.x ) );

    };

    this.dispose = function() {

        document.removeEventListener( 'mousemove', onMouseMove, false );

    };

    document.addEventListener( 'mousemove', onMouseMove, false );

    this.enabled = false;

    this.getObject = function () {

        return yawObject;

    };

    this.getDirection = function() {

        // assumes the camera itself is not rotated

        var rotation = new THREE.Euler(0, 0, 0, "YXZ");
    var direction = new THREE.Vector3(0, 0, -1);

        return function() {

            rotation.set(pitchObject.rotation.x, yawObject.rotation.y, 0);
            v.copy(direction).applyEuler(rotation);

            return v;

        };

    }();

};

你还会注意到它只是被剔除的地面,而不是其他物品

enter image description here

编辑:

我掀起了一个显示更大问题的孤立环境。在第一张图片中,我有一个平面PlaneBufferGeometry,其宽度和高度分别为400个,由var g = new THREE.PlaneBufferGeometry(380, 380, 400, 400);定义。即使非常接近表面,也不会出现削波:
enter image description here

但是,如果我只提供1个段var g = new THREE.PlaneBufferGeometry(380, 380, 1, 1);,则存在剪辑 enter image description here

我不确定这是否适用于Three.js / WebGL,但似乎我需要做一些事情来解决它。

1 个答案:

答案 0 :(得分:0)

我不认为这是一个错误,我认为这是不同设置中深度缓冲区的工作原理。 Look at this example。在右边,深度缓冲无法在“微观”和球体中的字母之间作出决定。这是因为它在非常小的尺度上具有较低的精度,并且开始在一个物体和另一个物体之间进行振荡,并且有利于z深度的绘制顺序。

这总是一个权衡。如果你想放弃这个问题,你可以尝试整体提高场景的比例,这样相机的“近处”永远不会那么接近它可以绕过它的东西 - 所以只需要工作在一个范围内,不会在对数z缓冲区的指数模型中舍入。

另外一个问题 - 蓝色是如何定义的,因为你所看到的可能不是因为太近而不是剪裁,而是蓝色或地面之间的混淆。如果它只是一个包含所有东西的蓝色盒子,你可以尝试让它更大,更远离地面。

修改: 好的,这看起来应该可行。所以我会开始寻找边缘情况。您可以做些什么来改变场景以使其发挥作用?你可以做些什么让其他事情开始破碎?

  • 尝试将景观向远/向上移动(当向上看而不是向下看时问题是否仍然存在,即使它毫无疑问地远离它也会持续存在?)
  • 尝试旋转景观
  • 尝试更换相机FOV
  • 尝试更改远摄镜头
  • 尝试将近距离的相机从1e-x表示法更改为.000001,.0001,.01,.1等,看看它有什么效果。
  • console.log渲染函数中的相机对象,并确保fov,near,far等与您在设置中设置的一样,并且它没有被覆盖并重置为默认值。检查它在chrome的开发者工具中输出的内容,你可以浏览整个对象,检查位置,父名称,所有这些。

基本上我没有看到一个明显的错误,所以我猜它很难被发现,或者它的工作正是应该的。找出你可以做些什么来改善效果/使情况变得更糟,这将澄清一个方向。

调试的一个好的经验法则是尝试将事情发挥到极致,而不是试图修复它,或者保持代码真正达到其目的,并且只看它以何种方式进一步突破/改变。当你发现某事时报告回来。