Blur 1

반응형

이전에도 blur를 한번 정리한적이 있긴 한데 다시 보다보니 이전에 적어둔 글에서

잘못된 부분이 있어서 처음부터 다시 r&d 하면서 정리를 하게 되었다.


블러링 방식은 크게 box blurgaussian blur 이 두가지로 나뉜다.

box blur는 16box, 64box, 9cone 방식이 있고

gaussian은 전통적인 gaussian 방식과 최적화시킨 SGX방식이 있다.


많이 쓰이는 9cone과 gaussian, 그리고 sgx만 간단하게 살펴보자


9cone blur

9cone의 기본 개념은 현재점을 중심으로 상,하,좌,우,상좌,상우,하좌,하우 

이렇게 기준점 + offset points(8) 값을 합치는 것이다.


원본 이미지


1/4 downsampling 한 이미지


1/4 downsampling + 9cone blur 한 이미지



위 사진들을 보면 그냥 다운샘플링한 이미지는 산쪽에 이미지 톱니현상이 눈에 많이 띄지만 

블러를 한 결과물은 조금 더 부드러워 지는것을 알 수 있다.


구현방법

float off = 1.0f;

Graphics.BlitMultiTap(src, dest, material_, new Vector2(-off, -off), new Vector2(-off, off),

new Vector2(off, off), new Vector2(off, -off));

그냥 알기쉽게 (-1,-1), (-1,1), (1,1), (1,-1) 이렇게 네개의 지점(파란색을 기준으로 한다.


셰이더 코드에서는 이 각 점에 대해 위 그림과 같이 다시 네 지점(빨간색)의 값을 참조하여 섞어준다.

shader-vertex code

o.taps[0] = v.texcoord.xy - (_MainTex_TexelSize.xy * _BlurOffsets.xy) + _MainTex_TexelSize.xy * _BlurOffsets.xy;

o.taps[1] = v.texcoord.xy - (_MainTex_TexelSize.xy * _BlurOffsets.xy) - _MainTex_TexelSize.xy * _BlurOffsets.xy;

o.taps[2] = v.texcoord.xy - (_MainTex_TexelSize.xy * _BlurOffsets.xy) + _MainTex_TexelSize.xy * _BlurOffsets.xy * half2(1,-1);

o.taps[3] = v.texcoord.xy - (_MainTex_TexelSize.xy * _BlurOffsets.xy) - _MainTex_TexelSize.xy * _BlurOffsets.xy * half2(1,-1);


shader-fragment code

fixed4 frag(v2f i) : SV_Target 

{

half4 color = tex2D(_MainTex, i.taps[0]);

color += tex2D(_MainTex, i.taps[1]);

color += tex2D(_MainTex, i.taps[2]);

color += tex2D(_MainTex, i.taps[3]);

return color * 0.25;

}


이러한 과정을 각 파란점마다 하면 아래와 같은 결과가 된다.

빨간점 옆의 숫자는 빨간점이 몇번이나 중복되는지를 나타내는 값이다.


그 이후에는 이 downsampling + 9cone  blur 된 이미지를 가지고

9cone blur를 얼마나 더 반복해줄 건지만 정하면 된다.

한 예로 아래 이미지는 결과 텍스처를 5번 반복해서 9 cone sampling 해 주었는데.

0.5, 1, 1.5, 2, 2.5 이렇게 0.5씩 늘려가며 픽셀값을 가져왔다.





downsampling

이 작업은 최적화를 위해 많이 사용하는 기술이다.

내용자체는 간단한데 무거운 postprocess 기술의 경우 렌더링 시간이 많이 걸리므로

렌더텍스처의 사이즈를 줄여서 연산량을 줄이자는 내용이다.

만약 가로세로 크기를 반으로만 줄여도 계산량은 1/4로 줄어든다.

downsampling(다운샘플링)을 할 경우 두가지 선택사항이 있다.


첫번째는 그냥 다운샘플링만 해서 후에 blur를 으쌰으쌰 하는 것.


사진 출처 : nvidia

simple downsampling은 단순히 하드웨어의 bilinear filtering을 사용한다.

이 그림에서 f 픽셀이 1,2,3,4 텍셀값을 평균한 값임을 알 수 있다.




두번째는 다운샘플링시 엘리어싱 현상을 줄이기 위해 filtering를 해주는 것.

사진 출처 : nvidia

두번째 기술은 다운샘플링시 fetching으로 추가로 sample(b,c,d,e)들을 필터로 더하는 방식이다.

최종 색상값은 다섯개의 sample들의 평균을 normalized한 색상이다.



단순히 simple downsampling와 filter downsampling만 비교하였는데 실제로

아래 nvidia 문서에 있는 more filter downsampling 까지 하여 비교스샷을 보면

결과물이 상당히 다르다.

엘리어싱이 없이 최대한 부드럽게 흐려지는 이미지를 구하기 위해 

가장 좋은 방법은 downsampling 없이 소실되는 픽셀없이 모두 사용하여 

평균시키는 방법이겠지만 여기에 최적화라는 단어를 붙인다면

고민해야할 부분이 잔뜩있고, 선택해야할 문제 또한 잔뜩있다.


가우스와 sgx는 다음 글에서....


잘못된 부분은 댓글로 적어주시면 감사하겠습니다 ^^a..


Reference Link

- BlitMultiTap

- mgun blur

- 16 box blur

- 64 box blur

- 9cone blur (잘못된 부분 수정 예정.)

- gaussian blur 

- sgx blur

- 선형 보간법(linear, bilinear, trilinear interpolation)

- unity doc - RnderTExture.GetTemporary

- Nvidia - Hight Quality Antialiasing

FroggyAA.pdf


-

'Study > Graphics ' 카테고리의 다른 글

rgbm  (0) 2016.12.29
Efficient Gaussian blur with linear sampling  (0) 2016.10.22
UV Texture Coordinates and Texture Mapping - OpenGL / DirectX  (0) 2016.08.14
normal map compression  (0) 2016.06.13
Semantics  (0) 2016.05.09
TAGS.

Comments