Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 8 of 8

Thread: Radiosity with OpenGL

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2012
    Posts
    5

    Radiosity with OpenGL

    Hi,
    Ive been trying to implement instant radiosity with OpenGL. I wont go through details but what ive been trying to do is :

    We have many lightsources and we want to get illumination of a scene with them. Ive been using accumulation buffer ( cos in opengl there is max 8 lights in one go ) and gl spot lights.

    Problem was that with glLightfv( Lightn, GL_DIFFUSE, LightIntensity); LightIntensity values are clumped to 1.0 and radiosity can be much bigger then one. Ive tried to do the trick LightIntensity /= 1000 and then with for every call of glAccum do glAccum( GL_ACCUM, 1000 ); unfortunetely that isnt possible without extension i believe.

    So in order to make it possible ive started using ARB_color_buffer_float extension with glew.

    Ive initialised glew and check if extension was available
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
    /* Problem: glewInit failed, something is seriously wrong. */
    fprintf(stderr, "Error: %s\n", glewGetErrorString(err));

    }
    if( glewIsSupported("GL_ARB_color_buffer_float") )
    {
    printf("COOL\n");
    }
    It was working fine.
    Then before rendering ive used
    glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE);
    glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FALSE);
    glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE);
    Program is compiling and works but unfortunetely results are still or
    black screen or completly white ( depending on parameters )
    Ive tried to simulate basic equation of global illumination with spotlights .Something like this :
    glLightfv( OpenGlLights[iLightIndeks], GL_DIFFUSE, LightDiffusse);
    glLightfv( OpenGlLights[iLightIndeks], GL_POSITION, LightSpotPosition);
    glLightfv( OpenGlLights[iLightIndeks], GL_SPOT_DIRECTION, LightSpotNormal );
    glLightf( OpenGlLights[iLightIndeks], GL_SPOT_CUTOFF , light0SpotCutoff);
    glLightf( OpenGlLights[iLightIndeks], GL_QUADRATIC_ATTENUATION, 1);

    I think that something is wrong with colors clamping.
    Any ideas ? How can i check it out(debug and stuff )? (besides basic
    knowledge of open gl i dont have experience with extension and more advanced stuff.
    Any help will be apprecieted.
    Thanks,

  2. #2
    Junior Member Newbie
    Join Date
    Apr 2012
    Posts
    5

    Re: Radiosity with OpenGL

    Hi
    Maybe i should rephrase my question.
    I would like to have spotlights with high lights intensity.
    The problem is that glLightfv( OpenGlLights[iLightIndeks], GL_DIFFUSE, LightDiffusse); clamps LightDiffusse to 1.0. What id like to do then
    is get rid of clamping ( i thought that ARB_color_buffer_float extension would be helpful but apparently it doesnt work too well ).

    I could also divide LightDiffusse by let say 1000 and after rendering multiply all colors values by 1000. In order it work i would have to increase the color depth on each channel lets say to 32 bit. Does anyone know how to do this ?
    thanks in advance.

  3. #3
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,655

    Re: Radiosity with OpenGL

    To attain your goals you should use modern OpenGL.

    That means, forget about accum buffer and glLightfv, but instead use vertex and fragment shaders with floating point render targets on FBO.

    Good tutorials for the general topics around modern GL are here : http://www.arcsynthesis.org/gltut/

  4. #4
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,716

    Re: Radiosity with OpenGL

    BTW, what you're talking about, "What id like to do then is get rid of clamping," has nothing to do with radiosity. That's high-dynamic-range rendering/lighting.

  5. #5
    Junior Member Newbie
    Join Date
    Apr 2012
    Posts
    5

    Re: Radiosity with OpenGL

    I didnt want to get throught all details but one voxels based method gives radiosity on voxels and for final gather i d like to use opengl.
    So light intensity would be radiosity in this case i imagine but it needs to be rescaled cos in opengl RGB channels are clumped to 1.

  6. #6
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,421

    Re: Radiosity with OpenGL

    Quote Originally Posted by maciekmos
    I didnt want to get throught all details but one voxels based method gives radiosity on voxels and for final gather i d like to use opengl.
    So light intensity would be radiosity in this case i imagine but it needs to be rescaled cos in opengl RGB channels are clumped to 1.
    It depends on the buffer format. If your buffer is a RGB8 or BGR8 or whatever, the values are from 0 to 255 (represented as 0.0 to 1.0).

    If you buffer format is floating point, then the full floating point range can be used, all negative and positive values.

    Example: GL_RGB32F, GL_RGBA32F, GL_RGB16F, GL_RGBA32F and the many other formats of GL 3.0
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  7. #7
    Junior Member Newbie
    Join Date
    Apr 2012
    Posts
    5

    Re: Radiosity with OpenGL

    Thanks a lot for showing me right direction.
    However is still have implementation problems/questions.
    Ive started implementing this with FBOs and i imagine it should work in following way:
    I have 2 FBOs :
    FBO_render - used to get part of image with 8 lights (or less )
    FBO_Accum - used to accumumulate image after rendering to FBO_render. So imagine it would work like that:
    i=0;
    while( i < number of lights )
    {
    render scene with lights from i to i+ max(7, number of lights -i) to FBO_render
    i += max(7, number of lights -i);
    FBO_Accum = FBO_Accum + FBO_render;
    }
    FBO_Accum would be final picture.
    The question is if and how i can perform FBO_Accum = FBO_Accum + FBO_render; operation
    using shaders ( i havent writen single shader in my life and its not very clear if its possible). '+' in this context means adding colors components of relevant texels.

    Second question:
    Also i've tried to render to FBO scene with lights with intensity > 1 and and then rendering texture (of this FBO) to the screen. Unfortunetely it doesnt work (ive got black screen). However it works fine with lights intensity <= 1. Here is initialisation of FBO :

    void OpenGlRenderer::initFrameBufferDepthBuffer(void)
    {

    glGenRenderbuffersEXT(1, &amp;iDepthBuffer); // Generate one render buffer and store the ID in iDepthBuffer
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, iDepthBuffer); // Bind the iDepthBuffer render buffer

    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, OPT.m_nWidth, OPT.m_nHeight); // Set the render buffer storage to be a depth component, with a width and height of the window

    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, iDepthBuffer); // Set the render buffer of this buffer to the depth buffer

    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // Unbind the render buffer
    }

    void OpenGlRenderer::initFrameBufferTexture(void)
    {
    glGenTextures(1, &amp;iTextureImg); // Generate one texture
    glBindTexture(GL_TEXTURE_2D, iTextureImg); // Bind the texture iTextureImg

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, OPT.m_nWidth, OPT.m_nHeight, 0, GL_RGB, GL_FLOAT, NULL); // Create a standard texture with the width and height of our window

    // Setup the basic texture parameters
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    // Unbind the texture
    glBindTexture(GL_TEXTURE_2D, 0);
    }

    void OpenGlRenderer::initFrameBuffer(void)
    {
    initFrameBufferDepthBuffer(); // Initialize our frame buffer depth buffer

    initFrameBufferTexture(); // Initialize our frame buffer texture

    glGenFramebuffersEXT(1, &amp;iFrameBufferAccumulation); // Generate one frame buffer and store the ID in iFrameBufferAccumulation
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, iFrameBufferAccumulation); // Bind our frame buffer
    }
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, iTextureImg, 0); // Attach the texture fbo_texture to the color buffer in our frame buffer

    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, iDepthBuffer); // Attach the depth buffer iDepthBuffer to our frame buffer
    checkFramebufferStatus();
    }

    and for lights initialisation:
    for(int i= iIndeksFrom; i< iIndeksFrom+iLightsToUse; ++i )
    {
    LightDiffusse[0] = xLights[i].Bradio.x /**0.0025*/;
    LightDiffusse[1] = xLights[i].Bradio.y /**0.0025*/;
    LightDiffusse[2] = xLights[i].Bradio.z /**0.0025*/;
    LightDiffusse[3] = 1;
    float XR = xLights[i].Bradio.x;
    float YR = xLights[i].Bradio.y;
    float ZR = xLights[i].Bradio.z;
    LightSpotNormal[0] = xLights[i].v_n.x;
    LightSpotNormal[1] = xLights[i].v_n.y;
    LightSpotNormal[2] = xLights[i].v_n.z;

    LightSpotPosition[0] = xLights[i].pos.x;
    LightSpotPosition[1] = xLights[i].pos.y;
    LightSpotPosition[2] = xLights[i].pos.z;

    float XP = xLights[i].pos.x;
    float YP = xLights[i].pos.y;
    float ZP = xLights[i].pos.z;

    glLightfv( OpenGlLights[iLightIndeks], GL_DIFFUSE, LightDiffusse);
    glLightfv( OpenGlLights[iLightIndeks], GL_POSITION, LightSpotPosition);
    glLightfv( OpenGlLights[iLightIndeks], GL_SPOT_DIRECTION, LightSpotNormal );
    glLightf( OpenGlLights[iLightIndeks], GL_SPOT_CUTOFF , 90);
    glLightf( OpenGlLights[iLightIndeks], GL_QUADRATIC_ATTENUATION, 1);
    iLightIndeks++;
    }
    Where xLights[i].Bradio.x, xLights[i].Bradio.y, xLights[i].Bradio.z are usually around 400

    Can someone help me out?
    Thanks in advance.

  8. #8
    Junior Member Newbie
    Join Date
    Apr 2012
    Posts
    5

    Re: Radiosity with OpenGL

    Ive changed
    void OpenGlRenderer::initFrameBufferTexture(void)
    {
    glGenTextures(1, &amp;iTextureImg); // Generate one texture
    glBindTexture(GL_TEXTURE_2D, iTextureImg); // Bind the texture iTextureImg

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, OPT.m_nWidth, OPT.m_nHeight, 0, GL_RGB, GL_FLOAT, NULL); // Create a standard texture with the width and height of our window

    // Setup the basic texture parameters
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    // Unbind the texture
    glBindTexture(GL_TEXTURE_2D, 0);
    }
    as it was recomended on the site http://gpgpu.org/ to
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, iTextureImg);

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_FLOAT_R32_NV, OPT.m_nWidth, OPT.m_nHeight, 0, GL_RGBA, GL_FLOAT, NULL);

    and generally GL_TEXTURE_2D to GL_TEXTURE_RECTANGLE_ARB but now i get
    only white screen .. ehh.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •