Programming/Shader

[Shader] Game Graphic Theory & OpenGL Installation

와들S 2023. 7. 16. 10:46

※ 해당 내용은 '카일 할러데이'의 "셰이더 코딩 입문" (에이콘) 을 읽고 작성하였습니다. 진짜 좋은 책이니 꼭 사세요

 

1) Rendering

- 컴퓨터 그래픽에서 렌더링이란 2D 또는 3D Mesh, 광원의 위치, 게임 카메라의 앵글 같은 Scene 정보로부터 이미지를 만드는 과정을 가리킨다. 렌더링에서 만든 이미지는 Render 또는 Frame이라 한다. 

- 게임을 구성하는 코드 중에서 렌더링을 담당하는 부분을 렌더링 엔진이라고 한다. 렌더링 엔진이 메쉬를 새로운 프레임으로 만드는 일련의 과정을 Rendering Pipeline (또는 Graphic pipeline)이라 한다.

 

2) Mesh

- 메쉬는 컴퓨터가 이해할 수 있는 형식으로 대상의 형태를 정의하는 방법 중 하나다. 메쉬는 형태를 정의하기 위해 Vertices와 Edges, Faces라는 세 가지 정보를 저장한다. 

- Vertices는 3D 공간에 있는 점을 가리킨다. Edges는 Vertices를 연결한 선을 가리키며 형태를 만들기 위해 Vertices가 어떻게 연결되는지 정의한다. Faces는 세 개 이상의 Edges로 구성된 2D 형태를 말한다. 어떠한 2D형태도 Face가 될 수 있으나 게임 엔진은 삼각형 형태의 페이스로 구성된 메쉬를 요구한다.

- 메쉬는 오직 Vertices만을 메모리에 저장하고, Edges와 Faces는 Vertices 순서를 간접적으로 저장한다. 이때 이 순서는 해당 Faces가 앞면인지 뒷면인지 구별하는데 무척이나 중요하다. 대부분의 게임엔진에서 앞면은 Face를 중심으로 반시계방향으로 정해진다. 많은 게임은 뒷면을 렌더링하지 않는 Backface Culling이라는 최적화 기술을 사용한다.

- 메쉬의 Vertices는 Vector를 사용해서 정의한다. 

 

3) Color

- 컴퓨터 그래픽에선 보통 4-컴포넌트 벡터 (vec4)를 이용해서 색상 데이터를 저장한다. X, Y, Z는 각각 R, G, B를 담당하며 W 컴포넌트는 알파(A)를 가리킨다. 

 

4) Rendering Pipeline

- Rendering Pipeline: 메쉬를 화면의 이미지로 만들기 위해 GPU(그래픽 카드)가 처리하는 일련의 과정
파이프라인은 전적으로 GPU에서 처리된다. 

- 순서: 메쉬 버텍스 데이터 ➡ 버텍스 셰이더 ➡ 형태 조립 ➡ 래스터화 ➡ 프래그먼트 셰이더 ➡ 프래그먼트 처리

- 버텍스 셰이더는 현재 처리하는 메쉬의 버텍스를 화면 어디에 그려야하는지를 계산한다. 물체의 위치 정보는 버텍스 셰이더로 전달되고, 그 정보는 카메라 위치나 방향같은 다른 정보와 같이 합쳐져서 물체의 메쉬를 구성하는 모든 버텍스의 화면 상의 위치를 결정한다. 

- 버텍스 셰이더에서 메쉬의 모든 버텍스를 처리하면 여기서 나온 데이터는 형태 조립 단계로 넘어가고, 이를 선으로 연결하는 역할을 담당한다. 화면에 메쉬의 Edges를 배치하는 단계다.

- 래스터화 단계에선 GPU가 앞서 처리한 메쉬가 화면에서 차지할 가능성이 있는 픽셀을 계산한다. 그리고 픽셀 후보 하나하나에 대해 프래그먼트를 만든다. 프래그먼트는 화면에 픽셀을 그리기 위해 필요한 모든 정보를 담은 데이터 구조를 가리킨다. 모든 프래그먼트가 화면 위의 픽셀이 되는 것은 아니기  때문에 프래그먼트를 '잠재적인' 픽셀이라 생각해도 좋다.

- 각 프래그먼트의 색상 정보는 프래그먼트 셰이더가 채워준다. 그 정보를 구하기 위해 모든 프래그먼트는 프래그먼트 셰이더로 보내진다. 

- 프래그먼트 처리 단계는 크게 프래그먼트 테스팅과 브랜딩 연산이라는 두 역할을 담당한다. 프래그먼트 테스팅은 프래그먼트를 화면에 그리고, 어떤 프래그먼트를 버릴 것인지 판단하는 과정이다. 메쉬의 프래그먼트를 생성 시 전체 씬에 대한 정보는 고려하지 않는다. 따라서 GPU는 실제로 그릴 픽셀보다 훨씬 많은 프래그먼트를 생성하고, 프래그먼트 처리 단계에 이르러서야 화면에 그릴 것과 버릴 것을 구별한다. 한편 프래그먼트 블렌딩은 반투명한 상자가 자신의 색상과 뒤에 비치는 바닥의 프래그먼트를 섞을 수 있게 해준다. 

- 프래그먼트 처리 단계까지 끝나면 화면에 프레임을 그릴 준비를 마치게 된다. 실제 렌더링 파이프라인에는 훨씬 복잡한 과정이 들어있다. 

 

5) Shader

