Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

승쨩개발공부

[SR] 버퍼(Buffer) 본문

SR

[SR] 버퍼(Buffer)

Unknowns 2022. 5. 24. 21:52

프레임 버퍼

그래픽 카드 VRAM에는 Frame Buffer라는 영역이 존재한다.

Frame Buffer는 전면 버퍼(Front Buffer) 후면 버퍼(Back Buffer)가 존재한다.

그래픽 카드가 없다면 DirectX가 내부적으로 생성해서 사용한다.

전면 버퍼와 후면 버퍼가 서로 계속 교환되며 화면의 출력된다

후면 버퍼는 색상 버퍼, 깊이 버퍼, 스텐실 버퍼로 분류되는데 일반적으로 깊이 스텐실 버퍼는

하나로 묶어서 사용한다.

깊이 버퍼에 24비트, 스텐실 버퍼에 8비트를 주고 합해서 32비트를 사용한다.

물론 깊이 버퍼만 사용하는 것도 가능하다.

 

 

 

 

수직 동기화

수직 동기화가 뭐냐면 그래픽 카드의 렌더링 갱신 속도를 모니터의 출력 갱신 속도에 맞춘다는 의미이다.

더블 버퍼링이 모니터의 깜빡임을 방지하는 기법이라면 수직 동기화는 프로그램을 좀더 퀘적하게 해주는 기법이다. 더블 버퍼링과는 관계가 없다.

 

일반적으로 모니터는 재생률(주사율, Refresh Rate) 60Hz로 설정이 되어있다.

재생이라는 건 모니터의 출력 갱신 속도를 말하고 이게 60Hz니까 초당 60번 갱신하게된다.

 

게임은 60FPS와 30FPS가 대부분이다. FPS(Frame Per Second) 는 초당 프레임 수 를 의미한다

여기서 말하는 60FPS는 게임의 갱신 속도를 말한다 렌더링이 될 수도 있고, 네트워크가 될 수도 있다.

 

모니터의 재생률이 60Hz라고 할 떄 컴퓨터 성능이 너무 좋아서 200FPS로 돌아간다면

실제로 컴퓨터는 200FPS에 맞게 일을 하지만 모니터는 60FPS에 맞게 일을 하게된다. 즉

결과적으로 손해이다.

하지만 수직 동기화를 활성화하면 컴퓨터의 성능이 아무리 좋아도 60FPS에 맞게 일을 하게된다

반대로 게임이 너무 고사양이라 컴퓨터 사양이 따라가지 못한다면 수직 동기화를 비활성화 하는것이 좋다

모니터의 재생률은 60Hz 그대로인데 개임 갱신 속도를 억지로 맞춰야 하니까 프레임이 개박살이난다.

 

 

 

 

 

 

후면 버퍼와 전면 버퍼

후면 버퍼는 프로그래밍의 핵심이다.

후면 버퍼는 색상 버퍼, 깊이 버퍼, 스텐실 버퍼 이렇게 3가지로 분류된다.

하지만 전면 버퍼는 색상 버퍼만 사용한다, 어차피 후면 버퍼에서 랜더링이 끝난 상태가

곧 색상 버퍼이기떄문이다.

깊이 버퍼와 스텐실 버퍼는 3D를 렌더링하기 위한 보조 버퍼라고 생각하면 된다.

우리가 실제로 모니터로 보는 건 색상 버퍼뿐이다.

후면 버퍼만 프로그래밍이 가능한데 후면 버퍼를 이용하면 렌더링에 관여할 수 있다.

어떤 텍스처를 프로그램에 로딩하고, 후면 버퍼를 이용해서 그 텍스처에 이런저런 작업을

할 수 있게된다.

일렁이는 효과, 왜곡되는 효과를 주기도 하는데 그런 것들은 후면 버퍼에서 처리한다.

 

 

색상 버퍼

색상 버퍼(Color Buffer)는 실제로 모니터에 출력할 크기만큼 픽셀(Pixel)을 갖고 있는 버퍼이다.

색상 버퍼에는 렌더링된 최종 결과물이 저장되므로 그걸 그대로 모니터에 출력하면 된다.

좀더 자세히 설명하자면 색상 버퍼에 서피스(Surface)에 저장된 픽셀들을 모니터에 출력 하는 것이다.

서피스는 픽셀들이 모여있는 버퍼를 말하는데 픽셀들이 모여있다는 건 렌더링 대상이 된다는 애기와 같다.

 

이것을 랜더 타겟(Render Taget)이라고 하는데 렌더 타겟은 출력이 아니라 랜더링 할 대상이라는 걸

