Janua Tutorial

Follow these simple steps to implement Janua in your application.



Step 0: Is Occlusion culling needed for my application?

Before considering using Janua, you should ask youself: "Does my 3D application have objects occluded by other objects?".
Janua does accelerate your application by indicating which objects are not visible from a given region in the scene. If your 3D scene has all the objects visible from all the possible view points, then occlusion culling will not likely accelerate your application.
On the other hand, if the scene has good occluders, (ie. opaque walls, doors, buildings, etc), then it is highly likely that these objects occlude other objects behind them. In this case, you can continue with Step 1.

Step 1: Preprocess the visibility database of your scene

In this step, Janua will calculate which objects are visible from different regions of the scene. To do this, it needs to know the polygons of the objects in your 3D scene and you need to provide them via the API methods available in the documentation. Each object will be a called a Model in this context.

Models can be of two types:

  • Occluders: These are 3D models that cover a large area and are completely opaque. Examples are walls, ceiling, doors, gates, buildings, houses, rocks, etc. Occluders will be occluding other occluders and occludees, meaning that from a given point an occluder may hide other occluders and other occludees.
  • Occludees: These are 3D models that we want to query if they are likely to be visible from a given region. Examples of occludees are: non playable characters, cars, boxes, etc,

For the moment, Janua only supports static occludees, meaning that they are not expected to change their position.


The following example code shows how to create a Scene and add to Models, one occluder and one occludee.

//Create a scene.
Scene scene = Scene(sceneOptions, "Level1");

//Create an occluder model based on a list of vertices and triangle indices.
Model modelOccluder(occluderVertices, occluderNumberOfVertices, occluderTriangleIndices, occluderTriangleCount);

//Create an occludee model based on a list of vertices and triangle indices.
Model modelOccludee(occludeeVertices, occludeeNumberOfVertices, occludeeTriangleIndices, occludeeTriangleCount);

//Add an instance of the occluder model using particular transformation matrix.
//Identify it by model 2.
scene.addModelInstance(modelOccluder, 1, occluderTransformMatrix, OCCLUDER);

//Add an instance of the occludee model using particular transformation matrix.
//Identify it by model 2.
scene.addModelInstance(modelOccludee, 2, occludeeTransformMatrix, OCCLUDEE);


Now Janua knows which Models are occluders and which ones are occludees. The next part is needed to actually start calculating the visibility database and generate an output file:


//Calculate the visibility database of the scene using a voxel size of 10x10x10.

PVSGenerator generator = PVSGenerator(scene, Vector3f(10,10,10) );


The PVSGenerator will create a file called pvs.lrb and will be used in the next step to make visibility queries at runtime.

Step 3: Query the visibility database

 Here the Janua Runtime library is used to query the visibility data created in step 2. The Runtime module recieves a pointer to a buffer that contains the visibility database. You can open the .lrb database file and fill in the buffer with it.

To initialize the Runtime, you need to create a Janua handler and load the visibility database.

janua_handler handler;
janua_handler_load_database(&handler, databaseBuffer);


After that, before every render cycle you can query for the visible models this way:


janua_query_result result;
janua_query_visibility_from_position( &handler, cameraPos.X, cameraPos.Y, cameraPos.Z, &result )


 The janua_query_result will contain the models that need to be rendered.

for(unsigned int c = 0; c < result.model_ids_count ; ++c)
    3Dengine.Render( meshes[ result.model_ids[c] ] );



Last edited Oct 19, 2013 at 10:39 PM by lebarba, version 4


No comments yet.