Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 3 123 LastLast
Results 1 to 10 of 23

Thread: Calculating where the shadow falls on a plane

  1. #1
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    46

    Calculating where the shadow falls on a plane

    Hi all,

    I am new to OpenGL and it's some time that I started programming with JOGL and JCUDA (OpenGL and Cuda porting on Java)

    I would need to calculate the shadow of a 3d model on a plane. Models can be also 5 milions triangles while the plane is basically a square that ranges from 480 to 4800 tiles.

    I already managed to draw the 3d model with OpenGL and calculate the projection of each triangle on the plane with CUDA.

    The big problem for me arises when I want to know which tiles are covered by the shadow and which ones arent. If I draw the array of the projected triangle I have the result printed on the screen, but I need somehow to manage it (an idea would be to retrieve the result like a boolean matrix).

    For example, a projected triangle on a 4x4 matrix could appear like the following:

    0100
    0110
    0111
    0000

    1 means I have shadow on that tile, 0 means no shadow

    I read a lot about rastering, ray tracing, FBOs, stencil buffer, etc...

    But since I am a newbie on this field, I am very confused and so I would like to ask you which is the best idea to reach this goal.

    Thanks in advance

  2. #2
    Member Regular Contributor
    Join Date
    Apr 2010
    Posts
    492

    Re: Calculating where the shadow falls on a plane

    If I draw the array of the projected triangle I have the result printed on the screen, but I need somehow to manage it
    This part is not clear to me. What do you actually want to do? Render your model such that it casts a shadow onto the plane or do you need e.g. the size of the area of the projection?

    Rendering shadows is a huge topic, with a large number of techniques. Most are variations of either "shadow volumes" (basically extrudes silhouette edges in light direction and renders that into the stencil buffer, then uses the stencil to determine where light is reflected) or "shadow maps" (basically render the scene from the light's point of view, and compare distance of a camera fragment with distance of closest object from light to decide if the fragment is lit).

  3. #3
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    46

    Re: Calculating where the shadow falls on a plane

    Quote Originally Posted by carsten neumann
    If I draw the array of the projected triangle I have the result printed on the screen, but I need somehow to manage it
    This part is not clear to me. What do you actually want to do? Render your model such that it casts a shadow onto the plane or do you need e.g. the size of the area of the projection?
    Hallo Carsten, thanks for replying,

    sorry if my english is not good , however I would need to cast the shadow on the plane and retrieving a kind of matrix that represents the plane itself and where each tiles is boolean (that is, shadow or not)

    At the moment I have somehow calculated the shadow by just projecting each triangle on the plane. At this point I'd need to rasterize it... but it appears like an hard job compared to OpenGL, where it's pretty easy and it rasterize them automatically. The problem is that the OpenGL output is only displayed on the screen.. while I'd need instead in a boolean matrix for example

  4. #4
    Member Regular Contributor
    Join Date
    Apr 2010
    Posts
    492

    Re: Calculating where the shadow falls on a plane

    One way to do this is to create a FBO (frame buffer object) that has the dimensions of your plane. You'd then set up rendering to go into that FBO instead of the usual application buffers (that are displayed on the screeen) and have your modelview/projection matrices perform the projection of triangles onto the plane. Clear the FBO to white, enable GL_MIN blending (glBlendEquation(GL_MIN)) and render the triangles in black. Then use glReadPixels() to read back the data to main memory or another buffer on the GPU (that buffer could use CUDA/GL interop to be shared with CUDA) depending on where you need to process the information. Black pixels are in shadow, white ones are not.

    Information on how to use FBOs can be found on the OpenGL wiki: FBO for example.

  5. #5
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    46

    Re: Calculating where the shadow falls on a plane

    Quote Originally Posted by carsten neumann
    One way to do this is to create a FBO (frame buffer object) that has the dimensions of your plane. You'd then set up rendering to go into that FBO instead of the usual application buffers (that are displayed on the screeen) and have your modelview/projection matrices perform the projection of triangles onto the plane. Clear the FBO to white, enable GL_MIN blending (glBlendEquation(GL_MIN)) and render the triangles in black. Then use glReadPixels() to read back the data to main memory or another buffer on the GPU (that buffer could use CUDA/GL interop to be shared with CUDA) depending on where you need to process the information. Black pixels are in shadow, white ones are not.

    Information on how to use FBOs can be found on the OpenGL wiki: FBO for example.
    After days spent looking for answer this looks the right solution! Thanks Carsten tomorrow I will try to apply it

  6. #6
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    46

    Re: Calculating where the shadow falls on a plane

    I am a little confused

    Do I need to render to texture anyway?
    Which attachment should I use? The color?
    What should I attach to the framebuffer, a texture image or a renderbuffer image?

    Unfortunately I didnt found any example that show clearly how to render off screen and save it as an image

    ( This user looks to had the same problem)

  7. #7
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    46

    Re: Calculating where the shadow falls on a plane

    Here at the end it says it doesnt matter if I attach a renderBuffer or a texture

    Do you have any suggest on which way should I use?

  8. #8
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    46

    Re: Calculating where the shadow falls on a plane

    Ok, I decided to opt for a renderBuffer

    here my code so far

    Code :
    private void renderShadows(GL2 gl)    {
            //  creating the FBO
            int[] frameBufferID = new int[1];
            gl.glGenBuffers(1, frameBufferID, 0);
     
            // bounding the FBO
            gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBufferID[0]);
     
            // creating the RenderBuffer Object
            int[] renderBufferID = new int[1];
            gl.glGenRenderbuffers(1, renderBufferID, 0);
     
            // bounding the RBO
            gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, renderBufferID[0]);
     
            // Allocate the RBO
            gl.glRenderbufferStorage(GL2.GL_RENDERBUFFER, GL2.GL_RGB, floorWidth, floorHeight);
     
            // Attaching the RB image (RBO) to the FBO
            gl.glFramebufferRenderbuffer(GL2.GL_FRAMEBUFFER, GL2.GL_COLOR_ATTACHMENT0,
                                                    GL2.GL_RENDERBUFFER, renderBufferID[0]);
     
            if(gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER) == GL2.GL_FRAMEBUFFER_COMPLETE)
                System.out.println("GL_FRAMEBUFFER_COMPLETE!!");
            else
                System.out.println("..[censored] ^^");
        }

    And so far it works , I get the frameBuffer complete

    But how can I go further now? How do I clean the FBO to white? And what about the pixel format?

  9. #9
    Intern Newbie
    Join Date
    Dec 2011
    Posts
    46

    Re: Calculating where the shadow falls on a plane

    Code :
    // save the current viewport and set the new
            gl.glPushAttrib(GL2.GL_VIEWPORT_BIT);
            gl.glViewport(0, 0, floorWidth, floorHeight);
     
            // bind the FBO
            gl.glBindFramebuffer(GL2.GL_DRAW_FRAMEBUFFER, frameBufferID[0]);
     
            int[] attachmentID = new int[1];
            attachmentID[0] = GL2.GL_COLOR_ATTACHMENT0;
            gl.glDrawBuffers(1, attachmentID, 0);
     
            // clear
            gl.glClear(GL2.GL_COLOR_BUFFER_BIT);
     
            gl.glBlendEquation(GL2.GL_MIN);
     
            gl.glColor3f(0.0f, 0.0f, 0.0f);
     
            // render
            gl.glBegin(GL2.GL_TRIANGLES);
                gl.glVertex3f(0.0f, 1.0f, 0.0f);
                gl.glVertex3f(1.0f, 0.0f, 0.0f);
                gl.glVertex3f(0.0f, 0.0f, 0.0f);
            gl.glEnd();
     
            gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
            gl.glReadBuffer(GL2.GL_BACK);
            gl.glDrawBuffer(GL2.GL_BACK);
     
            //  restore viewport
            gl.glPopAttrib();

    How can I render the FBO content on the screen to check it?

    This doesnt work:
    Code :
    gl.glBindFramebuffer( GL2.GL_FRAMEBUFFER, frameBufferID[0] );
            gl.glDrawBuffer(GL2.GL_COLOR_ATTACHMENT0);
            gl.glViewport( 0, 0, floorWidth, floorHeight );
            //gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            gl.glClear( GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );

  10. #10
    Member Regular Contributor
    Join Date
    Apr 2010
    Posts
    492

    Re: Calculating where the shadow falls on a plane

    If you attach a texture instead of a render buffer you can then use that texture on a quad rendered to the application frame buffer to look at it. Or you use glReadPixels() to transfer the pixels to main memory and write an image file.

    Is that last snippet meant to render to the screen? It binds the FBO and sets GL_COLOR_ATTACHMENT0 as draw buffer, so it draws to the FBO. To render to an application frame buffer, unbind the FBO (glBindFrameBuffer(GL_FRAMEBUFFER, 0)) and set the draw buffer to GL_BACK.

Posting Permissions

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