Jump to content

  • Log In with Google      Sign In   
  • Create Account

StanLee

Member Since 16 Mar 2012
Offline Last Active Dec 18 2015 07:51 AM

Topics I've Started

Faces of cube map not fitting together

06 November 2015 - 10:53 AM

Hi,

 

I am trying to render a scene to a cube map but the faces are not fitting together. I think there is something wrong with the perspective:

Unbenannt.jpg

 

I define a framebuffer and render the scene six times with different viewing directions (one renderpass for each face of the cube map). Then I place the camera at the origin and render a unit cube with the cube map.

 

The creation of the cube map:

TextureCubeMap::TextureCubeMap(const unsigned int size) : _size(size), _boundSlot(-1){
  glGenTextures(1, &_texID);
  glBindTexture(GL_TEXTURE_CUBE_MAP, _texID);

  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

  for (int loop = 0; loop < 6; ++loop)
  {
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + loop, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
  }

  glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}

int TextureCubeMap::bind(){
  ...
    glEnable(GL_TEXTURE0 + _boundSlot);
    glActiveTexture(GL_TEXTURE0 + _boundSlot);
    glEnable(GL_TEXTURE_CUBE_MAP);
    glBindTexture(GL_TEXTURE_CUBE_MAP, _texID);
  ...
  return _boundSlot;
}

void TextureCubeMap::unbind(){
  ...
  glActiveTexture(GL_TEXTURE0 + _boundSlot);
  glBindTexture(GL_TEXTURE_2D, 0);
  ...
}

And this is the part where I render the scene to the cube map sixe times:

void RenderToCubeMap::render(SceneContext& scene_context){
  glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
  const GLenum drawBuffer = { GL_COLOR_ATTACHMENT0 };
  glDrawBuffers(1, &drawBuffer);
  
  glViewport(0, 0, (GLsizei)_cubeMap->getSize(), (GLsizei)_cubeMap->getSize());
  SceneContext cubeMapContext = scene_context; //Contains all relevant matrices like projection-, view- and modelmatrix
  cubeMapContext._P = glm::perspective(90.f, 1.f, 1.f, 1000.f);
  
  _cubeMap->bind();
  for (unsigned int iFace = 0; iFace < 6; iFace++){
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + iFace, _cubeMap->getTexID(), 0);
    IRenderPass::startRenderPass(); //Enable depth test, backface culling, clear depth & draw buffer

    glm::vec3 viewDir, up;
    switch (GL_TEXTURE_CUBE_MAP_POSITIVE_X + iFace){
    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
      viewDir = glm::vec3(1.0f, 0.0f, 0.0f);
      up = glm::vec3(0.f, -1.f, 0.f);
      break;
    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
      viewDir = glm::vec3(-1.0f, 0.0f, 0.0f);
      up = glm::vec3(0.f, -1.f, 0.f);
      break;
    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
      viewDir = glm::vec3(0.0f, 1.0f, 0.0f);
      up = glm::vec3(0.f, 0.f, 1.f);
      break;
    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
      viewDir = glm::vec3(0.0f, -1.0f, 0.0f);
      up = glm::vec3(0.f, 0.f, -1.f);
      break;
    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
      viewDir = glm::vec3(0.0f, 0.0f, 1.0f);
      up = glm::vec3(0.f, -1.f, 0.f);
      break;
    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
      viewDir = glm::vec3(0.0f, 0.0f, -1.0f);
      up = glm::vec3(0.f, -1.f, 0.f);
      break;
    }
    
    auto viewMatrix = glm::lookAt(glm::vec3(scene_context._camPos), glm::vec3(viewDir + scene_context._camPos), up);
    cubeMapContext._V = viewMatrix;
    cubeMapContext._MV = viewMatrix * cubeMapContext._M;
    cubeMapContext._MVP = cubeMapContext._P * cubeMapContext._MV;
    _sceneGraph->renderSubtree(cubeMapContext);
  }
  _cubeMap->unbind();
  glBindFramebuffer(GL_FRAMEBUFFER, 0);
  IRenderPass::endRenderPass(); //Disable depth test, backface culling
}

