PDA

View Full Version : Ray Casting and Rotating



glnoob_andre
08-15-2012, 11:48 PM
Hi I have written a program to perform a GLSL ray cast. It seems to be working, except when I rotate my model, it doesn't rotate right that is it skews itself and kind of rotates weird and parts of the volume get distorted, and a smaller image of the model is created in the centre through continuous rotation.

All am simply doing is create three textures with the help of 3 FBO's. I render the back and front faces separately as 2 textures, and the last texture contains the result of the ray cast.

If someone has any idea what is wrong, please help me out. My relevant code is below.

/* Display Function */

void RayCaster::renderRayCast()
{
float ratio = float(width)/float(height);

// Fill screen with viewport
glViewport(0, 0, width, height);


// Reset projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Set a 45 degree perspective
gluPerspective(45, ratio, 0.0, 25);


// Reset Modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();


gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0);

glTranslatef(0.0, 0.0, 0.0);
glTranslatef(0.0, 0.0, zoom);
glRotatef(rotAngleY, 0.0, 1.0, 0.0);
glRotatef(rotAngleX, 1.0, 0.0, 0.0);
glMultMatrixf(rotMat);

glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


// Ray Start (Render to FBO)
glBindFramebuffer(GL_FRAMEBUFFER, fboRayStart);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glUseProgram(rayVertexProgram);
drawQuads(1.0, 1.0, 1.0);
glUseProgram(0);
glDisable(GL_CULL_FACE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, texRayStart);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);


// Ray Stop (Render to FBO)
glBindFramebuffer(GL_FRAMEBUFFER, fboRayStop);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glUseProgram(rayVertexProgram);
drawQuads(1.0, 1.0, 1.0);
glUseProgram(0);
glDisable(GL_CULL_FACE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, texRayStop);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);


// Ray Cast (Render to FBO)
glBindFramebuffer(GL_FRAMEBUFFER, fboResult);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glUseProgram(rayCasterProgram);


glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_3D, volumeTex);
utilities.setUniform("Volume", 2);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_3D, gradientTex);
utilities.setUniform("Gradient", 3);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texRayStop);
utilities.setUniform("RayStop", 1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texRayStart);
utilities.setUniform("RayStart", 0);


//utilities.setUniform("IsoValue", isoValue);
//utilities.setUniform("Absorption", absorption);
drawQuads(1.0, 1.0, 1.0);
glUseProgram(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, texResult);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


// Render to Quad

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texResult);


reshapeOrtho(width, height);
glColor4f(1.0, 1.0, 1.0, 1.0);
drawFullscreenQuad();


glDisable(GL_TEXTURE_2D);
}

/* Shader */
varying vec4 vPosition;


uniform sampler2D RayStart;
uniform sampler2D RayStop;
uniform sampler3D Volume;
uniform sampler3D Gradient;
uniform sampler2D TransferFunc;


const float StepLength = 0.01;
const float Threshold = 0.45;


vec3 LightPosition = vec3(5.0, 5.0, 15.0);
vec3 DiffuseMaterial = vec3(0.05, 0.05, 0.05);


float lookup(vec3 coord)
{
vec3 V = texture3D(Volume, coord).xyz;
return dot(V, V);
}


void main()
{
vec2 coord = 0.5 * (vPosition.xy + 1.0);
vec3 rayStart = texture2D(RayStart, coord).xyz;
vec3 rayStop = texture2D(RayStop, coord).xyz;


if (rayStart == rayStop) {
discard;
return;
}


vec3 ray = rayStop - rayStart;
float rayLength = length(ray);
vec3 stepVector = StepLength * ray / rayLength;


vec3 pos = rayStart;
vec4 dst = vec4(0);
while (dst.a < 1.0 && rayLength > 0.0) {

float V = lookup(pos);
if (V > Threshold) {


// Refine the hitpoint to reduce slicing artifacts:
vec3 s = -stepVector * 0.5;
pos += s;
V = lookup(pos);
if (V > Threshold)
s *= 0.5; else s *= -0.5;
pos += s;
V = lookup(pos);


if (V > Threshold)
{
float L = StepLength;
float E = lookup(pos + vec3(L,0,0));
float N = lookup(pos + vec3(0,L,0));
float U = lookup(pos + vec3(0,0,L));
vec3 normal = normalize(gl_NormalMatrix * vec3(E - V, N - V, U - V));
vec3 light = LightPosition;


float df = abs(dot(normal, light));
vec3 color = df * DiffuseMaterial;


vec4 src = vec4(color, 1.0);
dst = (1.0 - dst.a) * src + dst;
break;
}
}


pos += stepVector;
rayLength -= StepLength;
}


gl_FragColor = dst;
}

glnoob_andre
08-15-2012, 11:59 PM
Here is a video as well. http://www.youtube.com/watch?v=J9BMKKrrUW4&feature=g-upl