Fading in large, complex objects

Started by
8 comments, last by swiftcoder 12 years, 4 months ago
Hey everyone,

I am making a game in which I need very large (e.g. building sized) complex objects to appear in a scene by fading in from completely transparent to complete opaque.

The obvious way would be to simply enable GL_BLEND, etc. and then do glColor4f(1.0f, 1.0f, 1.0f, n) on each frame where 'n' is ramped up from 0.0f to 1.0f before drawing the object. The problem with this method is that it is possible to see some of the "insides" of the object as it fades in, which looks weird.

Instead, I thought of a method using an off screen buffer instead (render to texture):

1. Render my scene without the object.
2. Clear the off-screen buffer to transparent.
3. Copy the Z-buffer of the scene to the off-screen buffer.
4. Render the object fully opaque in the off-screen buffer.
5. Set desired fade-in transparency (e.g. glColor4f, as above).
6. Render the off-screen buffer as a (transparent) rectangle texture over the scene.

If I wanted to fade in multilpe large objects with different fade times, I could simply repeat steps 2, 4, 5 and 6 for each object (step 3 is not necessary, since the Z-buffer is already contains correct data from the previous object).

Is this a good approach to fading in an object with regards to performance? Are there any GPU's that this would be better or worse on (I only have access to Geforce 8600)? Are there any better ways to accomplish the same effect?

I am hoping the performance will be better than the obvious method, since I am rendering my complex object fully opaque rather than rendering all the geometry using GL_BLEND. Is this likely to be the case? Step 3 is my main worry in this method - is copying the Z-buffer an expensive operation? If so, maybe it's possible to make my off-screen buffer point to the same Z-buffer as the screen, to make step 3 unnecessary?

Any advice on this matter is appreciated!

Cheers,
Martin
Advertisement
Order the polygons in your building by lowest height from the ground.

When rendering buildings in progress, disable face-culling.

Render the first N polygons in your building, where N ramps up between 0 and 100%...

You could extend this to rendering the next M (where M is maybe 5 or 10% of the building's total count) as outline. That way you'd get a frame/filling in effect.
Thank you for the interesting suggestion. That would actually be a pretty cool transition.

However, I must stick with the transparent fade-in transition - this is a non-negotiable requirement of the project I'm working on - so I'm not really looking for alternative suggestions for the transition effect.

Maybe I will just have to try it for myself and see how it works. I was just hoping that someone with more knowledge/experience than I would be able to advise me before I spent a lot of time on something that could potentially fail or perform too slow.

Of course, I don't expect anyone to do the work for me; I just thought someone might have already tried this and could share experience. :)
I'm not sure whether this would suit the situation, but could you use a billboard impostor? Have just a static image of the fully opaque building rendered on a quad the size of the building, then simply fade the quad. Then when the fade reaches 100% opaque, simply switch the billboard with the full model. If you are close enough to the building for this effect to have obvious flatness, maybe have a special fade model that only has the outside of the building that you fade? Again, that might have quality issues, but I'd imagine it be easier than all the steps you mentioned.

Quick recap of suggestion:
  • Use a pre-rendered image of the side you see of the building as a texture map on a static billboard in place of the building
  • Fade the billboard's alpha in
  • Replace billboard with final model

OR
  • Use a special model that only contains the outsides of the building (using back-face culling to remove the sides you don't see)
  • Fade that model in
  • Replace with full model

I'm still new with all this, so I'm not sure if its at all feasible, but that's how I would approach the problem.
Thanks for the suggestion, but my feeling is that this would not work.

The reason is that my complex objects are not simply buildings; they are much more complex objects that are the size of buildings.

To explain in more detail, in the game, you cannot see any place that you have not yet explored (rectangular areas). When you explore a rectangular area, everything in the rectangular area is the complex "object" that fades in. I have a video of the game so you can see what I mean (using the obvious but flawed GL_BLEND and glColor4f method).
The problem with this method is that it is possible to see some of the "insides" of the object as it fades in, which looks weird.[/quote]
So the insides are different objects? Like a building that holds desks?

If so, then you need to just have the building own ALL objects inside it and set ALL children objects to the same glColor4f().

In the video, I didn't see anything like what you said in your original problem. What exactly faded in too quick? New areas faded in, with 1/2 a second. Did a certain block come in too fast?

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal


So the insides are different objects? Like a building that holds desks?

If so, then you need to just have the building own ALL objects inside it and set ALL children objects to the same glColor4f().

The problem with doing this is that you can still see the (transparent) desks inside the transparent building during the fade-in. This is what I want to prevent.

In my case, it is the walls and platforms behind the other walls and platforms that I do not want to be visible.

Try to think of it like teleportation in sci-fi TV shows where the person fades in (e.g. Star Trek). You see the person gradually appear, but you don't see all the transparent insides of the person's body during the fade-in. It's more like you see a "picture" of the person fading in, rather than a transparent 3D person fading in.

I realise that the problem is somewhat difficult to see in the video because of the low quality of the video; I only intend for the video to illustrate what I'm doing.

Another approach I can think of is to order the polygons to be drawn front-to-back, so the depth buffer would take care of not drawing things behind, but I think this would be even more work than my original idea given that the camera can freely rotate during the fade-in transition, which means the order of the polygons could potentially change in every frame, which would result in a lot of sorting.

EDIT: All of these alternative suggestions are leading me to assume that their are problem(s) with my idea. Yet, no-one has explained what the problem(s) are (e.g. why I need an alternative solution).

Would someone care to provide an explanation?
I'm no expert, and I followed this thread mostly to see if there would surface any nice hints here.

But from the options listed so far, your original general approach seems to me to be closest to the best.

All the others would have problems with too much being drawn, making it not really look like you want it to.
(If you have a complex object, I don't think you can sort the polygons so you guarantee no overlap)

That also means you draw less, wich generally is a good idea for performance :)

I also imagine blending one big rectangle in one pass is more efficient then blending a bunch of small polygons

I think you can share depth buffers using FBOs, but I have never tried it.
I see, well then I would just turn on fog for objects that are that far away and no fog for objects that you already can see or have traveled. That will get rid of your blending problem as long as your background is going to remain a solid color that you can make fog the same exact color.

It sounds more like fog than transparency that you want because, transparency means your building will basically be an x-ray and you can see everything in it.

The other option would be to:

1.) Render stuff you are allowed to see without any fading.
2.) Turn of color writing and only write depth for fade objects.
3.) Set Depth testing to GL_EQUAL
4.) Re-Render the faded objects but turn on color writing again.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

The normal solution to this problem is billboarded impostors. You render the object to a texture, and then when you render the scene, you add a quad with the texture, and you alpha-blend that quad.

However, billboards are a little cranky with respect to depth testing against adjacent objects. My feeling is that your tiles overlap too much (in screen space) for this to be very feasible - your original solution with an attached depth-buffer and proper depth-aware compositing would likely work better.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

This topic is closed to new replies.

Advertisement