# Understanding the Starcraft II depth of field paper

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

## 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 on other sites
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; // imageuniform sampler2D coc; // coc's computed in previous stepuniform float pixelStep; // 1.0/yresvoid 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 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!

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
13
5. 5
frob
12

• 9
• 9
• 11
• 11
• 23
• ### Forum Statistics

• Total Topics
633665
• Total Posts
3013246
×