Three.js对象在大距离闪烁

时间:2013-02-07 21:46:07

标签: javascript three.js webgl

我目前正在开展一个项目,涉及在物体范围从10到1000000的场景中工作。我一直有一个问题,当我处于这些尺寸的大范围时,物体开始“闪烁”这只发生在物体相交时,然后随着相机离开物体而变得越来越“暴力”

我已在此处上传了问题的图片:http://imgur.com/SOeemng

虽然我不知道造成这种情况的原因,但我对可能导致这种情况的原因有一些看法:

首先,我的工作尺寸是否太大而不适合three.js / webgl

我想到的第二种可能性可能是使用我所制作的相机控件的问题,如下所示:

    if(mouseIsDown == true){
        if(this.movementSpeed < this.maxSpeed){
            this.movementSpeed += this.acceleration
        }else{
            this.movementSpeed = this.maxSpeed
        }

    }else{
        if(this.movementSpeed > this.minSpeed){
            this.movementSpeed = this.movementSpeed/this.deceleration
        }else{
            this.movementSpeed = this.minSpeed  
        }

    }

其中this.minSpeed = 0,并且this.movementSpeed用于移动相机,如下所示:

var actualSpeed = delta * this.movementSpeed;
this.object.translateZ( -actualSpeed * forwardOrAuto );
this.object.translateX( actualSpeed * sideSpeed );
this.object.translateY( actualSpeed * upSpeed );

我不认为这会是问题,但由于移动速度实际上从未等于零,因此可能是一个问题。即使移动速度为10 ^ -20或-30,闪烁仍然会发生。

如果重要的话,我也在55号。

3 个答案:

答案 0 :(得分:11)

听起来像精确问题。运动可以放大舍入误差的影响。在使用three.js中的太阳系模型(uom:米)时,我遇到了许多关于“闪烁”纹理/模型的问题。 gaitat绝对正确,您遇到z缓冲区深度精度问题。我和我的伙伴有几种方法可以处理它。

z缓冲区不是线性的。 gaitat提到的sjbaker网站将会像几个月前那样清楚地表达出来。大多数z缓冲区精度都在附近找到。如果您的对象的大小最多为1000000个单位,那么对象本身(更不用说它们之间的空间)已经超出了有效精度范围。很多很多视频游戏都使用的一个解决方案是移动播放器(相机),而是移动世界。这样,随着某些东西越来越靠近相机,它的精度也会提高。这对于远处大的重叠物体(闪烁/遮挡)上的纹理或远离轴向原点的小网格来说是最重要的,其中圆角问题变得严重到足以将网格跳出视野。这说起来肯定说起来容易做起,因为你要么必须进行“及时”计算,以便根据玩家移动所有内容(并且仍然会遇到舍入错误),或者提出更优雅的解决方案。

对于非常高的远距离数字,你将失去非常接近的精度,但是你会在中距离内获得相当大的精度,并且近似数字略大。即使你正在使用的网格可以小到10个单位,近10或100的相机设置可能会让你有些松懈。相机设置不是处理z缓冲区的唯一方法。

polygonOffset - 你有效地告诉z-buffer哪个东西(网格上的材料)属于顶部。它可以引入尽可能多的问题,并且可以进行相当多的调整。考虑它类似于css中的z-index,但有点变幻无常。增加一个材质上的偏移以确保它在远处的某些东西上渲染,可以使其渲染在近处的某些东西上。它可以滚雪球,迫使你在大多数物体上设置偏移量。 polygonOffset的因子和单位数通常介于-1.0和1.0之间,可能需要进行调整。

depthWrite=false - 这意味着“不要写入深度缓冲区”,并且非常适用于始终在所有内容后面“渲染”的材质。很好的例子是天空盒和背景。

我们的项目使用了上述所有方法,并且仍然有平庸的结果,尽管我们处理的数字大到40个天文单位(米)(冥王星)。

“他们”称之为“z-fighting”,所以要打好斗争!

答案 1 :(得分:3)

由于你的范围很大,你必须将你的相机设置在接近0的平面附近,你的远平面接近1000000.但是没有足够的z分辨率。您可以在http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html了解更多相关信息。

答案 2 :(得分:0)

我不知道如何实现但可能有效的解决方案是使用两个场景和两个摄像头。

一个场景是关闭的东西,另一个场景是遥远的东西。使用具有适合于所需要的zNear和zFar的相机来渲染每个场景。即关闭场景有一个zNear = 0.1和zFar = 10,000的相机,而远场有一个zNear = 10,000且zFar = 6,000,000

的相机

难以将TrackballControls连接到两个摄像头以同步场景。