Ray Casting and Rotating

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;

}

Here is a video as well. - YouTube