2

我目前正在从事一个项目,该项目涉及在对象大小范围为 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 时,仍然会发生闪烁。

如果这很重要,我也在 r.55 上。

4

3 回答 3

13

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

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

对于非常高的远距离数字,您将损失很少的近精度,但您将在中等范围内获得相当大的精度,而近数字略大。即使您正在使用的网格可以小到 10 个单位,近摄像机设置为 10 或 100 可能会给您带来一些松弛。相机设置不是处理 z-buffer 的唯一方法。

polygonOffset - 您有效地告诉 z 缓冲区哪个东西(网格上的材料)属于顶部。它可以引入尽可能多的问题,因为它解决了,并且可能需要相当多的调整。认为它类似于 css 中的 z-index,但更易变。增加一种材质的偏移量以确保它渲染到远处的某物上,可能会使其渲染到近处的某物上。它会滚雪球,迫使您在大多数对象上设置偏移量。对于 polygonOffset,因子和单位数通常在 -1.0 和 1.0 之间,并且可能需要调整。

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

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

“他们”称其为“z-fighting”,所以要打好仗!

于 2013-02-08T01:29:12.807 回答
4

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

于 2013-02-07T23:10:07.137 回答
0

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

一个场景是近距离的东西,另一个是远距离的东西。每个场景都使用具有适合所需内容的 zNear 和 zFar 的相机进行渲染。即近距离场景有一个 zNear = 0.1 和 zFar = 10,000 的相机,而远景有一个 zNear = 10,000 和 zFar = 6,000,000 的相机

困难在于将 TrackballControls 连接到两个摄像机以同步场景。

于 2015-06-29T19:19:03.243 回答