Tag Archives: Depth of Field

Close to deferring the deferred demo post…

Yeah, I was quite close to postpone the writing of this post to tomorrow, but I won’t. :)
The title is humorous but clear, my last demo deals again with deferred shading.

GLSL_deferred with SSAO, iterative parallax mapping and Depth of Field

This time I made every effort to do things right: there is support for directional, point and spot lights and, much more important for performances, lights are rendered only inside their influence volumes using projective texturing.
This means that while directional ones affect everything and have to be rendered as full screen quads, point lights are only rendered as cubes and spot lights as pyramids.

Comparison between disabled and enabled SSAO

This is slightly different from the usual approach taken, which uses spheres and cones but is also a bit more vertex heavy. :)
Rendering bounding shapes should barely affect performance, but makes the check for camera position a bit different.
The check is disabled by default as it is sufficient to cull front faces and invert the depth test to avoid double lighting issue and benefit from some depth optimization.
By enabling the check the application will expose my poor approximation of checking if the camera is inside a pyramid by using a formula meant for a cone, so better if it stays disabled, while the volume is not intersecting the far plane everything should behave as expected… :D

Comparison between normal mapping and iterative parallax mapping

The demo is also a bigger attempt into effects integrations, it will serve as a test bed for a more organized and high level framework.
As a matter of fact it also features Screen Space Ambient Occlusion, Iterative Parallax Mapping and Depth of Field.
Very cool stuff, but I already have a list of things that I would like to implement sooner or later, like a Light Pre-Pass, a couple of advanced shadow mapping techniques, the integration of water rendering, HDR illumination and the reconstruction of position from depth.

Normal rendering and Depth of Field blur

I have published the sources and a video (Vimeo | YouTube), that for the first time comes with a nice soundtrack: it’s Nova Siberia by Big Giant Circles (Jimmy Hinson) from OverClocked ReMix! ;)

Note: I have had a hard time with glc, x264, mencoder and ffmpeg but still YouTube doesn’t accept my video together with the sound, at the moment I have uploaded a mute version.

Blurring the parallax

Today I have published the first demo making use of my new C++ class library, I designed it to be very easily ported to a strict GL3 profile or to ES 2.0.

From plain rendering to depth of field

From plain rendering to depth of field

As a matter of fact, it doesn’t make use of fixed pipeline or deprecated functions at all:

  • No immediate mode, only VBOs
  • No use of OpenGL matrix stacks, I have my classes handling transformations and passing matrices to shaders directly
  • No OpenGL lighting, only per-fragment one
  • No quads or polygons, just triangles
Normal versus parallax mapping

Normal versus parallax mapping

I couldn’t release something only to show changes “under the hood”, I had to make something cool, so I decided to mix together parallax mapping (that, as you can see in the screenshot, is a lot more pronounced now) and depth of field, with the little addition of Stanford PLY mesh loading. :D

Mr.Fixit model and maps (the character players portray in Sauerbraten) are courtesy of John Siar, thank you John. ;)

As usual, you can have a look to Vimeo videos (640×480, 1280×720) and download the sources.

Depth of field reloaded

Lately I’ve been really disappointed by the poor performances of my first depth of field implementation, thus I decided to do something about it…

glsl_dof2

The most natural step to do was to give a look to the second Direct3D example from the same paper I used for the first one, as I was sure it would have led to more satisfactory results.
I spent the two last nights converting, correcting and fine tuning it, but I was rewarded by the fact that I was right: even if it is a five passes algorithm which is using four different Frame Buffer Objects, it is about 2.5 times faster than my previous implementation!

I think the speed boost depends on the two following:

  1. image blurring is achieved by a gaussian filter which is calculated separating the X from the Y axis, it is an approximation of a standard 2D kernel but it also means that the convolution matrix calculation complexity decreases from a quadratic to a linear factor.
  2. this filter operates only on a downsampled (1/4th of the screen resolution actually) FBO

Another nice note about this new implementation is that there are only two focal parameters, focus depth and focus range, which really help to setup a correct scene.

Now let’s review the five passes in detail:

  1. Render the scene normally while calculating a blur amount per-vertex, then store the interpolated value per-pixel inside the alpha component of the fragment.
    The calculation at the vertex shader is just:

    Blur = clamp(abs(-PosWV.z - focalDistance) / focalRange, 0.0, 1.0);
    
  2. Downsample the scene rendered at the previous pass storing it in a smaller FBO
  3. Apply the gaussian filter along the X axis on the downsampled scene and store it in a new FBO
  4. Apply the gaussian filter along the Y axis on the already X blurred scene and store it in a new FBO
  5. Calculate a linear interpolation between the first full resolution FBO and the XY downsampled blurred one
    This is performed in the fragment shader as:

    gl_FragColor = Fullres + Fullres.a * (Blurred - Fullres);
    

Again, you can view it in action on my YouTube Channel, or in a high definition 720p version hosted on my Vimeo page. ;)

I love depth of field

I consider depth of field as one of the most beautiful post-processing effects of the “next-gen” games.
It was natural for me to choose it as the first shader demo to implement after months of inactivity, as a matter of fact GLSL_impgro was really just a testbed for post-processing basic techniques, like Frame Buffer Objects.

GLSL_DoF

I have studied the theory from an ATI paper included in the ShaderX2 book, titled Real-Time Depth of Field Simulation, I have choosen the first of the two different implementation and converted it from Direct3D and HLSL to OpenGL and GLSL.

Of course, being a post-processing effect, the rendering is actually divided in two pass:

  1. Rendering the scene storing the depth of every vertex and calculating the amount of blur per fragment
  2. Applying the blur per fragment based on the value from the previous step

The second pass fragment shader, the one which is really applying the blur effect, is slow even on my 8600GT, because it performs several calculations for every one of the twelve fragments that are contributing to the blur of the center one.

Another interesting aspect is that, in order to calculate a correct approximation of the circular blur needed for circles of confusion simulation, these twelve pixel are sampled around the center based on a poissonian disc distribution, thus creating much less artifacts than a small convolution matrix scaled too much in order to sample from far away the center.

Just like the previous demo you can view it in action on my YouTube Channel, but I really suggest you to give a look to the high definition 720p version instead, hosted together with the other ones on my Vimeo page. ;)