What am I doing wrong? Is there something wrong with the projection matrix? I am really thankful for any input.

 

Best regards,

Stan


3D Texture upload fails

08 May 2015 - 03:30 PM

Hello guys,
 
I am developing a direct volume renderer and have issues with the 3D texture upload. I have a ct scan with 421 slices and each slice has a size of 512x512 with one channel containing an unsigned short value. This is how I upload the data at the moment:
 

glBindTexture(GL_TEXTURE_3D, _volumeTextureID);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);

glTexImage3D(GL_TEXTURE_3D, 0, GL_R16F, 512, 512, 421, 0, GL_RED, GL_UNSIGNED_SHORT, _volumeData);

The problem is in the fragment shader. The values of the volumeTexture are not clamped to the range of [0,1]. I do raycasting in a cube which contains my 3D texture. As you can see in the for loop I check if the sampled value of my volumeTexture is bigger than 0.1 and set the color output to red. Unfortunately I don't see anything red in the cube. The values are all below 0.1 because when I do checks of the values below 0.1 then I already can see the lung, spine etc. 

#version 430

out vec4 color;

uniform sampler2D backTex;
uniform sampler2D frontTex;
uniform sampler3D volumeTexture;

smooth in vec4 position;

uniform int width;
uniform int height;
uniform uint samplingSteps;

void main(void){
  vec2 texCoor = vec2( (gl_FragCoord.x-0.5)/width, (gl_FragCoord.y-0.5)/height);
  vec3 front = texture(frontTex, texCoor).xyz;
  vec3 back = texture(backTex, texCoor).xyz;
  
  float length = length(back - front);
  vec3 dir = normalize(back - front);
  vec3 step = dir * 1/samplingSteps;
  vec4 pos = vec4(front, 0);
  
  float volValue = 0;
  vec4 src = vec4(0);
  vec4 finalColor = vec4(1);
  
  float max = 0;
  
  for(int i = 0; i < samplingSteps*length; i++){
    
    volValue = texture(volumeTexture, pos.xyz).r;
    if(volValue >= 0.1){
      finalColor = vec4(0.5, 0, 0, 0.5);
      break;
    }
    
    pos.xyz += step;
    
    if(pos.x > 1 || pos.y > 1 || pos.z > 1){
      break;
    }
  }
  color = finalColor;
}

 
What is happening here? Why are all my values in the volume texture clamped to [0, 0.1] and not to [0, 1]?
 
Best regards,
StanLee


Raytracing via compute shader

14 March 2013 - 03:15 PM

I am trying to do some raytracing on the GPU via the compute shader in OpenGL and I came across a very strange behaviour.

For every pixel in the screen I launch a compute shader invocation and this is how the compute shader looks like:

 

 

#version 430

struct Camera{
    vec4    pos, dir, up, xAxis ;
    float   focalLength;
    float   pW, pH;
};

struct Sphere{
    vec4    position;
    float   radius;
};

struct Ray{
    vec3    origin;
    vec3    dir;
};

uniform Camera      camera;
uniform uint        width;
uniform uint        height;

uniform image2D outputTexture;

float hitSphere(Ray r, Sphere s){
    
    float s_ov = dot(r.origin, r.dir);
    float s_mv = dot(s.position.xyz, r.dir);
    float s_mm = dot(s.position.xyz, s.position.xyz);
    float s_mo = dot(s.position.xyz, r.origin);
    float s_oo = dot(r.origin, r.origin);
    
    float d = s_ov*s_ov-2.0f*s_ov*s_mv+s_mv*s_mv-s_mm+2.0f*s_mo*s_oo+s.radius*s.radius;
    
    if(d < 0){
        return -1.0f;
    } else if(d == 0){
        return (s_mv-s_ov);
    } else {
        float t1 = 0, t2 = 0;
        t1 = s_mv-s_ov;
        
        t2 = (t1-sqrt(d));
        t1 = (t1+sqrt(d));
        
        return t1>t2? t2 : t1 ;
    }
}

