Showing posts with label GPU Volume Rendering. Show all posts
Showing posts with label GPU Volume Rendering. Show all posts

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)); 
    }
}

Sunday, November 20, 2011

Thursday, February 24, 2011

Thursday, October 29, 2009

Half angle slicing






Half angle slicing


Half angle slicing


Half angle slicing


I was looking to implement Half angle slicing but
due to some problems I was unable to get the results.
see the image below. The problems included how to
update the OpenGL blending order front to back
and back to front for the light and eye buffers.
Once this was sorted, I was still not getting the same
output as was shown in the paper by Joe Kniss.
So just today I noticed I was not clearing the eye
and light buffers doing so removed the bugs. Finally,
I managed to get it working. Compare the above images
to this one.

Half angle slicing

Saturday, May 23, 2009

Half angle slicing



Half angle slicing is a really wonderful technique invented by Joe Kniss. The details are given in GPUGems1-Chapter 39. I implemented it and the results are amazing. I will post videos after the whole thing is finished. Till then, enjoy some snapshots.



Half angle slicing
Half angle slicing
Half angle slicing
Half angle slicing
Half angle slicing
Half angle slicing

Monday, June 9, 2008

Light makes a very big difference.


Don't believe me take at a look at the snapshots yourself. I have added gradient based lighting on the 2D object based texture slice volume rendering.


Lit engine volume rendering
Lit engine volume rendering

Sunday, June 8, 2008

Transfer function loaded into 2D object based texture slicing


Today, I added the transfer functions. First I made a simple class to wrap a transfer function. This class has a very easy interface. To add color point curve, simply call TransferFunction::AddPoint(int intensity, float opacity). Then I added it to my object based 2D texture slicer. See the snapshots for details.


Transfer function object based texture slicing
Transfer function object based texture slicing
Transfer function object based texture slicing

Saturday, June 7, 2008

View aligned 3D Texture Slicing


Today I did the View aligned 3D Texture Slicing. The only thing different here is that we have to get the intersection test between a plane parallel to the viewing plane and intersect it to the unit cube placed at origin.

I will add transfer functions to this and the object aligned version later.



View aligned 3d texture slicing

Thursday, June 5, 2008

Object aligned slice based volume rendering


I just finished 2D texture slices based volume rendering today. Here are the snapshots of the application. Its damn fast. I will be adding some transfer function editing facility into it tomorrow.

A cool idea though will now work on transfer functions and then view aligned slicing of 3D texture.



Object aligned slicing

Implementation details:

I used glut and OpenGL for this b/c I think its much more fast to develop applications in OpenGL and glut. First I determine the current view direction vector which is simply obtained using the following code


GLfloat matView[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matView);
GLfloat viewDir[3]={ -matView[2], -matView[6], -matView[10]};


Next a 3d texture is loaded from the CT/MRI scans and then using this code, object space quad slices are generated. Here I am only giving the code for the PosZ axis. A slight modification is needed for the other axes.



void DrawSliceZPos()
{
float zPos = 0.5;
float zAmt = -1.0f/zSlices;

glBindTexture(GL_TEXTURE_3D,textureID);
glBegin(GL_QUADS);

//offset the slice so its in the middle
zPos += zAmt/2.0f;
for(int i=zSlices-1;i>=0;i--)
{
float tex = (((float)i)/zSlices);
glTexCoord3f(0,0,tex); glVertex3f(-0.5, -0.5, zPos);
glTexCoord3f(0,1,tex); glVertex3f(-0.5, 0.5, zPos);
glTexCoord3f(1,1,tex); glVertex3f( 0.5, 0.5, zPos);
glTexCoord3f(1,0,tex); glVertex3f( 0.5, -0.5, zPos);
zPos += zAmt;
}
glEnd();
}


The appropriate slices are drawn based on the maximum abs value of the current view direction as



switch(GetMaxDim(viewDir))
{
case 0:
if(viewDir[maxDim] > 0.0f)
DrawSlicePosX();
else
DrawSliceNegX();
break;
...
case n: ... and so on
}


Thats it and finally the result is blended to produce the rendering as shown above.

Popular Posts

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