Saturday, March 8, 2014

GPU ray march renderer for PVR (Production Volume Rendering)

I have managed to integrate my GPU ray marcher with the awesome Production Volume Renderer (PVR) by Magnus Wrenninge on Windows 7 using Visual Studio 2012. The results are amazing as can be seen in the image below.
GPU based Ray Marcher for Production Volume Renderer
Here is the video
 


I had to put the video on vimeo as youtube is occassionally blocked in my country. The PVR code to model this volume is follows. This is based of the example python code from Chapter 1.

#include < pvr/Modeler.h >
#include < pvr/Primitives/Rasterization/PyroclasticPoint.h >
#include < pvr/Renderer.h >
#include < pvr/RaymarchSamplers/PhysicalSampler.h >
#include < pvr/Raymarchers/UniformRaymarcher.h >
#include < pvr/Camera.h >
#include < pvr/Occluders/OtfTransmittanceMapOccluder.h >
#include < pvr/Lights/PointLight.h >
#include < pvr/Volumes/VoxelVolume.h >
#include < Imath/ImathVec.h >
#include < pvr/VoxelBuffer.h >

void GenerateVolumeData(std::vector < GLubyte > & buffer, int& xdim, int& ydim, int& zdim) {
    pvr::Model::Modeler::Ptr modeler = pvr::Model::Modeler::create();
    pvr::Model::ModelerInput::Ptr input = pvr::Model::ModelerInput::create();
    pvr::Geo::Particles::Ptr parts = pvr::Geo::Particles::create();
    pvr::Geo::Geometry::Ptr geo = pvr::Geo::Geometry::create();
    pvr::Model::Prim::Rast::PyroclasticPoint::Ptr prim =    pvr::Model::Prim::Rast::PyroclasticPoint::create();
   
    parts - > add(1);
    geo - > setParticles(parts);       
     
    pvr::Util::ParamMap map;
    map.floatMap["amplitude"] = 0.5f;
    prim - > setParams(map);

    input - > setGeometry(geo);
    input - > setVolumePrimitive(prim);

    modeler - > addInput(input);   
    modeler - > updateBounds();
    modeler - > setResolution(200);
    modeler - > execute();

    pvr::VoxelBuffer::Ptr buf =    modeler - > buffer();
    Imath::V3i res = buf - > dataResolution(); 
   
    xdim = res.x;
    ydim = res.y;
    zdim = res.z;
   
    int index = 0; 
    for(pvr::VoxelBuffer::iterator i = buf - > begin(); i!= buf - > end(); ++i)
    {
        Imath::V3f value = *i; 
        buffer.push_back((GLubyte)(value.x*255));
        buffer.push_back((GLubyte)(value.y*255));
        buffer.push_back((GLubyte)(value.z*255)); 
    }
}

6 comments:

Godot said...

Nice work!
I am also making volume data and rendering the volume data by using PVR.
PVR only provides python examples.
So I has thought that thank you for your codes. The upper codes is working well.
But the result is volume data in buffer.
Can I know how could you render?

MMMovania said...

Hi,
Thanks for appreciating my work. I am using a custom written single pass GPU raycaster. I can recommend two webpages which detail all this.
1) Miles Macklin's blogpost: http://blog.mmacklin.com/2010/11/01/adventures-in-fluid-simulation/
2) The little grasshopper's single pass volume renderer: http://prideout.net/blog/?p=64

Hope it helps.

Slim Ghariani said...

Hi Muhammad,

Going through the pain of compiling pvr for windows. Any chance you could share your version (not including your GPU raymarcher). I came across the XRT thread, which helps to some extend.

Thank you very much!

Slim

MMMovania said...

Hi Slim,
Here you go. https://github.com/mmmovania/PVR_Windows

Slim Ghariani said...

Thank you very much Muhammad for putting this huge archive so fast online!!

MMMovania said...

You are always welcome Slim :)

Popular Posts

Copyright (C) 2011 - Movania Muhammad Mobeen. Awesome Inc. theme. Powered by Blogger.