Ray initRay(uint x, uint y, Camera cam){
    Ray ray;
    ray.origin = cam.pos.xyz;
    
    ray.dir = cam.dir.xyz * cam.focalLength + vec3(1, 0, 0)*( float(x-(width/2)))*cam.pW
                              + cam.up.xyz * (float(y-(height/2))*cam.pH);
                              
    ray.dir = normalize(ray.dir);
                              
    return ray;
}

layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main(){
    uint x = gl_GlobalInvocationID.x;
    uint y = gl_GlobalInvocationID.y;
    
    if(x < 1024 && y < 768){
        float t = 0.0f;

        Ray r = initRay(x, y, camera);
        
        Sphere sp ={vec4(0.0f, 0.0f, 20.0f, 0.0f), 2.0f};

        t = hitSphere(r, sp);
        
        if(t <= -0.001f){
            imageStore(outputTexture, ivec2(x, y), vec4(0.0, 0.0, 1.0, 1.0));
        } else {
            imageStore(outputTexture, ivec2(x, y), vec4(0.0, 1.0, 0.0, 1.0));
        }
        
    }
}
 

Rendering on the GPU yields the following broken image:

quarter.png

Rendering on the CPU with the same algorithm yields this image:

normal.png

I can't figure out the problem since I just copied and pasted the "hitSphere()" and "initRay()" functions into my compute shader. First I thought I haven't dispatched enough work groups, but then the background wouldn't be blue, so this can't be the case. This is how I dispatch my compute shader:

#define WORK_GROUP_SIZE 16
//width = 1024, height = 768
void OpenGLRaytracer::renderScene(int width, int height){
    glUseProgram(_progID);

    glDispatchCompute(width/WORK_GROUP_SIZE, height/WORK_GROUP_SIZE,1);

    glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
}

Then I changed the position of the sphere in x direction to the right:

half1.png

In y direction to the top:

half2.png

And in both directions (right and top):

full.png

When I change the position far enough in both directions to the left and to the bottom, then the sphere actually disappears. It seems that all the calculations on the GPU only work in one quarter of the image (top-right) and happen to yield false results in the other three quarters.

 

I am totally clueless at the moment and don't even know how to start fixing this.


Camera for Raytracing

13 March 2013 - 10:48 AM

Hello,

 

I am working on a raytracer at the moment and I come across some issues with the camera model. I just don't seem to manage the calculation of the direction vector of my rays.

 

Let's say we have given an image resolution of resX x resY, a position pos of the camera, the up vector, the direction vector dir (the direction in which the camera is looking) and a field of view for the horizontal and vertical component fovX and fovY. With the help of these values I can manage to calculate the focal length and thus the width of my pixels.

fovx.jpg

 

But when I do the same for the height I'll get another focal length.

fovy.jpg

 

There is something I must be missing because the focal length determines the distance between my camera position and the image plane and thus must be unique.

But let's suppose that I've got one unique focal length, then calculating the direction of a ray for the screen coordinates (x,y) should be done with this formula.

formel.jpg

I adjust the direction vector in such a way, that he is always in the center of a pixel.

 

Unfortunately applying this to my raytracer yields absolutely no results. sad.png


Texture as background for framebuffer

12 October 2012 - 02:53 PM

Hello,

I am curious if it is possible to set a texture as the background for the framebuffer on which the 3D scene is rendered on in an easy way.
To be more specific:

I want to take the frames of my webcam and draw my 3D scene (which consits of particles in a black space) on it. I experimented with framebufferObjects and render-to-texture techniques. At the moment I create a framebuffer object and attach two textures to it. On one texture I render my 3D scene, while I copy the frame of my webcam to the other texture. I thought I could do something with glBlitFramebuffer() but unfortunately it just copies one texture to the other.

I thought I could somehow work with stencil buffers because I just need to punch out the black space of my 3D particle scene and draw it on my webcam frame, but I couldn't find any helpful ressources on this topic so far.

Thanks for any help in advance! :)

PARTNERS