Saturday, April 7, 2012

Another Bokeh Technique

hi all

last post i talked about bokeh effect done inside pixel shader using special bokeh kernel, this time i will talk about more generic technique for doing bokeh.
first lets talk about whats wasn't good in the pixel shader technique.
in my engine i say i have film dof effect, what this means is that i can set almost any size of kernel per pixel! this means i'm not suffering from depth difference and stuff like that.
i can set one pixel to be blurred by radius 5, and the next pixel beside by radius 100, without any artifacts... (as long i will not get crazy with kernel radius)

anyway, because the ps technique is some kind of blur technique, if i will inject it to my engine on top of my dof, it will 'erase' my 'perfect' blur technique, because it is a blur, but not smarter than what i already have.

so if you don't have any dof/blur solution yet, it will probably be good for you, if you have some kind of smart blur, it probably wont.

so is there any thing we can do to add bokeh effect without dx10,11?
yes there is...
on the last post i said few words about a technique to generate bokeh using vertex shader, here i will write some detail about it and show some images from the engine.

this new technique uses the vertex shader to generate bokeh sprites/billboards, the steps to do this is:
* create big vertex shader containing 4 vertices per pixel!, yes you are reading it correct, 4 vertices per pixel...
* inside vs, you generate the quad vertices based on some math, this math will actually use some circle of confusion values and your current image, so you can set bokeh color and size.
* inside ps, you just sample your bokeh texture, can be any shape you like, and use the color you output from the vs, to set its intensity etc.

technique pros:
* very easy to do
* support any bokeh shape
* dx9 hardware (shader model 3)
* work hand by hand with any dof/blur technique
* very fast

technique cons:
* takes lots of vertex memory (depends on your size)
* vertex shader heavy (basically not a problem as we are more ps heave than vs)
* can be slow if you won't filter them in a good way, you don't want to generate bokeh for every pixel in the screen, this can be nasty! i got blur screen on win 7 ;)

here is few screenshots (not compressed) from the engine that's shows it in action, you could also see the film dof effect with very large coc to enhanced the effect (kernel radius of 80 for far pixels)

orignal image (no dof, no bokeh)

film dof (no bokeh)

pentagonal bokeh

hexagonal bokeh

circle bokeh

star bokeh

that's it, very simple and very fast! cya until next time...


Sander van Rossen said...

You say it's fast, but you never mention any numbers .. now I'm curious how many ms it took & what hardware you where using etc. ;)

orenk2k said...

Hi sander
you are right, didn't post numbers.
i need to add some gpu profiling code to my engine...
so how do i know if its fast you ask?
in this example i did two things:
1. compare both techniques in render monkey, checks fps and quality on few images and sizes.

2. if the technique looks good in RM, i'm injecting it to my engine and compare quality and speed here all effects and stuff running side by side, this is my key test, as one technique could look promising in RM but not so good in my engine, where you move your camera and check it with other post effects - as i wrote, ps technique wasn't so great inside engine working with my dof effect.

as for my hardware:
my gpu is very old one, little geforce 240 gt ddr3 - not bigger than a mouse :P
RM numbers on 800x600 window on my card:
PS tech - 190-194
VS tech - 170-174
so i can tell its about 10% slower if i'm using the same kernel size. when kernel size is big, something like 20+, ps tech shows some artifacts as i'm not using lots of samples to create bokeh shape (only 30)
VS tech takes it all the way, nothing to compare really.
the quality and speed of VS tech is much much better...
hope this clears few things.