Saturday, April 23, 2011

April 23, Project End

Hi guys,
It's been a fun and fruitful semester.  The submission for this project includes a paper, video, poster, and source code.  All of these should appear below:

Paper: http://www.stuartsummerfield.com/shadowspaper.pdf
Poster: http://www.stuartsummerfield.com/shadowsposter.pptx
Video: http://www.stuartsummerfield.com/shadowsvideo.wmv
Source: http://www.stuartsummerfield.com/shadowsproj.zip

Wednesday, April 20, 2011

Final Stretch Update April 20

Hi guys,
So I made an attempt to do shadow volumes this week. At first I wanted the shadow volumes to be simple like extending some triangles to infinity to form cylinders to implement a kind of "drop shadow" which is sometimes implemented in multiplayer games as the "lowest" quality dynamic shadow rendering technique where FPS and performance is extremely important and gamers won't sacrifice quality if it drops their fps below say... 50 fps. Here's a pic of my cylinders to be used as shadow volumes, which change depending on the direction of the light.
After getting the volumes, I found a project that implemented shadow volumes and attempted to integrate the code to make it work. The code I scrapped together to draw the shadow volumes looked something like this...

void Terrain::DrawVolumes()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glClearColor(sky_color[0], sky_color[1], sky_color[2], sky_color[3]);

    //Draw ambient
    glPushAttrib(GL_ENABLE_BIT);
    glEnable(GL_COLOR_MATERIAL);
    glLightfv(GL_LIGHT1, GL_POSITION, light_pos);
    glLightfv(GL_LIGHT1, GL_AMBIENT, sky_color_div);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, sky_color_div);
    glLightfv(GL_LIGHT1, GL_SPECULAR, black);
    glEnable(GL_LIGHT1);
    glEnable(GL_LIGHTING);

    drawObjects() // terrain, static, and animateable

    //Draw shadow volumes
    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glColorMask(0, 0, 0, 0);
    glShadeModel(GL_FLAT);
    glDepthMask(0);
    glDepthFunc(GL_LESS);
    glEnable(GL_STENCIL_TEST);

    glPushMatrix();
    glTranslatef(-half_width, 0, -half_height);

    // Shadow Volumes
        for(unsigned int i=0; i<1; i++)
        {
            //using zpass
            //Increment stencil buffer for front face depth pass
            glStencilFunc(GL_ALWAYS, 0, ~0);
            glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
            glCullFace(GL_BACK);

            // Draw Shadow Volume Objects
            DrawCylinders();

            //Decrement stencil buffer for back face depth pass
            glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
            glCullFace(GL_FRONT);

            // Draw Shadow Volume Objects
            DrawCylinders();
        }   
    glPopMatrix();
    glPopAttrib();

    //Now draw lit where stencil == 0
    glPushAttrib(GL_ENABLE_BIT);
    glEnable(GL_COLOR_MATERIAL);
    glLightfv(GL_LIGHT1, GL_POSITION, light_pos);
    glLightfv(GL_LIGHT1, GL_AMBIENT, sky_color_div);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, sky_color);
    glLightfv(GL_LIGHT1, GL_SPECULAR, white);
    glEnable(GL_LIGHT1);
    glEnable(GL_LIGHTING);
    glStencilFunc(GL_EQUAL, 0, ~0);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glEnable(GL_STENCIL_TEST);

   drawObjects();
}

Unfortunately I wasn't getting any shadows, even after initializing openGL differently. I then thought, maybe drawing cylinders using gluQuadricObjects wasn't valid, so I drew a single triangle and extended its 3 edges to infinity by drawing 3 quads. I was able to see the 3 faces of this triangle without endcaps, but wasn't able to get a triangle of shadow.
I'm giving up on rendering shadow volumes for now, as I'd like to explore more shadow mapping techniques before the deadline for this project, which is next week. Although it's somewhat demoralizing to spend about 15 hours attempting to get shadow volumes working without much to show for the effort, I've learned that one of the biggest disadvantages to shadow volume rendering is implementation difficulty. Even had I been able to get the single triangle working, there's still several cases I hadn't handled like the viewport being inside a shadow volume, for example. Also the fps wasn't looking very promising even with drawing the cylinders, let alone extending silhouette edges for somewhat complicated 3d models. Stay tuned for the final!