알아야 한다. 즉, 전면 버퍼가 아니라 후면 버퍼가 렌더 타겟이 된다.

랜더 타켓은 인덱스로 관리되는데 후면 버퍼의 인덱스가 0이다.

따라서 렌더 타겟이 0번인 후면 버퍼의 서피스에 렌더링이 된다.

후면 버퍼는 iDirect3DDevice9::GetBackBuffer()를 이용하면 가져올 수 있는데 여기에 서피스가 사용된다.

 

 

 

 

 

깊이 버퍼

깊이 버퍼(Depth Buffer)는 3D를 표현하는 기법 중 하나이다.

우리가 원하는 건 3D지만 모니터는 2D이다. 즉, 2D를 이용해서 3D처럼 보이게 만들어야 한다.

실제로는 3D를 연산한 뒤에 2D로 랜더링하게 된다. 색상 버퍼와 햇갈릴 수 잇는데 깊이 버퍼에는

픽셀이 없다.

 

깊이 버퍼에는 왜 숫자가 있느냐?

깊이 버퍼에 저장되는 값은 각 픽셀의 깊이값을 의미한다

각 픽셀의 깊이값을 서로 비교해서 마치 앞뒤가 존재하는듯한 효과를 만들어준다.

 

실제 출력되는 이미지를 보면 도형들의 앞뒤를 구분할 수 있는데 이렇게 만들어 주는게

깊이 버퍼의 역활이다.

 

앞에 있는 효과를 보여주려면 깊이값이 작아야 하고, 뒤에 있는 효과를 보여주려면 깊이값이 커야한다.

깊이값은 0 ~ 1로 고정되어있는데 이렇게 값의 범위가 고정된 것을 정규화(Normalization)라고 한다.

왜 깊이값이 0 ~ 1로 고정되느냐? 어떤 수학적인 계산에 의해 값으 범위가 고정되게된다.

깊이 버퍼에 저장된 깊이값을 서로 비교하는 깊이 테스트(Depth Test)를 하고

깊이 테스트를 통과하게 되면 깊이 기록(Depth Write)을 하게된다.

내가 그릴려고 했던 깊이가 꺼내온 깊이보다 작으면 깊이 테스트를 통과하고

깊이를 기록하고 화면에 찍는다.

깊이 테스트를 통과 못한 픽셀은 그리지 않는다.

참고로 깊이버퍼 사이즈는 색상버퍼 사이즈와 꼭 반드시 같아야한다.

 

3D 렌더링은 곧 2D 랜더링이 된다.

3D 정보를 2D 정보로 변환해줘야 하는데 최종적으로는 3D정보가 2D 픽셀이 된다.

3D 정보 -> 2D 픽셀이 되는 것을 레스터화 즉 렌더링 파이프라인 레스터라이즈 라고 한다.

 

 

 

스텐실 버퍼

 스텐실 버퍼(Stencil Buffer)는 깊이 버퍼와 비슷하게 보이는데 정확히는 다르다.

깊이 버퍼가 깊이값으로 앞뒤를 구분하는 것이었다면, 스텐실 버퍼는 렌더링에서 제외할 픽셀을

기억하는 버퍼이다.

스텐실 테스트 결과에 따라 렌더링에서 제외할 픽셀을 찾는데 지금 당장은 스텐실 버퍼를 쓸 일이 없다

쓰고 싶어도 DirectX9에서 스텐실 버퍼를 사용하지 않는 게 기본 설정이다. 따로 활성화를 해주어야한다.

스텐실 버퍼는 주로 외곽선이나 그림자를 만들 떄 사용한다고 하는데 방법이 좀 어렵다.

 

위에 있는 이미지를 보면 스텐실 버퍼가 적용되면서 색상 버퍼의 픽셀들이

렌더링에서 제외된 걸 볼 수 있다.

참고도 DirectX는 깊이 버퍼와 스텐실 버퍼를 따로 구분하지 않고 깊이 스텐실 버퍼로 합쳐서 사용한다.

하지만 아까도 말했듯이 깊이 버퍼는 기본 설정이 활성화이고, 스텐실 버퍼는 기본 설정이 비활성화이다.

 

 

 

 

'SR' 카테고리의 다른 글

[SR] 랜더링 기본 단위  (0) 2022.06.07
[SR] #1. Rendering PipeLine  (0) 2021.12.23
[SR] Graphic_Device  (0) 2021.12.23
[SR] Time / GameInstance  (0) 2021.12.22
[SR] 프레임워크2 (DLL 파일 피싱)  (0) 2021.12.10