I’ve got a problem with rendering. In the two links you can find pictures made with movie recorder (base.movie). In game w/o movie the effect or bug is the same. When I look almost perpendicular at two textured planes(one of them is about 3m closer to camera, both about 800m away from it), I can see stripes of texture from the lower plane which should be totally invisible. Here are two images illustrating the problem:
EDIT:It happens at almost any angle if camera is far away. It looks like one of the planes is changing position every frame…like vibrating. The getPos() of two planes returns:
Point3(9.48843, 84.9114, 75.7869)
Point3(7.75332, 83.8271, 73.5929)
The plane below is the one with brighter colours.
Any help welcome.
This is called Z-fighting, and happens when to planes evaluate to the same Z value in normalized space–that is to say, they are very nearly coplanar. In this case, your graphics card will sometimes evaluate one plane on top, and sometimes the other, and it all changes radically based on very tiny adjustments of your camera position, so it seems that the planes are flickering.
There are three possible solutions.
(1) move the two competing planes farther apart until they no longer flash.
(2) move your camera’s near distance and far distance closer together–this increases the resolution of Z values available to your graphics card. In particular, making setNear() a bigger value will have a much more important effect than making setFar() a smaller value, so push your near distance out as much as you need to.
(3) Insist on opening a window with a larger depth buffer. Modern graphics cards offer depth (Z) buffers with 16, 24, or 32 bits. If you are seeing this effect on a distance of 3 m apart with only 800m from the camera, either you only have a 16-bit depth buffer, or your near distance is set very very tiny. You can try to get a larger depth buffer by putting:
in your Config.prc file. Of course, there are no guarantees that your graphics card will be able to fulfill this request.
Actually, I guess there are a few more solutions, depending on the particular circumstances; for instance, you can disable depth test on one or both planes. But these are very scene-specific workarounds.
What are the safest values we set for near/far planes if we use 24 and 32 bits for the zbuffer?
Is there any formula we can use to convert positions to zbuffer values to check if two positions will be computed to the same zbuffer value after the value is rounded or wharever happens when the gc computes this?
Finnaly is it possible to test what zbuffer resolution a gc suports and choose the best one programmaticaly?
Thanks in advance.
This really depends on the nature of your scene. But it’s fairly easily to determine experimentally what values work for a given scene; just set them and see what happens. Usually, the near plane should be set to at least a foot or so.
Hmm, surely there is. I don’t know it off-hand, but I bet you could find this by googling around for it or by checking tips on opengl.org.
Panda does try to do this automatically. However, this usually involves a compromise between zbuffer resolution and color resolution and/or other framebuffer options such as stencil planes, multisample bits, and what-have-you. Basically, your graphics card has a certain number of bits per pixel that it can give you, and you have several ways to divvy up those bits. If you put more of them into the depth buffer, in means you have fewer bits to use for other special features.
This is the purpose of the depth-bits config variable; there are also other config variables such as color-bits, stencil-bits, and multisamples. If you put a number in depth-bits, it tells Panda to put more importance on getting at least the requested number of depth bits, perhaps at the expense of one of the other planes if necessary. If you do not request a minimum number of depth bits, Panda will try to choose a format that offers a good compromise between depth bits and the other bits.
You can also find out how many depth bits you ended up with by examining base.win.getFbProperties().