Controlling the rendering order

To be able to render with good performance and display effects like transparency correctly, Panda3D automatically sorts the scene geometry and puts it into "cull bins", so vertices that share the same texture, for example, are sent to the graphics card in one batch.

Panda3D allows you to change the rendering order manually, to achieve custom scene sorting, which is what you will learn in this recipe.

Getting ready

This recipe requires the base code created in Setting up the game structure found in Chapter 1, to which the following sample code will be added.

How to do it...

Let's get started with this recipe's tasks:

  1. Add the following code to Application.py:
    from direct.showbase.ShowBase import ShowBase
    from direct.actor.Actor import Actor
    class Application(ShowBase):
    def __init__(self):
    ShowBase.__init__(self)
    self.panda = Actor("panda", {"walk": "panda-walk"})
    self.panda.reparentTo(render)
    self.panda.loop("walk")
    self.panda.setBin("fixed", 40, 0)
    self.teapot = loader.loadModel("teapot")
    self.teapot.reparentTo(render)
    self.teapot.setBin("fixed", 40, 1)
    self.teapot.setDepthTest(False)
    self.teapot.setDepthWrite(False)
    self.smiley = loader.loadModel("smiley")
    self.smiley.reparentTo(render)
    self.smiley.setPos(0, 50, 6)
    self.smiley.setScale(30)
    self.smiley.setBin("background", 10)
    self.smiley.setDepthTest(False)
    self.smiley.setDepthWrite(False)
    self.cam.setPos(0, -30, 6)
    
  2. Start the application using the F6 key to see the following scene:
How to do it...

How it works...

The quintessential parts of this recipe are the highlighted lines in the sample code. The setBin() method adds the affected scene node to the specified cull bin. The panda and the teapot are added to the"fixed" bin, which is rendered in the order given by the third parameter. To illustrate the results of manually ordering scene objects, we turned off depth writes and depth testing for the teapot. Normally, the teapot would appear between the panda's feet, but using the third parameter we force the panda to be drawn first, followed by the teapot. Because we do not use the depth buffer for rendering the teapot and we requested that drawing order, the teapot is drawn in front of the panda.

The same principle applies to the"background" bin. With a priority value of 10 it is drawn before the"fixed" bin, which causes the smiley to be overdrawn by the panda and the teapot.

At this point we can see the principle of multiple bins unravel itself. Panda3D's rendering subsystem always processes these bins from lowest to highest priority. Summing up, this creates the following render order for our sample code:

  1. The"background" bin has a priority value of 10—the lowest in our scene. Therefore, the smiley model it contains is rendered first.
  2. Next comes the"fixed" bin with a priority of 40. This bin allows us to manually control the render order of the contained models and actors based on another priority value. The scene object with the lowest priority value is rendered first. This means that the panda is rendered next.
  3. The teapot is in the"fixed" bin and has a sub-priority value of 1. This is the highest value for all objects in the scene, causing it to be the last object to be rendered.

There's more...

The sample code only showed you a part of Panda3D's scene sorting features, so let's take a deeper look!

Cull bin types

If we take a look at the BinType enumeration found in Panda3D's API, we can see five different types of cull bins:

  • BTUnsorted: An unsorted bin just sends geometry to the graphics card in the order it is encountered while traversing the scene graph.
  • BTStateSorted: A state sorted cull bin sorts geometry by material, texture, and shader, among others, to minimize the switching of render states to increase drawing performance.
  • BTBackToFront: This type of cull bin will cause the parts of a model that are the furthest away from the point of view to be drawn first. This is necessary for drawing semi-transparent models, for example: Because we need to properly blend the colors of the translucent parts of a model and the colors of the surfaces behind these see-through parts. For further information on this topic, read up on alpha blending.
  • BTFrontToBack: This is the reversal of BTBackToFront. Geometry that is nearer to the camera is drawn first.
  • BTFixed: The order of rendering is completely user defined and needs to be specified as the third parameter of the setBin() method. Objects with lower order values are drawn first.

Default cull bins

By default, Panda3D creates the following bins ready to be used by your code. Bins with a lower priority value are processed first.

Name

Type

Priority

background

BTFixed

10

opaque

BTStateSorted

20

transparent

BTBackToFront

30

fixed

BTFixed

40

unsorted

BTUnsorted

50

gui-popup

BTUnsorted

60

Adding a cull bin at runtime

It's very easy to add new cull bins at runtime. Consider the following code snippet:

from panda3d.core import CullBinManager
cbm = CullBinManager.getGlobalPtr()
cbm.addBin("mybin", CullBinManager.BTFixed, 80)

All you need to do is import the CullBinManager class, get the global singleton instance, and pass the new bin's name, type, and order value to the addBin() method. The bin type is one out of the types presented previously. The order value can be any positive or negative integer, but should not interfere with the priorities of the default cull bins.

Adding a cull bin using the configuration file

You can also add custom cull bins using the Config.prc file. All you need to do is add lines similar to the ones shown in the following code:

cull-bin nameA 80 unsorted
cull-bin nameB 90 state_sorted
cull-bin nameC 100 back_to_front
cull-bin nameD 110 front_to_back
cull-bin nameE 120 fixed

As you might have guessed already, the arguments to the cull-bin variable are the bin's name, the sort order, and the cull bin's type. Different to the names of the bin types shown in the preceding sections, this uses a slightly different naming convention.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset