본문 바로가기
Web/Graphics

[1] WebGL Fundamental

by Riverandeye 2020. 9. 10.

해당 내용은 이 동영상을 들으면서 기록한 것입니다. 

가벼운 마음으로 심심할때마다 공부해서 끝내는 것이 목표입니다. 

 

1. Basic Mathematics, Translation Rotation Scaling Projection

OpenGL은 2차원 및 3차원 그래픽스의 표준 API 규격이다. 실제 구현체는 manufacturer (NVIDIA ..) 들의 GPU Driver에 존재하기 떄문에, 구현 방식은 개별 드라이버에 따라 다르다. WebGL은 OpenGL-ES 스펙을 구현한 구현체로, 해당 구현체를 이용하여 개발을 하게 되면 GPU Vendor 에 구애받지 않고 기능을 구현할 수 있다. 

 

CPU가 아닌 GPU를 사용하는 이유는 GPU는 병렬처리가 가능하기 때문이다. 

Computer Graphics에서 모든 요소들은 작은 삼각형들로 이루어져 있고, 각 Object는 mesh 라고 불린다. 

물체를 움직이는 것은 물체를 구성하는 모든 삼각형을 이동시키는 것과 같다. 

삼각형의 Vertex를 이동시키는 것은 Matrix 의 모든 점을 선형변환 하는 행위이기 때문에, 개별 점들에 대한 계산을 병렬적으로 구성하게 되면 더욱 빠른 성능을 얻을 수 있다. 

 

매 프레임의 변화 사이에 어떤 작업이 이루어질까?

우선 그래픽스는 기본적으로 어떤 Object를 디자인하고 생성하는 것으로부터 시작된다. 3차원의 Object Space에서 Object를 구성하면, 이를 2차원으로 변환하는 작업을 거치게 된다. 이 과정에서 Matrix 연산이 일반 for loop 보다 최적화가 되어있기 때문에 Matrix 연산을 사용한다. Matrix 연산을 통해 Point를 원점으로부터 회전하고, Scaling, Translating을 수행할 수 있다. 

Rotation과 Scaling은 고등학교때도 배우는거지만, Translation은 좀 참신하다. 왜 이렇게 하는걸까? 

 

그냥 더하면 되는걸 행렬연산을 한다고? 이유가뭘까..

아무래도 Scaling과 Rotation이 행렬로 독립적으로 구성되어 있어서, Translation 도 행렬로 구성하는 것이 더욱 효율적이여서 그런 것으로 보인다. 

어떤 Action을 취하고 싶으면, 해당 Action에 맞는 Translation, Scaling, Rotation Matrix가 조합되어 구성된다. 

Rotate, Scaling, Translation 순으로 연산된다

 

World Space (3d 공간)에 어떤 Object가 고정되어 있고 내 캐릭터를 움직이는 상황을 생각해보자. 

사용자는 카메라를 통해 세상을 보게 된다. 보고있는 세상의 영역을 View, 시야라고 한다. 근데 실제로 카메라는 존재하지 않는다.  

실제로는 Matrix만 있고, 연산만 할 뿐이다. 오른쪽으로 움직이고 왼쪽으로 움직이는 것은 실제로 공간상의 Matrix가 선형변환을 하는 것이다. 

 

그래서 위에서 설명한 TSRX를 MX (M = TSR : Model Matrix) 로 치고, 구성된 Matrix에 View Matrix를 곱한다. 

View Matrix는 Camera를 시뮬레이션한다. View Matrix엔 카메라의 Translation Rotation 이 있다. 

View Matrix와 Model Matrix를 합쳐서 함께 계산한 결과를 반환한다. 

 

Model Matrix는 Object에 따라 다르지만, View Model은 모든 Object에 대해 동일하게 동작한다. 사용자에 대해서는 다르겠지만..

이렇게 구성한 3d Object를 2d 화면으로 Projection을 해야한다. 이 또한 행렬 연산으로 수행된다. (Projection Matrix)

 

Perspective Projection : 실제로 사람이 보는 것을 시뮬레이션 함. 거리가 멀어지면 작게 보이고.. (일반적인 그래픽스)

Orthogonal Projection : 사람이 보는 것 과 관계없이 모든 선이 평행하고 축에 대해 수직함. (애는 CAD와 같은 정교한 그래픽 작업에 사용)

 

두 Projection 간의 차이는 (이 글을 참고함)

 

Perspective Projection Matrix를 생성할 때 Camera의 특성을 Parameter화 한다. 

예를 들어 배율이라던지, 시야각이라던지. 밑의 사진을 보면 알 수 있다. 

 

카메라의 시작점으로부터 거리가 10이고, 전체 커버하는 반경이 10000이면

10000까지 보이는 영역이 10으로 축소되어 나타나는 것이다. 

10 보다 가까운 거리에 위치하는 object는 보이지 않는다.

 

카메라의 시작점에서 양쪽 시야의 각도 또한 반영될 수 있는 중요한 요소이다. 

그래서 이런 속성을 지정해주는 Projection Matrix까지 곱해서 최종 결과가 나오는 것이다. 

 

그 결과는 각 축의 -1~1 사이의 값으로 나타나고, 그 외의 영역은 모두 제거한다. (OpenGL ES 스펙)

 

2. Shader 

Shader는 GPU를 대상으로 한 프로그램 명령으로, Screen의 모든 픽셀에 대해 적용된다. 

병렬적으로 수행될 수 있는 Dependency가 없는 함수라고 생각하면 된다. 

Shader를 이용해서, 구성되어있는 3d object에 Color 와 Light를 부여한다. 

 

동영상을 보면 조금 더 빠르게 이해가 될 것이다. 

서로 다른 Shader를 사용하여 화면의 질감을 달리 할 수 있다. 

 

Shader엔 2가지 종류가 있는데 하나는 Vertex Shader이고 다른 하나는 Fragment Shader이다. 

Vertex Shader는 모든 각각의 Vertex에 대해 이전에 이야기한 모든 Transformation이 동작한다. 이는 곧 Vertex Shader의 역할이 3d space의 좌표를 옮기는 것이라고 생각하면 된다. 

Fragment Shader는 Screen에 나타나야 하는 픽셀값을 지정할 때 사용되며, 실제로 화면(Viewport)에 어떤 Color가 렌더되야하는 지에 대해 연산할 때 사용된다. 

 

이러한 연산이 다른 픽셀과 독립적으로 계산되어 렌더링되기 때문에, 병렬적으로 연산이 가능한 것이다. 

 

데이터는 다음과 같이 전송된다. 

CPU에 개별 vertices와 해당 vertice의 color, matrix 정보들이 담겨있고, 이를 GPU로 보낸다.

vertex shader는 CPU가 전송한 정보 중 vertice 정보와 matrice 정보를 이용해 새로운 위치를 렌더링한다. 

fragment shader는 생성된 새로운 정보를 이용하여 현재 viewport에 렌더링 될 색상을 결정한다. 

 

색상을 렌더링할 때, Viewport의 픽셀 정보에 모든 vertice가 다 명시되어 있지는 않다. 

비어있는 영역을 렌더링할 때는 Interpolation을 이용해서 색상을 지정해준다. 

 

3. After the Projection

Shader 연산이 완료된 후에는 어떤 작업이 수행될까? 

 

셰이더 연산 후 결과물

셰이더 후 결과물은 dimension -1 ~ 1의 3차원 큐브가 형성된다. 

음.. 왜 3차원이지? 우리가 보이는 화면은 2d인데? 그 이유는 z축의 보는 방향의 Depth도 필요하기 때문이다. 

실제 화면에 나타나야하는 이미지를 구성하기 위해, z축으로 나열된 모든 object를 xy축으로 정사영시키고

depth와 transparency를 체크하여 실제 화면에 표현되어야 할 픽셀이 결정된다. 

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

[4] Three.js - Material  (0) 2020.09.28
[3] Three.js - Scene, Light Sources  (0) 2020.09.23
[2] Three.js - 시작하기  (0) 2020.09.22

댓글