Lighting/Renderworld question

Blitz3D Forums/Blitz3D Programming/Lighting/Renderworld question

Axel Wheeler(Posted 2013) [#1]
Hi there.

So, I have a planet that is not really as big as it looks; to keep it within the default 1-1000 unit camera range, I've reduced it in size and use EntityOrder to put it in front of the skybox and behind the space ships. So far, so good.

The problem is, it reflects the light coming from the exploding ships, which, while cool looking, is highly inaccurate.

I have discovered that I can actually make the planet full size (I mean, actual size as in 1 meter/blitz unit!) if I want, and adjust the camera range accordingly. This would require three separate renders; one for the skybox, one for the planet, and one for everything else.

Or, I can leave the planet where it is and not bother with the camera range, and just turn off the explosion lights during the planet render. Still multiple renders, just a different trick being employed.

A. Which of these is better, or will actually work?

B. Is there another option I haven't though of?

Here is the newest demo. You'll see the planet is much improved with more colors and general richness. Press Enter to generate a new one.

Thanks!


Kryzon(Posted 2013) [#2]
Set the planet to use the FullBright and Vertex-Color FXs, then light your planet manually*.

* You can try LightMesh, but I think setting each vertice's colors manually with some algorithm of your choice may look better, as you might be able to use some coloring effects in your code (according to the sun's position etc.).
Note doing this should be very slow, so you'd light the planet as soon as you created it, then you'd leave it colored like that.


Axel Wheeler(Posted 2013) [#3]
Thanks for the response.

I should mention that the planet rotates, so it needs to reflect the sunlight naturally. Fullbright would prevent that. I like where your head is at, though!

(Actually it rotates unusually fast currently so I can see all of it. Forgot to mention that. Normally it's slower)


Kryzon(Posted 2013) [#4]
Sure, off the top of my head: try layering meshes, all full-bright but educatedly colored.



Your original planet (#2), with a dark overlay mesh (#1) and highlight overlay mesh (#3).
The dark and light overlay meshes should have the Multiply and Add EntityBlend values respectively (default entityblend mode is Alpha, and it wouldn't work for this effect).
You can smoothly fade part of these overlay meshes with vertex-alpha, since they'll be full-bright and won't be receiving light.

The idea is that the original planet spins normally, but these overlay meshes blend whatever detail passes through them.


Bobysait(Posted 2013) [#5]
You can also use multiple rendering pass if you set the ClsMode of the camera and use clever pivots

It's as fast as only one renderworld (or almost as fast)

------------------------------------------
- how to :
------------------------------------------
If we don't clear the Color buffer, the pixels remains (which is actually the desired effet) but the take care to clear the depth buffer !
else you 'll have some undesired entities from Far space drawn front of some objects on earth

(it's due to the pixel compare function that compares a "depth" which actually is not the "real" depth, but the depth according to the camera range.
for ex : a cube at 10 meters from camera -> Depth = 10/1.0 = 10
a planet at 5 000 000 from camera : 5 000 000 / 1000 000 = 5
the planet is front.)

So, Clear the depth buffer on each rendering pass !

------------------------------------------


Then, the process :

+ create a pivot for each "degree" of rendering (space-sky-earth-[micro?])
+ use some const to deal with the scales (and remember that, even if we can use large float number, the precision will be lost at some range (probably a very big range, but anyway))
+ when you create something, attach it to the good pivot (a tree is parented to earth, a planet is parented to the space, a cloud is parented to the sky ...etc ...)

for rendering :
1 - Hide all layer's pivots and show the space's one
-> Set the clsmode to clear everything (as it's the first rendering, it needs to clear the previous frame)
-> render the world
2 - hide everything but the next step pivot (in this case, it's the sky pivot)
-> set clsmode to clear the depth buffer but not the color buffer
-> render the world
3 - hide everything [.....] etc ... (same as the second pass with the next pivot)

4- .... do the same for each rendering depth you need.





[EDIT]
A small SDK to create render pass
(I added a funny Inverse fog on the really neay range, that fake ambient oclusion of the "player" when near from the cube or anything)

And a more colorfull sky using the vertex color of the mesh




Rroff(Posted 2013) [#6]
I'd seriously reccomend using something like Bobysait suggested rather than trying to hack it up by other methods.

Depending on how your world is setup you can either hide/show groups for the rendering or use a small section outside of the main world and render a camera from there first then do a second render without clearing the color buffer from where the actual player's eye is.


Captain Wicker (crazy hillbilly)(Posted 2013) [#7]
Axel Wheeler: Search the forums for a program called "planet creator". I believe it is open source and is written in BlitzMax + miniB3D (Blitz3D). could have what you are looking for..


Axel Wheeler(Posted 2013) [#8]
You guys are awesome! I work weekends and don't have time to digest this right now, but hopefully I'll get a chance in the morning...

Thanks all!


Kryzon(Posted 2013) [#9]
@Bobysait: how would you work out letting the player\ships come near those planets, or even enter their atmostphere, land etc?


Bobysait(Posted 2013) [#10]
At the moment they are reaaaaally far from the planet, I don't think Axel was trying to make them landing.

The method here is just to separate the different background at different scale.
If you want a ship to land on a planet, then it means the planet is not that far, but its size would be so large when the ship will come close to the planet, that the float won't enable a good precision for this kind of thing unless you rescale the planet to something descent, but inappropriate for a "planet"
So maybe, if we want this kind of thing, you need a Spore-like system.

-> the zoom out effect when you live a planet and come to a universe scaling.
Everything is just resized.


I'm testing a system where the global pivots are suitable for this kind of purpose.
I'll post it soon.


ZJP(Posted 2013) [#11]
Salut Boby )


JP972


_PJ_(Posted 2013) [#12]

how would you work out letting the player\ships come near those planets, or even enter their atmostphere, land etc?

I like the Eve-Online method for this. Adjusting scale factors depending on the precision required.

While in orbit and around a few thousand kilometres from the planet, the planet and maybe its moons can be "attached" to the Skybox as described in this thread - yet when approaching the planet, the scale is altered and LOD changes reflect this:
The Planet and (Moons?) become Meshes, the Star may be attached to the Skybox.
Small MESH Objects still in orbit can be freed, but if they still need referencing, stick a Sprite (or flat quad) if they still need to be visible, or just a Pivot to the relevant Skybox position.
Clouds/atmosphere etc. can be realised.

By committing these changes through careful use of Hiding then Freeing entities and 'Loading' then Showing (or Swapping) the entities this can be achieved smoothly and, even masked (as with Eve) via the use of a "Warp Drive" effect so it's not so obvious as things are popping into and out of existance.
With the descent to a planet's surface, this 'masking effect' can be achieved with something like atmospheric burn-up or 'ploughing through cloud layers' provided of course that the planet has an atmosphere.

Regardless of the approach, it's pretty unfeasible to have a consistent and comprehensive single-scaled planetary system. Just modelling the Earth, Moon and Sun to scales of size and distance can stretch the floating point arithmetic and rendering capabilities.
Every space game or simulation in existence has always had a procedure for either altering scale or occluding via "rooms" (consider X games where each 'sector' in the universe had to be reached via a "gate" - effectively the same as a door between adjacent rooms which allowed specific point-to-point travel with no visibility through)


Axel Wheeler(Posted 2013) [#13]
Ok I can update you on this:

Based on Bobysait's comment I basically went with a modified form of my first option; that is, the spinning planet is full size and distance and is rendered in the same Renderworld as the skybox, but it's entity order is later (closer) so one render takes care of skybox, planet, and stars (which are EntityCopies of the same quad set to different colors).

The second render is standard 1-1000 range and takes care of everything that travels. This is working fine so far.

This is most similar to Bobysait's solution except that he suggests using a system to hide the near entities during the far render and vice versa.

This would be a burden since near objects also include things like fragments of broken ships and particles of various kinds (bullets, etc.). Add to this the fact that I am sometimes parenting and unparenting the various objects to other things during a given frame, so there is overhead in making sure everything ends up parented to a "hideme" pivot for rendering purposes. Doable, of course, but I wondered what the time saved would really be. I wrote a test. Long story short, it turns out that hiding the entities would save a little time, but most of the time saved is due to them being out of sight (i.e. in front of the camera range). I guess the difference is because if they are hidden the system dismisses them faster than having to calculate their distance and do a test.

So the lesson is, if I scale up the number of nearby objects, I should consider hiding them during the far render to save a bit of extra time. (Of course there's no need to hide the far objects during the near render; there aren't enough of them to make a noticeable time difference.)




Bobysait(Posted 2013) [#14]
The stuff behind the "global pivots" is a bit more complicated.

When you call "renderworld", the entities are drawn according to the hierarchy.
Just imagine that blitz use a kind of Linked-List for the "root" entities, and all the other entities are accessibles only with the hierarchy
relative to those roots. so when the renderworld is called, it first loops the Root-entities and for each root, it performs a simple
"If Show=true Then render children"

if we made this in blitz it would/could(/should?) looks like this
Type Entity
   field bbEntity ; the blitz entity
   field nextentity.Entity ; the next entity in the hierarchy (the next "child")
   field preventity.Entity ; the previous (for doubly-linked list)
   field parent.Entity ; the parent ^^
   field firstchild.Entity ; the first child of this entity
   field lastchild.Entity ; and the last one.
   
   field Mat.Matrix ; the global 4*3 matrix (blitz3d use more than just a 4*3 matrix, it can be seen in the memory, where we find offsets for quaternions, position, scale, origin etc ... but let's simplify this with a single 4*3 matrix)
   field show ; a boolean value true/false (des/activated with Hide/ShowEntity)
   field .... all the entity stuff (class, flags, associated/derived objects etc ...)
End type


Type RootEntity
   Field entity.Entity
End Type

Type Camera
   Field entity.Entity
   Field frustum.Frustum
   Field ProjMat.Matrix
   Field ModelViewMat.Matrix
End type

Function RenderWorld()
  For camera= Each Camera
      if camera\Projmode>0
         if camera\show=true
            For Root = Each RootEntity
                RenderEntity Root\Entity, Camera
            Next
         endif
      endif
  Next
End Function


Function RenderEntity(entity.Entity,camera.Camera)
   If Entity\Show=false then Return
   ; Else performs a frustum test with the bounding box if the entity is a "renderable" class
   Select EntityClass(entity\bbEntity)
       case "Mesh"
          If EntityInFrustum(entity,camera\Frustum)
            RenderMesh(entity)
          Endif
       case "Terrain"
          If EntityInFrustum(entity,camera\Frustum)
            RenderTerrain(entity)
          Endif
       case "Sprite", .... 
          If EntityInFrustum(entity,camera\Frustum)
            RenderSprite(entity)
          Endif
   End Select
   
   ; finally, call the renderentity on each child (recursively)
   child = entity\firstChild
   while child<>null
      RenderEntity(child,camera)
      child=child\nextentity
   wend
End function



So, when you have a simple pivot containing all entities for a layer (like the background vs foreground layers), the renderworld
will only perform one : "If Backgroundpivot\show = false then Return" (it's not exactly what is involved, but it's almost the same)
When you don't hide the "root pivot", the renderworld will perform the "If Show = true/False" and as it is not hidden, it will check
for each children (recursively) the frustum check ("EntityInView Test") and some other internal stuff
Then, if you manage a lot of entities (like sprites for fake-stars or things like this) on a layer, then, just think you'll render
the layer twice

Of course, if there is only two planets (less than 10 entities) it saves ... 0.001 ms (?) which is not noticable ...

One other point to check is that, some machines are lower on rendering lots of triangles as it really depends on both cpu AND gpu
- with a good cpu and bad graphics card, rendering many entities won't be a big deal unless each entities is made of lots of polygons :
and as you ask the graphics card to render them twice it will be twice lower.
- with a bad cpu and a good graphics card, you can go for two or three or more renderworld without problems, but the framerate will decrease with more entities.

So, in both cases, hiding the pivot you don't nead to render on the current rendering pass will prevent users with low cpu or low gpu (or both) from drastic slowdown.

and of course, it's required only if you envisage to broadcast your app/game(s)



Hope it's not too confused, but I think this post can maybe help people to understand what is involved in almost graphics engines based on hierarchy
and then why some codes are slow or not depending on the computers that run them


Axel Wheeler(Posted 2013) [#15]
Yes, Bobysait, that is extremely useful information. Thanks!