Particle-Based Rendering
Particle-Based Rendering (PBR) renders 3D scalar fields as particle clouds and incorporates both the emission and absorption effects. Particle density depends on the transfer function and is used to evaluate the number of particles to be generated in the volume data. Because the particles can be considered opaque, no visibility sorting processing is required. PBR has three processes:
- 1. particle generation,
- 2. particle projection onto the image,
- 3. nsemble averaging of particle luminosities.
For more detail:
Koji Koyamada, Naohisa Sakamoto and Satoshi Tanaka,
"A Particle Modeling for Rendering Irregular Volumes,"
Proceedings of the International Conference on Computer Modeling and Simulation (UKSIM 2008),
Cambridge, England, April 1 3, 2008, pp.372-377, 2008. )
1. Make a working directory
First please create a working directory (e.g., RBVR) and move in this directory
# mkdir PBVR
# cd PBVR
2. Programming
In order to import the volume and transer function data from standard input, you check the number of command-line argument.
int main( int argc, char** argv )
{
if( !(argc == 2 || argc == 3) ) {
std::cerr << "USAGE (1): PBVR volume_data" ;
std::cerr << std::endl;
// Case with transfer function data
std::cerr << "USAGE (2): PBVR volume_data transfer_fnction.kvsml" ;
std::cerr << std::endl;
exit(1) ;
}
return ( 0 );
}
3. File Importer
The input data file imports by using kvs::StructuredVolumeImporter and transfers to kvs::StructuredVolumeObject.
kvs::StructuredVolumeObject* volume =
new kvs::StructuredVolumeImporter( std::string( argv[1] ));
if ( !volume ) {
kvsMessageError( "Cannot create a structured volume object." );
return( false );
}

4. Transfer function
Transfer function is mapping table to the relationship between the field value and the color, opacity.
If the transfer function does not pass as a command-line argument, initialized transfer function data is applied.
kvs::TransferFunction* transfer_function = 0 ;
if ( argc == 2 ) {
// rainbow color (default)
transfer_function = new kvs::TransferFunction ();
} else
if ( argc == 3 ) {
//
transfer_function = new kvs::TransferFunction ( argv[2] );
}
5. Sampling -particle generation-
In order to execute PBR, you convert the object from kvs::StructuredVolumeObject to kvs::PointObject by using kvs::CellByCellMetropolisSampling class.
In kvs::CellByCellMetropolisSampling, the particles according with the transfer function can be generated.
The constructor of kvs::CellByCellMetropolisSampling has following input parameters:
- const kvs::VolumeObjectBase* volume:
- volume data
- const size_t subpixel_level :
- square root of repeat level for PBR renderer
- const float sampling_step :
- sampling step in the object coordinate
- const kvs::TransferFunction& transfer_function :
- transfer function
// repeat level
int repeat_level = 9 ;
// subpixel level
int subpixel_level;
subpixel_level = (int) sqrt ( (double)repeat_level );
// sampling step
const float sampling_step = 0.5f;
// sampling
kvs::PointObject* object =
new kvs::CellByCellMetropolisSampling(
volume,
subpixel_level,
sampling_step,
*transfer_function );
You can check the number of particles by using the member function of kvs::PointObject:
- numberOfVertices()
Here, the number of particles determines by the repeat level and transfer function.
For example,
int num_particles = object->numberOfVertices() ;
std::cout << "** Number of Particles: " << num_particles << std::endl;
6. Create renderer
In order to apply the PBR for rendering the point object, you create the instance of kvs::glsl::ParticleBasedRenderer class.
And then, you set the repeat level to control the quality of rendering image:
- setRepetitionLevel ( const size_t repetition_level )
For example,
kvs::glsl::ParticleBasedRenderer* renderer =
new kvs::glsl::ParticleBasedRenderer(); // Renderer
renderer->setRepetitionLevel ( repeat_level ); // set repeat level
7. Drawing
For visualization, we should instantiate classes kvs::glut::Application and kvs::glut::Screen and resiter the viusalized objects to the screen.
Notice that the renderer registers with the object.
kvs::glut::Application app( argc, argv );
kvs::glut::Screen screen( &app );
screen.setGeometry( 0, 0, 512, 512 );
screen.registerObject( object, renderer );
screen.setTitle( " Particle Volume Renderer " ) ;
screen.show();
return( app.run() );
8. Header file
You have to include the header file for following class:
- kvs::StructuredVolumeImporter
- kvs::StructuredVolumeObject
- kvs::Message
- kvs::TransferFunction
- kvs::CellByCellMetropolisSampling
- kvs::PointObject
- kvs::glsl::ParticleBasedRenderer
- kvs::glut::Application
- kvs::glut::Screen
Therefore, you include :
#include <kvs/StructuredVolumeImporter>
#include <kvs/StructuredVolumeObject>
#include <kvs/Message>
#include <kvs/TransferFunction>
#include <kvs/CellByCellMetropolisSampling>
#include <kvs/PointObject>
#include <kvs/glut/Application>
#include <kvs/ParticleBasedRenderer>
#include <kvs/glut/Screen>
9. Sample program
Sample program: PBVR.tgz
Notice that this sample program includes sample data:
- · test.fld
- · hydrogen.kvsml
- · lobster.fld
10. Compile and execute
Let's try to compile and execute above program.
When compiling a KVS program, it is easy to use the automatic Makefile-generation tool kvsmake supplied by KVS.
# kvsmake -G <-- Create Makefile
# kvsmake <-- Compile
And then, you show following image.
# ./PBVR lobster.fld

Result of visualization
Number of particles : About 7M,repeat level : 9
Last Updated at Nov. 1, 2015