- 셰이더는 그래픽 카드에서 실행되는 프로그램이며, 제일 중요한 일은 렌더링 파이프라인을 제어하는 일이다. 

- 여기서 집중할 대상은 버텍스 셰이더와 프래그먼트 셰이더이다. 이 두 셰이더는 렌더링 파이프라인을 통해 무언가를 화면에 그리기 위한 최소 요건이고, 가장 널리 사용되는 셰이더이다. 

- 셰이더는 Shading Language라는 특별한 프로그래밍 언어로 작성한다. 

- 앞으로 공부할 이 책에선 OopenGL을 사용하기 때문에 OpenGL Shading Language인 GLSL을 사용한다. 

 

6) OpenGL 설치

- 책에 있는 방법은 비주얼 스튜디오 2017 버전만 되는 거 같았다. 난 2022 버전을 쓰고 있어서 해당 설치 방법이 2017 버전만 호환이 되는 것 같다. 그래서 다른 방법을 찾아보았다. 이전에 SDL을 할 때 ㅈ같은 SDL을 설치해본 적이 있어서 쉬웠다. 아래 방법은 https://www.youtube.com/watch?v=HzFatL3WT6g 유튜브를 참고했다. 

- https://www.glfw.org/download.html 이 페이지에 들어가 Windows pre-compiled binaries - 64-bit Windows binaries를 다운받는다. 그리고 압축을 푼다.

- 이후 Visual Studio를 열어 새 C++ 파일을 만들어 생성한다. 이름이 main.cpp인 cpp 파일을 만들고 위 홈페이지 - Documentation에서 소스코드를 복사한다.

- 위 코드를 복사해 그 main.cpp에 넣는다. 그럼 빨간 줄이 뜰 것이다.

- 이를 해결하기 위해서는 먼저 프로젝트 - OpenGL 속성에 들어간다.

 - 먼저 맨 위에서 구성: 모든 구성, 플랫폼: x64로 맞춘다. 활성 x64가 아닌 x64로 한다. 

- 이후 C/C++ 를 눌러 추가 포함 디렉터리에 새걸 추가한다. 위에서 다운로드한 폴더 속 include 폴더를 넣으면 된다. 

- 다음으론 링커 -일반 - 추가 라이브러리 디렉터리에 들어가 VS 버전에 맞춘 2022 버전을 골라 넣으면 된다. 

- 마지막으로 링커 - 입력 - 추가 종속성에 다음을 적어야 한다.

glfw3.lib
opengl32.lib
user32.lib
gdi32.lib
shell32.lib

- 그리고 다 확인을 눌렀을 때 완전히 빨간 줄이 없어지면 된다.

이렇게 뜬다. 

- 실행해보면 이름이 Hello World 인 빈 창이 뜬다. 그럼 성공이다.

 

+) 실행해서 책의 코드를 해보려 하니 OpenGL 이랑 조금 다른 거 같다. 따라서 책의 방법을 다시 실행해보았다.

- 이 페이지 https://openframeworks.cc/download/ 에 들어가,

- windows - visual studio (2017-2022) 다운받는다. 책에서 0.10.0을 다운받으라 했지만 일단 가장 최신 버전으로 하기로 했다. 문제 생기면 다시 하지뭐 ㅋㅋ...

- 다운로드 후 압축을 풀고 그 폴더 속 projectGenerator 폴더 - projectGenerator.exe 파일을 실행한다. 

- 난 이미 새 파일을 만들어서 update란 버튼이 뜨지만 원래라면 Generate라는 버튼이 보인다. 이름과 경로를 설정하고 Generate를 누르면 새 파일이 만들어진다. 이후 Open in IDE 버튼이 있는 새 창이 뜨고, 그걸 누르면 두 개의 프로젝트가 들어있는 비주얼 스튜디오 솔루션이 열린다. 

- 이후 아래에서 프로젝트 세팅을 한다. 책에 있는 대로 코드를 넣고 바꿔줬다.

main.cpp
ofApp.cpp
ofApp.h

- 코드를 설명하겠다.

- OpenFrameworks에서 메쉬 클래스는 ofMesh라고 한다. 기본 생성자를 이용해서 ofMesh 객체를 생성하고 그 객체의 addVertex() 함수에 3-컴포넌트 벡터로 된 버텍스 위치 정보를 전달하면 된다. OpenFrameworks는 GLM라는 수학 라이브러리를 통해서 벡터 연산을 처리한다. 따라서 vec3 데이터 타입은 glm 네임스페이스를 사용한다. 

- 만든 메쉬를 화면에 띄우려면 draw()함수를 이용한다. 

- 별도로 셰이더를 지정하지 않을 경우, OpenFrameworks는 기본 버텍스 셰이더와 프래그먼트 셰이더를 메쉬에 적용한다. 이 기본 셰이더는 버텍스 좌표를 스크린 픽셀 좌표(Screen pixel coordinates)로 읽어 들이고 메쉬를 하얀색으로 렌더링한다. 

- 따라서 실행하면 위처럼 삼각형이 렌더링 된다. 맨 왼쪽상단이 좌표 (0, 0)이고 오른쪽, 아래로 갈수록 큰 숫자, 좌표로 이어진다. 

'Programming > Shader' 카테고리의 다른 글

[Shader] 4) Transparency and Depth  (0) 2023.08.12
[Shader] 3) Texture -2  (0) 2023.08.11
[Shader] Open Framework 사용법  (0) 2023.08.11
[Shader] 3) Texture -1  (0) 2023.08.10
[Shader] First Step of OpenGL Shader Scripting  (0) 2023.07.16