Game Development Community

NewbieQ: scene render order

by Rob Rendell · in Torque Game Engine · 02/27/2005 (3:30 pm) · 6 replies

(Sorry about the first attempt at this thread - hit CR when the text area didn't have focus, and it posted an empty message ):

So, I'm playing around with the new shiny toy that is Torque, and I'm trying to define a new C++ class that renders after the sky but before the terrain. According to the docs, the render order is:
Sky
BeginSort
Terrain
Normal
Point
Plane
EndSort
So, SceneRenderImage::BeginSort looks ideal. However, despite setting up a SceneRenderImage in prepRenderImage like so:
...
if (state->isObjectRendered(this))
{
    SceneRenderImage* image = new SceneRenderImage;
    image->obj = this;
    image->isTranslucent = true;
    image->sortType = SceneRenderImage::BeginSort;
    state->insertRenderImage(image);
}

my object is rendering over the top of the terrain, as well as various buildings, trees etc.

So, I'm assuming I have some fundamental misunderstanding about how this all works. I'm a total newbie with OpenGL, though an experienced programmer in general. Torque's rendering presumably either works using a z-buffer, or by using the painter's algorithm. Since you could supply the sortType parameter, I'd assumed it was the painter's algorithm. However, there's obviously something more going on...

In investigating this, I stuck some Con::printf()s throughout the render sequence, and I see that the terrain is actually being rendered before the fxSunLight object (which is the example I'm looking at for a render-after-sky-and-before-terrain object). So, that implies some sort of z-buffer.

Can someone help me clear up my misconceptions? Thanks!

About the author

Recent Threads

  • Animated textures

  • #1
    02/27/2005 (4:07 pm)
    What are your results when trying to use EndSort? Curious if its actually backwards.
    #2
    02/27/2005 (6:19 pm)
    Interesting thought. . No, it looks identical :-/

    Digging into the source of insertRenderImage in engine/sceheGraph/sceneState.cc, it appears odd... all things that register themselves as non-transparent are stored in one list, sorted by (the numerical value of) their sortType. Things that claim to be transparent go into one of four other lists, one each for Plane, Point, BeginSort and EndSort. However, when it actually comes to rendering, everything from the non-translucent list is rendered first, then the things in the BeginSort list, then the Plane and Point lists are rendered in BSP-sorted order, and finally the EndSort things are rendered.

    So, by that, I'd say it was buggy, and translucent BeginSort things will always go in front of the terrain as I'm observing with my object, except that I've seen the fxSunLight object (which claims to be translucent and BeginSort) go behind the terrain...

    I can see one way to work around it. I could claim that my translucent object is in fact not, and change fxSunLight to also be non-translucent, and so they all go into the mRenderImages list together. By changing the enum of sortTypes so BeginSort occurs numerically between Sky and Terrain, it would work. Except that this is obviously unnecessary when the fxSunLight is somehow able to work while still saying it's translucent.

    All rather confusing really.
    #3
    02/27/2005 (6:44 pm)
    BTW, I've been coy about saying what my object is, and it may help to understand what I'm trying to do: I've pulled the cloud code out of the sky.cc object, and defined a new fxCloudLayer object that does a single cloud layer. Hence the desire to render below the skybox, but above (behind) the terrain.

    Why am I doing this? Well, the initial impetus was because I've been playing around with fxSunLight to allow me to have a moon texture on it which orients correctly based on the camera's viewpoint (the standard fxSunLight just draws the billboard in the same orientation independant of the camera's position, which looks odd when you look up at the moon directly overhead and start spinning...) and which does the moon phase sweeping across the moon's surface. However, because the skybox is rendered in one hit, there was no way to get the fxSunLight objects to render below the skybox, but above the cloud layer - the moon appeared below the clouds. While that's not generally noticeable for a sunlight, it was glaringly obvious with a moon, especially one with a substantial umbra... the half-moon doesn't cover up the clouds with a full circle; the dark half is generally almost undetectable because it's the same colour as the sky and behind the clouds.

    There are other advantages to a stand-alone clould layer object. You can have more than three. You can more easily change them in-game using script (the skybox doesn't allow for changing the cloud textures via script, as far as I can see). I've also had thoughts about other features I can add, like folding in Josef Jahn's fractal cloud resource into it. I could release this as a new resource (with due acknowledgement to Josef Jahn, natch), and it would be simpler than the existing resource, because instead of being a patch on a file in the repository that might change and break the patch, it becomes a stand-alone drop-in object that you can just add to your project.

    Anyway, grand plans are all very well, but right now I'm now stuck on this rendering issue.
    #4
    02/28/2005 (1:04 am)
    Why not simply not register it as an OPAQUE object? Transparency is just a hint to help do proper sorting; for this where you already know the order and can enforce it, nothing needs to know you're drawing transparently. Just draw whatever is appropriate and go on your way. :)
    #5
    02/28/2005 (1:06 am)
    While I dont have any answers for you at the moment about the sorting problem I would just like to say that I think an fxCloudLayer object sounds like a great idea. Just this past weekend I was re-implementing a lightning effect from another engine wherein the clouds near the lightning strike light up as the lightning strikes.

    The effect is fairly simple, just a camera facing billboard which is top capped with another billboard for the cloud effect. However with something like an fxCloudLayer I could take this even further with more convincing results.
    #6
    03/01/2005 (6:06 pm)
    @Ben, it's a good idea. However, to make that change, I needed to change the SortType enum in sceneGraph/sceneState.h, because BeginSort occurs at the end of the enum, and non-translucent objects are sorted by the numeric value of their sortType. I was a bit worried, because the first three values of the SortType enum are given explicit values of 0, 1 and 2, so I wasn't sure if I would break anything by removing the 1 and 2 and inserting a new value. I didn't notice anything going horribly wrong, though, and after making that change, the clouds were rendered behind the terrain, as they should be.

    Unfortunately, the fxSunLight object registers itself as translucent, which means fxSunLights render after opaque objects. So, I was back to having the moon in front of the clouds again, which was the problem I was having that made me start writing the fxCloudLayer object in the first place :).

    I modified the fxSunLight object to not be translucent, and that worked... except that I started getting strange effects where the moon vanishes or appears really dim from certain angles. I'm wondering if it's vanishing behind the skybox. Not sure if this may be one of the side-effects I was worried about when I changed the numeric values of the second and third SortType enum values...

    Nothing's ever simple, is it? :)

    Also, I'm patching lots of other files to get working what I was hoping would be a drop-in object... and it's not working 100% in any case, since the moon keeps vanishing.

    Mind you, most other people probably don't have a moon object, and rendering the sun in front of the clouds isn't noticeably different from it shining through them, so it's probably already useful to other people.

    @Robert, thanks for the encouragement. Your lightning glow sounds like a cool effect, too. I'll definitely post my object as a resource, but I'd like to get at least the render order issues solved to my satisfaction first.

    The thing that gets me about all this is that the fxSunLight object already does exactly what I want, being both translucent and rendering behind the terrain. If it wasn't for that, I'd say from my reading of the code that it can't be done, give up on doing it any better way, and just go with making it opaque and hacking sceneState.h... but obviously it can be done without doing that. Maybe I should email Melvin May and ask him how he did it...

    BTW, I put in Joseph Jahn's fractal cloud code, but it didn't work for me... so I re-wrote the fractal generation code into the good old plasma algorithm :) The fractal clouds look quite decent. However, I've been reading about Perlin noise, which seems rather more cool than plasmas, so I'm just about to do a Perlin noise function and have a stab at generating fractal clouds that can potentially roil over time.