Graphics Programming

피사계 심도(Depth Of Field) 본문

Season 1/OpenGL

피사계 심도(Depth Of Field)

minseoklee 2018. 5. 4. 21:46


불칸 책을 다 읽고 뭔가를 만들려고 보니 코딩 분량이 너무 막막해서 예전에 버린 OpenGL 프로젝트를 다시 꺼내들었다.

PBR을 조금 알아봤는데 계산만 복잡하지 기존의 블린-퐁 셰이딩과 구현 방법이 별로 다르지 않아서 이거나 해볼려고 했는데 프로젝트를 열어보니 DOF를 만들다 말았었다.


DOF는 대략 이런 식으로 구현한다.

1. 일단 장면을 그린다.

2. 장면 텍스처의 subsum을 컴퓨트 셰이더로 계산한다.

3. subsum을 가지고 박스 블러를 계산한다. 이 때 박스 블러의 세기는 각 픽셀의 깊이값을 가지고 결정한다.


뷰에 의존적인 이펙트여서 뷰 스페이스에서 픽셀의 z값을 가지고 계산해야 하는데 내 디퍼드 렌더러를 가만히 보니 라이팅 계산을 월드 스페이스에서 하고 있다.


다행히 추가로 바꿀 것은 별로 없었다. 버텍스 위치 외에 월드 스페이스에서 뷰 스페이스로 바꿀 것이 eye 벡터와 라이트 방향/위치 밖에 없었다. 테두리의 검은색은 뭔지 모르겠다. 큰 메시가 테두리 위로 그려지는 걸 보니 샘플링을 잘못해서 그런 건 아닌 거 같은데...;


깃헙을 열어보니 7개월만에 커밋했다. 올해 세운 목표 단 2개 중 하나가 OpenGL Super Bible 다 읽고 다 만들어보기인데 너무 게으르다.




검은색 테두리 때문에 한참을 고민하다 책 데모를 열어보니 이건 배경이 검은색이다.


그리고 subsum 텍스처를 샘플링하는 건데 입력 범위가 0.0 ~ 1.0인 textureLod()로 샘플링을 하고 있다. 아니 필터링이 GL_NEAREST이면 상관 없긴 한데... 아무튼 샘플링 좌표를 (0,0) ~ (width-1, height-1)로 자르고 texelFetch()로 샘플링한 다음 영역합 넓이도 알맞게 계산해서 나눠준다. 테두리에서는 영역합의 넓이가 좁아지기 때문이다.



검은색 테두리가 거의 사라졌다. 1픽셀은 남아있는 거 같은데 texelFetch()를 써서 샘플링하는 네 점이 모두 같아 영역합이 0이 나오기 때문일 것이다. 크게 눈에 띄진 않으니 그냥 넘어가고...


GTX 1070에서 1920x1080으로 돌리다가 GTX 750에서 돌리니 60프레임이 안 나와서 해상도를 800x600으로 줄여야했다. 겨우 이거 그리는데 1920x1080 60fps가 안 나오는 걸 보니 최적화도 한참 해야 한다.

Comments