Can anybody explain how Bucket.Sky nodes are sorted for rendering?

Hi, I am trying to understand how Bucket.Sky nodes are sorted for rendering as it seems no matter what I do, I can’t predict which node will draw on top of the others. I also have a fear that they are not sorted using their Z position center but rather by their /volume/ which would then be a complete nightmare for the project I’m working on. If it is so, can anybody give a trick on how to achieve making one Bucket.Sky node draw on top of the other Bucket.Sky nodes BUT STILL behind everything else in the scene. Thanks.

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:jme3_renderbuckets

It’s in the order they’ve been put in the node that dictates their order.

First added = first rendered, etc.

If you want to force something like an opaque skybox to be drawn before anything else, you can do something like:

[java]someNode.attachChildAt(something, 0); // this will force adding ‘something’ to index 0, thus rendered first[/java]

1 Like

Hi @madjack, thanks for giving some explaination. I can tell you that it’s definitely not the only parameter in the sorting equation tough, because even tough I attached node-A in the sky and /then/ node-B, the node-A still shows in the front (nearer to the camera) and I also tried to reverse which node is attached fisrt but it did not change anything.

The goal is to have node-A behind node-B and keep both in the Bucket.Sky. I tried to setLocalTranslation() on node-A and play around with the Z values but only if it goes WAY WAY far like out of the frustum, then it disappears completely… which is not what we want to do here. We want it to be visible but drawn behind the node-B. I tried to setLocalTranslation() on node-B to bring it closer to the camera thinking node-A will at some point fall behind node-B, but it still draws closer to the camera no matter what :stuck_out_tongue:

EDIT: attachChildAt() either did not change anything or made one node disappear completely depending on what value I would pass to it.

Are you sure it doesn’t have some fancy thing to do with volume bounds?

It’s the way I fixed the issue I had with the sky control coupled with a sky box. Only by forcing the cubemap sky to be attached at 0 was I successful in rendering the clouds. Anywhere higher than 0 would render the cubemap above the previous layers.

Don’t forget that (afaik), Sky bucket renders everything at the farthest distance (Float.PositiveInfinity I think) or, if you prefer, it’s all rendered on the same “plane” visually. Of course if you walked through a sky-bucketed texture mesh, you would get some funky result.

But, this is only local to a single node. I’m not exactly sure how it would act when you have multiple of those mixed up.

I’d suggest dumping everything into a single node and see how that goes. From there you can guess where you want to go. It might not be possible to do that though.

Just spit-balling here. :wink:

1 Like
@madjack said: Sky bucket renders everything at the farthest distance (Float.PositiveInfinity I think)

O’RLY? So basically my question kind of doesn’t make any sense. If we assume what you’re saying is right, then everything in the Bucket.Sky simply has no depth whatsoever, therefore unless what I put in this bucket is COMPLETELY FLAT it will never work as expected. Damnit. It means I have to hack the Sky Control instead of trying to stick my node behind it… The node I want to stick behind the Sky Control is NOT flat, that’s why it wouldn’t work as expected. inb4 just bake the damn node, well… can’t do that, since it emits light dynamically.

Facepalm OK I’m f***'ed. Back to square one I guess. But thanks so much for this information I must have misread somewhere before. It was either that or it had something to do with volume bounds.

Thanks again.

Instead of baking it flat, I just had an idea, but I’m not sure if it’s viable or even possible using JME3. What about rendering my node on a transparent viewport and then add this composition as a flat node in the main viewport or something? Is that a viable route? If so, then how would one go and do that?

What is it that you are trying to render? Why do you need to render it behind the sky? (I’m not even sure what that means since the sky will fill the whole far plane.)

Hi Paul! Thank you for taking the time to reply to my thread :smiley:

Few things: First, the node-A I’m trying to render emits a light cone (SpotLight) and that’s why it can’t be flat but still needs to be behind node-B. Second, node-B is not a /sky/ and it does not fill the whole background either. That’s exactly why I need node-A to be behind node-B, because at certain angles, node-A will be visible and at other angles it won’t, because it will be hidden by node-B. As I mentionned, both nodes need to be in the Bucket.sky render queue to pin them in the /scene background/ altough they remain dyamic (colors will change, dimensions, everything…). That’s why I cannot bake node-A.

@.Ben. said: Hi Paul! Thank you for taking the time to reply to my thread :D

Few things: First, the node-A I’m trying to render emits a light cone (SpotLight) and that’s why it can’t be flat but still needs to be behind node-B. Second, node-B is not a /sky/ and it does not fill the whole background either. That’s exactly why I need node-A to be behind node-B, because at certain angles, node-A will be visible and at other angles it won’t, because it will be hidden by node-B. As I mentionned, both nodes need to be in the Bucket.sky render queue to pin them in the /scene background/ altough they remain dyamic (colors will change, dimensions, everything…). That’s why I cannot bake node-A.

A picture might explain better. Perhaps there is a different way to do what you are doing.

Sky is rendered in “order added” and it’s rendered at depth infinity, basically. You can render 3D things but there will not be zbuffer sorting between the different things.

If you need all of that then perhaps you do not really want to use the sky bucket at all. It’s sole purpose is pretty much to “render things at infinity after the opaque objects are drawn”.

Paul, if it were that simple and always rendered in “order added” then I would not even have made this thread to begin with, but it seems it’s not exactly working like this. That’s why I replied that earlier in this thread:

Hi @madjack, thanks for giving some explaination. I can tell you that it’s definitely not the only parameter in the sorting equation tough, because even tough I attached node-A in the sky and /then/ node-B, the node-A still shows in the front (nearer to the camera) and I also tried to reverse which node is attached fisrt but it did not change anything.

Then madjack pointed out that geometries in the Bucket.Sky are meant to be flat, so it defeats the whole idea of putting a SpotLight in the Bucket.Sky and I clearly see why it wouldn’t work, since SpotLight cones are not flat at all and are meant to have lots of volume. That’s why I thought about rendering it apart like in another transparent viewport or something and then splat it in the main viewport or something, I just don’t know how to go about with this.

Here is a picture of the problem described in this thread. Node-A is the spotlight, Node-B is the GRASS BAND (not the sky!)

As you can see, I don’t want the SpotLight to be visible when under the horizon (under Node-B, the grass band)

What happens if you attach node A before Node B to the scenegraph?

I see you TLDR;'ed the whole thread and the post right before yours too, @zzuegg, but again: it did not change anything to attach it before or after Node-B. Nada. It’s exactly the same, probably because it’s a light and not a geometry I guess.

EDIT: And for next TLDR;'ers I already tried setLocalTranslation() on both nodes, it did not change anything, except for if Node-A is very very far away, then it disappears completely due to frustum out of bounds. I also tried the attachChildAt(node, 0); trick which didn’t change anything, except for some tests I did with higher values, it made the node disappear.

Ah, sorry, didn’t get that you are actually adding a spot light. I actually didn’t even know that a spotlight creates something visible.
I guess the common way of dooing it is to add a quad with a sun texture to the sky and use a directional light for the actual scene lighting…

As stated earlier in this thread, I cannot bake it to a quad texture, because it changes color, dimensions, etc… like the halos are very difficult to mimic for ever hour of the day) but I am more interested in a more rare approach that would consist of rendering this spotlight in another transparent viewport and then splatting it in the main viewport, not sure I’m expressing my idea with the correct technical terms, tough. It’s like rendering it aside and fuse the 2 viewports together or even apply that spotlight viewport as a texture in a quad in the main viewport, is that possible?

It’s possible to render a separate viewport first and then use that rending as texture. I know some guy’s do that for their gui stuff.
https://code.google.com/p/jmonkeyengine/source/browse/branches/jme3/src/test/jme3test/post/TestRenderToTexture.java?r=6417
But still:

  1. changes in dimension could be easily done in a control
  2. changes in color could be done in a shader controlled by the same control
1 Like

I understand it would be /possible/ using only one viewport, but it’s easier said than done, especially for me. I’m not very maths and shader savvy at the moment, but I’m willing to learn… I’m just not there yet tough. I’m making progress day after day. I’ve only been learning JME3 part time for 2 months now.

The halos would indeed be the hardest part to bake in a quad, but I’m VERY interested in rendering a viewport in another viewport’s textured quad, that would completely solve this WHOLE thread and AS A BONUS: I could even only render it once every so often like once a second or something to save some framerate! VERY interesting! Thx for the link I’ll check it out right now. This looks like the perfect maths/shader-lazy technique and I also see future things I could use this technique for. +1 for you. I’ll post this new technique’s results here. Looks promising in my situation :smiley: Thx again @zzuegg.

EDIT: Actually, the link you provided has very outdated code and I couldn’t make it work properly, but this one is newer and works as-is perfectly: http://jmonkeyengine.googlecode.com/svn/trunk/engine/src/test/jme3test/post/TestRenderToTexture.java

TL;DR for me too, but as madjack stated anything in the sky bucket is rendered with a depth of 1.0 (the depth buffer goes from 0 to 1, 1 being the farthest away).
The geometries are not sorted in the sky bucket, so they are rendered in the order they appear in the queue (which is not guaranteed to be the order in which you inserted them).
But you can specify your own GeometryComparator for the sky bucket and pretty much control the order things are rendered.
[java]
viewPort.getQueue().setGeometryComparator(RenderQueue.Bucket.Sky, new WhatEverGeometryComparator());
[/java]

1 Like
@nehon said:(which is not guaranteed to be the order in which you inserted them).

Then why provide attachChildAt(thing, atIndex) then if there is no guarantee it’ll be rendered in that order? I’ve -never- seen my sky fail to render behind everything. (I specifically use attachChildAt(thing, 0))

@madjack I think it’s just a coincidence it has always worked in your project. Also are your nodes SpotLights? I think this is specifically why my situation doesn’t work out like yours using the attachChildAt(thing,0)) trick.

@nehon Altough I’m currently trying @zzuegg 's trick, I’ll duplicate my project folder and try yours immediately, because it sounds way simpler than splitting on a second viewport just for my SpotLight. BUT the viewport offline rendering is so cool, I see so many uses for it in the future! :stuck_out_tongue: