Jump to content
  • Advertisement
Sign in to follow this  
JasperBekkers

Understanding the Starcraft II depth of field paper

This topic is 2854 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I'm trying to implement the Starcraft II Depth of field shader as detailed in this paper and I'm struggling to understand some parts of it; primarily the description of how they generate the medium blurred image.

Quote:
Generate the medium blur image by applying a RGB Gaussian blur with each sample weighted by the CoC (Circle of Confusion) on the source image


From how I understand it, a Gaussian blur always weights the pixel values following a Gaussian function with a kernel varying in size depending on how blurry the image should be (the blur radius).

How do I fit in the Circle of Confusion process?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by JasperBekkers
Hi,

I'm trying to implement the Starcraft II Depth of field shader as detailed in this paper and I'm struggling to understand some parts of it; primarily the description of how they generate the medium blurred image.

Quote:
Generate the medium blur image by applying a RGB Gaussian blur with each sample weighted by the CoC (Circle of Confusion) on the source image


From how I understand it, a Gaussian blur always weights the pixel values following a Gaussian function with a kernel varying in size depending on how blurry the image should be (the blur radius).

How do I fit in the Circle of Confusion process?


Hi Jasper,

the way gaussian blur works is that you multiply each sample with the gaussian weight and divide it by the sum of all weight values from all the samples. Since the gaussian weights are often normalized already (they sum up to 1) the division is not necessary. Now with the coc weights its exactly the same. You multiply the sample by the coc value. But now the coc values are not normalized (they dont sum up to 1) so you have to divide each samples coc value by the sum of all coc-values before you multiply it with the sample.

That sounds much more complicated than it is. Here is the glsl source for the horizontal dof blur. The way I do it here is that I add up the gaussian weights to the coc weights and then divide them by the sum to normalize them. So the order is different:

varying vec2 uv;
uniform sampler2D input; // image
uniform sampler2D coc; // coc's computed in previous step

uniform float pixelStep; // 1.0/yres

void main(void)
{
vec3 sum = vec3(0.0);


float coc0 = texture2D(coc, vec2(uv.x - 4.0*pixelStep, uv.y)).w + 0.05;
float coc1 = texture2D(coc, vec2(uv.x - 3.0*pixelStep, uv.y)).w + 0.09;
float coc2 = texture2D(coc, vec2(uv.x - 2.0*pixelStep, uv.y)).w + 0.12;
float coc3 = texture2D(coc, vec2(uv.x - pixelStep, uv.y)).w + 0.15;
float centerCOC = texture2D(coc, vec2(uv.x, uv.y)).w;
float coc4 = centerCOC + 0.16;
float coc5 = texture2D(coc, vec2(uv.x + pixelStep, uv.y)).w + 0.15;
float coc6 = texture2D(coc, vec2(uv.x + 2.0*pixelStep, uv.y)).w + 0.12;
float coc7 = texture2D(coc, vec2(uv.x + 3.0*pixelStep, uv.y)).w + 0.09;
float coc8 = texture2D(coc, vec2(uv.x + 4.0*pixelStep, uv.y)).w + 0.05;

float cocSum = 0.0;
cocSum += coc0;
cocSum += coc1;
cocSum += coc2;
cocSum += coc3;
cocSum += coc4;
cocSum += coc5;
cocSum += coc6;
cocSum += coc7;
cocSum += coc8;

coc0 /= cocSum;
coc1 /= cocSum;
coc2 /= cocSum;
coc3 /= cocSum;
coc4 /= cocSum;
coc5 /= cocSum;
coc6 /= cocSum;
coc7 /= cocSum;
coc8 /= cocSum;


// blur in x (horizontal)
sum += texture2D(input, vec2(uv.x - 4.0*pixelStep, uv.y)).xyz * coc0;
sum += texture2D(input, vec2(uv.x - 3.0*pixelStep, uv.y)).xyz * coc1;
sum += texture2D(input, vec2(uv.x - 2.0*pixelStep, uv.y)).xyz * coc2;
sum += texture2D(input, vec2(uv.x - pixelStep, uv.y)).xyz * coc3;
sum += texture2D(input, vec2(uv.x, uv.y)).xyz * coc4;
sum += texture2D(input, vec2(uv.x + pixelStep, uv.y)).xyz * coc5;
sum += texture2D(input, vec2(uv.x + 2.0*pixelStep, uv.y)).xyz * coc6;
sum += texture2D(input, vec2(uv.x + 3.0*pixelStep, uv.y)).xyz * coc7;
sum += texture2D(input, vec2(uv.x + 4.0*pixelStep, uv.y)).xyz * coc8;

gl_FragColor.xyz = sum;
gl_FragColor.w = centerCOC;
}



Let me know if you have any further questions. It works quite well.

David

P.S.: the plus sign is not displayed in preview of that post...I hope it will show up

Share this post


Link to post
Share on other sites
Quote:
Original post by skydave
Quote:
Original post by JasperBekkers
Hi,

I'm trying to implement the Starcraft II Depth of field shader as detailed in this paper and I'm struggling to understand some parts of it; primarily the description of how they generate the medium blurred image.

Quote:
Generate the medium blur image by applying a RGB Gaussian blur with each sample weighted by the CoC (Circle of Confusion) on the source image


From how I understand it, a Gaussian blur always weights the pixel values following a Gaussian function with a kernel varying in size depending on how blurry the image should be (the blur radius).

How do I fit in the Circle of Confusion process?


Hi Jasper,

the way gaussian blur works is that you multiply each sample with the gaussian weight and divide it by the sum of all weight values from all the samples. Since the gaussian weights are often normalized already (they sum up to 1) the division is not necessary. Now with the coc weights its exactly the same. You multiply the sample by the coc value. But now the coc values are not normalized (they dont sum up to 1) so you have to divide each samples coc value by the sum of all coc-values before you multiply it with the sample.


That was what I needed to hear, thank you!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!