Mirrors and portals

Easy, assume a face to the side of the portal target, extends only partially into the portal target frustum. Now you have two options. You either clip the face to the frustum involving up to 6 plane-plane intersection tests and then project and render the clipped polygon, or you can just project the whole face and clip it by a single plane. Which would you do?

Originally posted by mcraighead:
[b]I can absolutely assure you, having seen the source code to said game and having stepped through our driver many times while running it, that it does use a clip plane for mirrors and portals.

  • Matt[/b]

How about disabling the user clip plane in your driver experimentally, and tell us what artifacts you see when looking at a portal/teleporter ?

Originally posted by DFrey:
Easy, assume a face to the side of the portal target, extends only partially into the portal target frustum. Now you have two options. You either clip the face to the frustum involving up to 6 plane-plane intersection tests and then project and render the clipped polygon, or you can just project the whole face and clip it by a single plane. Which would you do?

I dont see the picture. The normal frustrum culling should take care of everything.

If you download the source code to glTrace, you could easily modify it to ignore all glEnable(GL_CLIP_PLANE0) calls, and see for yourself.

I went ahead and did exactly that, and took a screenshot of the result. Here you can see the artifact I’ve been speaking of: http://personal.lig.bellsouth.net/~dfrey/noclip.jpg and http://personal.lig.bellsouth.net/~dfrey/noclip2.jpg

[This message has been edited by DFrey (edited 02-19-2001).]

Originally posted by DFrey:
[b]I went ahead and did exactly that, and took a screenshot of the result. Here you can see the artifact I’ve been speaking of: http://personal.lig.bellsouth.net/~dfrey/noclip.jpg and http://personal.lig.bellsouth.net/~dfrey/noclip2.jpg

[This message has been edited by DFrey (edited 02-19-2001).][/b]

GlTrace is a nice utility. I can see that some geometry may get in the way if it is placed near the back of the target view of the portal. I guess there is none with most of the portals, so the clip plane could often be optimized away.

It’s nice that we finally reached ‘the way’ Q3 does this thingy

Now we could need some info on Unreal!!

DFrey,
Am I missing something, because I dont see the problem in the second image.
http://personal.lig.bellsouth.net/~dfrey/noclip2.jpg

As far as I can tell, thats supposed to be how it looks.

No, that dark part in the portal image is not supposed to be there since it is behind the portal target. Try going to that spot in q3dm7 and see if you can see it. You shouldn’t be able to see it, instead you should see the farther away curved wall.

See: http://personal.lig.bellsouth.net/~dfrey/q3dm7_clipped.jpg

[This message has been edited by DFrey (edited 02-19-2001).]

Yeah, now I see it. I actually modified glTrace so that it only enables the clip plane if the shift key is down. The strange thing I noticed was that even with the clip plane disabled, none of the geometry extended outside of the portal. You could see it through the portal, but that’s it.

Exactly, because after all the geometry in the portal is rendered, the depth buffer is cleared, and then the portal surface is blended over it, preserving the portion of the errorneous geometry that is within the projected area of the portal, and then the rest of the scene is drawn, overwriting the portion of the erroneous geometry that is outside the projected area of the portal.

[This message has been edited by DFrey (edited 02-19-2001).]

From NVidia’s OpenGL performance FAQ:
23. Are user-defined clip planes hardware accelerated?
Yes, a number of user-defined clip planes are hardware accelerated through use of texture mapping and special hardware features.

The next paragraph in the FAQ explains that every unused texture unit buys you two hardware-accelerated clipping planes. This means that, strictly speaking, LordKronos wasn’t wrong when he stated that they use texture mapping for the portals

  • Tom

Originally posted by Tom Nuydens:
The next paragraph in the FAQ explains that every unused texture unit buys you two hardware-accelerated clipping planes. This means that, strictly speaking, LordKronos wasn’t wrong when he stated that they use texture mapping for the portals

Nice try Tom, and thanks for the defense, but when Im wrong, I guess Im wrong. That surely wasnt what I was referring to.

After extensively looking for the document I read over a year ago, I still cant seem to find it. I was thinking about it, and maybe it was an old one (when he first started Q3) where John was talking about what he PLANNED on doing in quake 3, or maybe it was even quake 2. I did find in a Quake 3 FAQ (http://www.pavenet.net/users/westmore/faq.html) this bit of info:

Previously, the engine couldn´t handle more then 1 static mirror at a time. In Q3A, multiple views can be reflected allowing to create dramatic effects such as rotating mirrors, etc. John Carmack has warned, that use of rotating mirrors will make a huge hit on the pefomance.

Two things here. First it says that quake2 had a 1 mirror limitation. This may indicate that he set aside one texture for a mirror texture. Second of all, he said that rotating mirrors in Q3 will be a huge performance hit. Im not sure what would be so huge about this unless he planned on generating textures for the reflection. Otherwise all he would have to do is build a single reflection matrix from 3 points each frame (not exactly a noticable performance hit).

So, In retrospect, I think the artice I read was either talking about the quake 2 engine (I dont have the game, so I cant confirm anything) and/or an early version of the quake 3 engine.

By the way, since it was brought up, for anyone who is curious about why clip planes use up texture units on nvidia cards, here is what I think is going on…

Think of implementing a clip plane as a 2D 2x2 texture. This 2x2 texture has a left column, a right column, a top row, and a bottom row. The left column means “clipped by clipping plane 0”, whereas the right column means “not clipped by clipping plane 0”. The bottom row means “clipped by clipping plane 1” and the top row means “not clipped by clipping plane 1”. Now, if you assign an alpha value of 1 to the top right texel, alpha values of 0 to the other 3, and enable the alpha test, any fragment that doesnt get textured with the top right texel will not be visible (ie: it will be “clipped”). Then you just use the appropriate texgen modes to select the appropriate texel based on whether or not the fragment lies in front of or behind the corresponding clip plane (ie: clip plane 0 is used to configure s-coord tex gen, and clip plane 1 configures t-coord tex gen).

Thats my take on it, and I might even be wrong (any comment matt?). Thought it might be insteresting to some, and perhaps it might even give you other ideas.

Interesting, trick for accelerating clip planes. It does give me some ideas . I wonder if the TNT does something similiar. That OpenGL performance FAQ doesn’t cover the TNT so I have no idea.

Knowing that the clipping planes burn a texture unit, I figured I’d try if I could push the driver into software by creating a Q3A map with recursive mirrors.

I couldn’t - it never actually enabled more than one mirror at a time. I don’t see any logic in how it decides which mirror to enable. Furthermore, when a mirror goes “blank”, the picture in it sort of fades out.

I’ve taken some screenshots of this, at http://www.gamedeveloper.org/delphi3d/misc/temp . The mirror*.jpg files show how only one mirror is active at a time, the fade*.jpg files show how the image in a mirror fades to black when the mirror is disabled.

I wonder if this was done on purpose to prevent the software fallback?

  • Tom

[EDIT] I did manage to get it to display two mirrors next to one another by placing a single misc_portal_surface entity between them, as shown in 2mirrors.jpg at the above URL. Strange.

[This message has been edited by Tom Nuydens (edited 02-20-2001).]

I suspect those 2 mirrors were able to work because they were in the same plane and using the same entity (so as far as the engine was concerned that describes one mirror?). I got to looking at the fading out effect, and I think that is just a bug. Try using the gauntlent while looking at the reflections of the blacked out mirrors. The resulting saturation surely was not something id desired. For the blackened mirrors, it appears the mirror routine starts to draw the mirror by blending a quad and then abruptly aborts, it appears to be the same texture that it uses at the start of rendering each one. Ironicly it also still clears the depth buffer for each mirror. Just appears some logic (with poor hysteresis) uses viewing direction and lighting to determine which mirror to complete.

[This message has been edited by DFrey (edited 02-20-2001).]

Hi!
Now I read my way through this whole mess!

Hmm…If I understand everything correctly the way Q3 does it´s mirrors is very slow and unelegant. ´Cause if I get it right you render the whole scene from the portal´s camera first and afterwards you render the whole scene again as seen from the player´s viewpoint. This means that a mirror might easily double the poly-count. And you render alot of unseen polys ´cause all those polys lying outside of the mirror-poly are never seen in the final image…

Are you really sure that Q3 does it this way?
On my machine the mirrors don´t slow down the game that much. The big mirrors yes but not the teleporters.

Greets, XBTC!

[This message has been edited by XBCT (edited 02-28-2001).]

As I see it it is more or less the ‘only way’. I guess the z-buffer clearing could be avoided if splitting up the z-buffer.

Most of the portals in Q3 are placed at locations with very little geometry, so the polygon count doesn’t get too big.

Actually map q3dm0 in front of the mirror kills my fps tremendously, something like a factor 5 compared to average framerate. All the portals render very good.

Originally posted by Tom Nuydens:
[b]Knowing that the clipping planes burn a texture unit, I figured I’d try if I could push the driver into software by creating a Q3A map with recursive mirrors.

I couldn’t - it never actually enabled more than one mirror at a time. I don’t see any logic in how it decides which mirror to enable. Furthermore, when a mirror goes “blank”, the picture in it sort of fades out.

I’ve taken some screenshots of this, at http://www.gamedeveloper.org/delphi3d/misc/temp . The mirror*.jpg files show how only one mirror is active at a time, the fade*.jpg files show how the image in a mirror fades to black when the mirror is disabled.

I wonder if this was done on purpose to prevent the software fallback?

  • Tom

[EDIT] I did manage to get it to display two mirrors next to one another by placing a single misc_portal_surface entity between them, as shown in 2mirrors.jpg at the above URL. Strange.

[This message has been edited by Tom Nuydens (edited 02-20-2001).][/b]

With the technique we have been talking about, it should not be a problem with several mirrors and with multiple itterations as long as the mirror is rendered first. So it’s starnge that Q3 does not have this feature. It would really kill performance though.

You can go to Gamasutra and listen to Brian Hook’s GDC 2000 presentation. He explains how mirrors and portals work (actually outlines the code that we have already presented above), and why they decided to make them non-recursive. Of course the presentation covers much more than just mirrors and portals.

[This message has been edited by DFrey (edited 03-01-2001).]