Monday, April 11, 2011

Checkpoint April 11

Things Accomplished Thus Far...

Find a base project, which has a few static objects, cascade shadow mapping, and PCF implemented already
Added more objects 400, 265 triangle birds
Animated the birds
Added FPS counter
Added a way to toggle on and off, cascade shadow mapping.
Made some FPS comparisons

High Priority Items:
Variance Shadow Mapping
Perspective Shadow Mapping
Most efficient algorithm possible for the scene
    -Baking shadows in for static objects via light maps
    -Simple shadow volumes with cylinder for each animate-able object
    -Very low resolution single shadow map

Pic of Demo thus far...




Video of Demo thus far:
http://www.stuartsummerfield.com/Checkpoint.mp4
Checkpoint Presentation:
http://www.stuartsummerfield.com/Checkpoint.ppt

Wednesday, April 6, 2011

Update April 6

After doing my presentation on shadows, I discovered it is probably best to use the NVIDIA SDK for Cascade Shadow Mapping as my project base. I just need to add a bunch of animate-able objects, then I will implement other shadow rendering techniques, like drop shadows which look worse but perform much better than the current shadow map implementation. Pic of the Demo:

 

My presentation on various rendering techniques can be downloaded here
http://www.stuartsummerfield.com/Shadows.mp4
Alternatively you can get just the slides
http://www.stuartsummerfield.com/Shadows.ppt

A short video of the Nvidia Cascade Shadow Mapping demo is included near the end of the presentation.

Wednesday, March 30, 2011

Seeking good base project(s)

The search continues for a decent project to serve as the base for my various shadow implementations.  Ideally I would not like to have to do all the work to make a scene graph instantiating 100+ 3d models that move around in a non-trivial static environment.  I have emailed the creator of the iterinix engine for crowd simulation, hoping to get a basic version sent to me as source code, if not I'll have to do some more searching or make my own scenegraph. This YouTube video shows the IterInix engine, which is something similar to what I'm lookng for.
I will begin to do most of the research for my Shadows presentation on Monday in the next few days. The search process might end or be expedited by the time I finish the research and presentation on Monday. That is all for this week, stay tuned!

Wednesday, March 23, 2011

Project Proposal

The project proposal on shadows was submitted and approved! The next step must be to acquire one or more visual studio projects with 100ish moving characters with a shadow map and/or shadow volume implementation.

Proposal-

        The goal of this project is to reduce performance implications for shadow rendering. The need arises from the fact that many games’ shadow rendering methods result in too large of an FPS decrease for users to even bother using. Most conventional shadow rendering is done by a technique known as shadow volumes. Volumes are constructed using silhouette edges and rendered into a stencil buffer. This is repeated for each light source and the resulting images are combined to form a final frame, a process called multi-pass rendering. This idea is by no means novel and has been used for decades with various optimizations and tweaks increasing performance over the years.  This technique is slow because it requires many passes and shadow volume construction which consists of quickly finding silhouette edges, usually stored as additional information in the vertex buffer, and must be transformed to infinity.

        The first step of the project will be to attain a visual studio C++ project that consists of a scene with several moving objects illuminated by one or more point light sources. This project will have the option of turning shadows on which will use a conventional shadow rendering technique. Turning shadows on will reduce FPS from say 60 to 40. The goal of the project will be to be able to turn on an additional, perhaps less physically accurate shadow rendering mode which results in a non noticeable drop in FPS. One idea that might attain the goal of this project is to render shadows as a post processing effect. Inspired by screen space ambient occlusion, I propose gathering randomly distributed occlusion samples that lie within a cone from the sample point to each light source. Determining the number of points in the cone that occlude the sample point and weighting them in different ways might be a way to estimate whether the point should be in shadow. An additional technique that I have seen in some games is to render shadows quickly on a large number of objects is to use drop shadows. I have still noticed a significant performance impact in using simple drop shadows, although much less worse so than using regular shadows. Since drop shadows are simple dark circles underneath each object, it should be a simple matter of doing drop shadows as a post processing effect on the GPU. Regardless of the method, I firmly believe there should be a way to render shadows or at last an approximation with absolutely no performance hit. This project will attempt to discover and implement that method in a scene with many dynamically moving objects.