Culling: What am I missing?

I’ve just discovered, thanks to a player reporting it, that if one sets the FOV in A Door to the Mists to 60, one suddenly encounters rather nasty flickering of geometry that looks like a culling issue.

This flickering doesn’t seem to be visible at an FOV of 50, or of 70.

My guess is that I’m missing a step somewhere that would update Panda’s culling frustum, or something like that–but if so, then I don’t know what step I’m missing.

Note that this is being done on a custom camera, rather than the default “base.cam” camera.

The FOV is adjusted like so:

        lens = world.sceneCamera.node().getLens()

        lens.setFov(fov*lens.getAspectRatio())

And the camera and related card and buffer are created or (if antialiasing is toggled) updated like so:

        self.cleanupBuffers()

        frameProperties = FrameBufferProperties()
        frameProperties.setMultisamples(multisamples)
        frameProperties.setRgbaBits(8, 8, 8, 0)
        frameProperties.setDepthBits(32)

        windowProperties = base.win.getProperties()

        self.mainBuffer = base.graphicsEngine.makeOutput(base.pipe, "Main Buffer", -1,
                                                         frameProperties, windowProperties,
                                                         GraphicsPipe.BFRefuseWindow, base.win.getGsg(), base.win)
        self.mainBuffer.setClearColor(Vec4(0, 0, 0, 1))

        if self.sceneCamera is None:
            self.sceneCamera = base.makeCamera(self.mainBuffer)
            self.sceneCamera.node().setScene(self.rootNode)
            self.sceneCamera.node().setCameraMask(BitMask32(1))
            self.updateAspectRatio()
        else:
            region = self.mainBuffer.makeDisplayRegion(0, 1, 0, 1)
            region.setCamera(self.sceneCamera)

        self.sceneTexture = Texture()
        self.sceneTexture.setWrapU(Texture.WM_clamp)
        self.sceneTexture.setWrapV(Texture.WM_clamp)

        self.mainBuffer.addRenderTexture(self.sceneTexture,
                                         GraphicsOutput.RTMBindOrCopy)

        self.card.setTexture(self.sceneTexture)

Note that “self.sceneCamera” in the latter excerpt should be the same as “world.sceneCamera” in the former, I believe.

What happens if you increase the “near” distance of the camera?

Ah, based on a quick test, that does seem to help.

Hmm… Since I’m using a first-person camera, this may call for some tweaking and experimentation, then.

(My test-value of 0.1 is likely a bit too large. That said, I didn’t notice too many clipping issues, so perhaps it’s better that I might have thought, and my current value of 0.01 rather smaller than I can get away with…)

Does the flickering occur in the distance, nearby, or at medium range?

You could also try seeing if switching to 24 depth bits makes a difference. It sounds counter-intuitive, but 24-bits depth is an integer format, and 32-bit depth is a floating-point format. Integer depth values are distributed more uniformly across the depth range, whereas OpenGL conventions put most of the floating-point depth precision in the middle of the depth range. (Also see this article for more on that).

Using a reverse-Z set-up would yield ideal results, but it should not be necessary in most games.

I’ve only seen it at near-to-mid range, I think. However, the only test-scenario that I have that includes much distant geometry also has a fairly limited view-range (due to taking place in the dark).

That said, I think that I may have found a decent compromise value of 0.03: with this value I’m not seeing significant clipping, and the flickering doesn’t seem to occur–at least that I’ve spotted thus far.

However, if it does turn up again, I can revisit your further suggestions; and either way, thank you for them! :slight_smile: