Rendering multiple Unreal-style skyboxes in a scene

Just wondering if anyone has any ideas on how to render multiple Unreal-style skyboxes at once without having them interfere with each other… The skyboxes may or may not be visible at the same time, too.

Right now I’m thinking about using the stencil buffer to do it, but I’d like to avoid the stencil buffer if at all possible for compatibility reasons…

I wouldn’t worry about someone not having stencil support. All cards now have it and all cards from 4 or more years ago had it. At least the important ones, like nvidia, ati, matrox (i think), etc. But anyway, I don’t remember what the skys looked like in Unreal since it’s been a long time since I have played it, but I think I may know what you’re wanting. I think the effect is that it looks like multiple layers of “sky” is moving around with some parts of layers transparent to see the other layers. All you would need to do in this case is just render one skybox geometry but use multitexturing with alpha blending to get this desired effect. If this is not how Unreal does it please correct me.

-SirKnight

In Unreal, you could set up a camera on the map that would be the skybox camera. Then, the skybox is drawn from that vp (taking into account the users orientation, of course). Made for some damn cool effects.

The problem is, I’m doing the OpenGL port of ZDoom and it has support for more than one skybox like that. In fact, one demo map has 4 (with 3 visible at once)… Along with the normal sky, too. Of course, this is a much simpler problem with a software engine, so I’m at a bit of a loss here =/

The reason I want to avoid the stencil buffer is there are still quite a few people who have Voodoo3’s that use ZDoomGL, and I want to avoid driving them away. I’m sure they wouldn’t mind that skyboxes don’t work the way the software engine does, but I at least want to make an effort to include them

Oh you’re doing it for a doom port and not for your own 3d engine. I see. Well does Unreal Tourney have this same effect? If so ill load that up and look for myself at what it’s doing. I dont have unreal installed so maybe I could get some screenshots somewhere so I can see exactly what’s going on.

-SirKnight

I think Unreal can only have one skybox in the map, but I’m not sure about that…

If you can render the portal skies before world geometry, then you can:

  1. clear the zbuffer to the far value
  2. set depth range to be something like 0.75 to 1 for the first sky, and 0.5 to 0.75 for the second, and so on. Use normal depth comparisons.
  3. after rendering any one portal sky, render all of its portals with color writing disabled and depth test disabled but depth writing enabled and depth range 0 to 0
  4. clear the z-buffer to far value and render the rest of your scene as normal.

You can get rid of the loss in z precision if you do a z-clear after rendering each portal sky but before rendering the portal surface polygons, at the expense of some additional z clears. You can also get rid of the code to force the z values for the last portal sky to be 0, since you will clear them to the far plane immediately afterward.

This doesn’t use the stencil buffer, but it does use some extra fill rate for the additional z-clears, and it does require you to be able to draw your sky geometry first.

Havn’t played Unreal, but idea is intresting.
Hmm, multitexturing skybox? You mean tex0 would be static & others should move? I think there will be “small” problem at all edges.
BTW, skybox is slow as **** on my GF2GTS with one texture, can’t imagine what will happen on Voodoos.

Why do think skybox is slow?
The only disadvantage of skybox is fillrate, but you can also subpartition 6 sides of your skybox into say 6x6 quads to speed up things. I tried this in my engine and it worked very fast on my old voodoo2.

Skyboxes used to be as fast as clearing the frame buffer, but these days, some hardware accelerates clearing so it’s faster than drawing over the framebuffer with a skybox.

Anyway, at work we sometimes fade between skies when you walk between areas. We do this by drawing the new sky on top of the old sky with alpha blending, fading the alpha from 0 to 1. Apart from the fill rate hit, there is no special magic to doing this; each sky is drawn centered on the camera but rotated according to viewing direction, and it all just works.

Originally posted by MickeyMouse:
Why do think skybox is slow?
The only disadvantage of skybox is fillrate, but you can also subpartition 6 sides of your skybox into say 6x6 quads to speed up things. I tried this in my engine and it worked very fast on my old voodoo2.

Pardon my lack of understanding but why does subpartitioning into smaller quads speed things up? Isn’t fill rate just linked to the number of texels that are drawn over?

Originally posted by rgpc:
Isn’t fill rate just linked to the number of texels that are drawn over?

??? No , you probably meant number of pixels that are drawn, number of texels drawn should have actually no influence on overall speed…
Subpartitioning skybox helps a bit (not sure if it’s really worth an effort though) because when you look through the window which is very small you’ll display only few subquads of skybox that are visible, thus rendering less pixels.
In my case it was sometimes significantly faster since skyboxes could reflect many times in mirrors. If you’re interested in seeing it working come here http://rainbow.mimuw.edu.pl/~ms189438/3d/Features.php

[This message has been edited by MickeyMouse (edited 01-30-2003).]

Originally posted by MickeyMouse:
??? No , you probably meant number of pixels that are drawn,

Der, yes I did mean pixels… (Damn keyboard is upside down…

Her is my solution to the problem. Just after having cleared the screen buffer:

  • draw in the zbuffer polygon(s) where the sky should appear (ie: draw the windows through which you should see the sky)
  • set ztest to greater (not >=)
  • draw sky
  • draw polygons to “clear” the zbuffer where required
  • loop until no more sky
  • set z testing to <=, or whatever your normal mode is.
  • draw the rest of the world

That seems like a lot of work to save a little bit of write rate. You still have to test every pixel on the screen, so it’s not THAT much faster.

I’d rather just sort near to far, and draw the skybox last, with a >= test for close to the maximum depth value, and/or adjust it with glDepthRange(). On modern hardware, this saves at least the same amount of work, and is simpler.