[vtkusers] Performance leak in multipass rendering resolved

Rocco Gasteiger post at rocco-gasteiger.de
Fri Jan 15 04:41:51 EST 2010


Dear VTK-Users,

 

in a previous post
(http://www.vtk.org/pipermail/vtkusers/2009-December/104490.html) I reported
a strong performance leak during rendering twice of my object with the new
multipass framework of VTK. Especially, if my object consist of many
triangles. Now, I figured out what the problem was by examine the source
code of the vtkOpenGLMapper and want to shade these information with the
VTK-community, especially these users which have not yet a deep
understanding of the rendering pipeline of VTK, like me.

 

In the render-routine of my derived vtkRenderPass-class I changed some actor
properties, e.g., surface rendering style (wireframe or surface) or opacity
via “actor->GetProperty()->SetOpacity(
)” in each pass. This occurred a
deletion and new creation of the display lists of the corresponding
polydata-object in the mapper. Because this happened every frame, the
performance leak occurred.

 

To resolve it, I use the property key capability of the frame work by
orientation to  vtkShadowMappPass. Like in my previous approach, I create
different actors of my object based on the same vtkPolyData object. After
this, I set the properties of each actor in that way I want to use it in the
corresponding pass (e.g. wireframe). Additionally I set different
vtkInformation-objects with special keys as property keys to the actors. In
my render-routine of my derived vtkRenderingPass I set  the required keys to
my render state object and only these actor(s) with the same key is (are)
rendered. Now I can call 

this->DelegatePass->Render(&newRenderState); multiple times with setting the
correct key property and without performace leak.

 

Here is a (pseudo-)code snippet which illustrate what I have done. For
simplification I distinguish between my main-routine (definition of the
vtkPolyData, vtkRenderer and so on) and my derived vtkRenderPass-class
vtkMyRenderPass.

 

///////////////

Main-routine:

///////////////

 

// 1. Setup actors with corresponding key properties

mySurfaceMapper->SetInput(myVtkPolyData);

mySurfaceActor->SetMapper(mySurfaceMapper);

myWireframeSurfaceActor->SetMapper(mySurfaceMapper);

 

vtkSmartPointer<vtkInformation>surfacePropKey =
vtkSmartPointer<vtkInformation>::New();

surfacePropKey ->Set(vtkMyRenderPass::SURFACE(), 0);

surfaceActor->SetPropertyKeys(surfacePropKey);

 

vtkSmartPointer<vtkInformation>wirfeframePropKey =
vtkSmartPointer<vtkInformation>::New();

wirfeframePropKey ->Set(vtkMyRenderPass::WIREFRAME(), 0);

myWireframeSurfaceActor->SetPropertyKeys(wirfeframePropKey);

 

// 2. Create all necessary passes (vtkLightsPass, vtkOpaquePass,
vtkTranslucentPass, and so on), collect them

// in a vtkRenderPassCollection, pass it into a vtkSequencePass and delegate
it to a vtkCameraPass.

 

// 3. Create vtkMyRenderPass and set its delegate pass to the vtkCameraPass.

 

////////////////////

vtkMyRenderPass

////////////////////

 

// 1. Setup pass like other rendering passes e.g. vtkShadowMappPass (e.g.
frame buffers, texture objects, shaders, 
)

 

// 2. Define the property keys in the header file 


static vtkInformationIntegerKey *SURFACE();

static vtkInformationIntegerKey *WIREFRAME ();

// 
and the corresponding macros in the c++-file

vtkInformationKeyMacro(vtkMyRenderPass,SURFACE,Integer);

vtkInformationKeyMacro(vtkMyRenderPass, WIREFRAME,Integer);

 

// 3. Create vtkInformation-object which holds the current required keys

if (this->requiredKeys == 0) this->requiredKeys =
vtkSmartPointer<vtkInformation>::New();

this->requiredKeys->Set(vtkMyRenderPass::SURFACE(),0);

 

// 4. Create vtkRenderState object, set key-object, framebuffers and so on

vtkRenderState newRenderState(renderer);

newRenderState.SetPropArrayAndCount(renderState->GetPropArray(),
renderState->GetPropArrayCount());

newRenderState.SetRequiredKeys(requiredKeys);

newRenderState.SetFrameBuffer(this->FrameBufferObject);

 

// 5. Render first pass

this->DelegatePass->Render(renderState);

this->NumberOfRenderedProps +=
this->DelegatePass->GetNumberOfRenderedProps();

 

// 6. Remove key SURFACE and set key WIREFRAME 

requiredKeys->Remove(vtkHiddenLineDesignerPass::SURFACE_SEMI());

requiredKeys->Set(vtkMyRenderPass::WIREFRAME(),0);

newRenderState.SetRequiredKeys(requiredKeys);

 

// 7. Render second pass

this->DelegatePass->Render(renderState);

this->NumberOfRenderedProps +=
this->DelegatePass->GetNumberOfRenderedProps();

 

// 8. Remove key WIREFRAME to have a “clean” key-property object for a new
call of the render-routine

requiredKeys->Remove(vtkMyRenderPass:: WIREFRAME());

 

 

I hope this small example helps somebody by implementing its on multipass
algorithms. The capability of the key property object is a very flexible and
good design decision . Thanks to François Bertel for designing and
implementing this framework!

 

Best regards, Rocco

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20100115/c3853c1a/attachment.htm>


More information about the vtkusers mailing list