프로젝트를 수행하다보면, Chart 를 사용하는 경우가 정말 많은것 같습니다. 수행하는 업무에 따라 사용하는 Chart 의 종류는 달라지겠지만, 대부분 Line 관련 Chart 는 많이 사용하는것 같습니다.
단순히 y = ax + b 와 같은 1차 함수를 사용한 Chart 도 있겠지만, 여러 points 를 line 으로 연결해서 표현하는 Chart 가 오히려 일반적일 것 같습니다. point to point 를 직선으로 연결하는 line chart 도 있지만, 포인트 들을 부드러운 곡선으로 구성되어 있는 Chart도 쉽게 찾아 볼 수 있습니다.
이전 WebGL 의 예시된 Sample 에서도 간단한 움직임을 표시한 적이 있었습니다. 물체 자체를 움직이기 위해서 이동(Translation), 혹은 회전(Rotation) 혹은 이 둘의 결합으로 움직임을 표현하기도 하고, 물체가 아닌 카메라의 위치 이동을 통해 물체의 다른 면을 주시하게 하여 변화된 화면을 구성해 보기도 하였습니다. 어느 대상을 중심으로 움직임을 표현하는가에 따라 구성 방법은 달라지겠지만, 움직임을 표현하기 위한 회전은 공통적으로, X, Y, Z 축을 대상으로 각각 어느 정도의 각도로 움직이는 가를 표현 하였습니다. 이런 방식의 회전을 오일러 각도를 이용한 변환이라고 하며, 직관적이기 때문에 구현이 상대적으로 편리한 측면이 있습니다.
앞선 글에서 구(Sphere) 와 Ray의 충돌까지 정리해 보려고 하다 보니, 공간의 역변환을 정리하는 것도 간단한 일이 아니어서 간략하게 언급만 하였습니다. 개인적으로 수학을 잘하는 것이 아니기 때문에 주어진 공식을 활용하는 정도면 될 것 같긴 하지만, Ray Tracing 은 충돌 같은 것에서만 사용하는 것이 아니라, 굴절, 반사 등에 의해 현실적인 묘사를 위해 사용되고 있는 기법이라, 조금 더 정리할 필요성이 있어 보입니다. 이해를 위한 부분이라 어쩔수 없이 수식을 나열하듯 전개해 보려고 합니다. 검증은 정말 간단한 예제를 만들어 구성해 볼 예정 입니다.
사용자가 선택한 위치의 Pixel 정보를 기반으로 구성하고 있는 물체를 식별하는 방법은 구성의 단순함 측면에서, 구현의 편리성 측면에서 좋은 방법 같습니다. 이런 방법외에 사용할 수 있는 방법이 마우스가 클릭한 위치에서 광선을 만들어 해당 위치에 물체가 있는지, 있다면 어느 물체가 가까운지 찾아서 물체를 선택하는 방법이 있습니다. 다소 복잡한 연산을 통해 물체를 찾는 방법이지만, 광선을 추적하는 기본 알고리즘을 정리할 수 있는 부분이라, 간단히 정리해 보고자 합니다. 실제 WebGL로 구현하는 것 보다는 추적하는 과정을 예제로 구성하여 추적해 보려고 합니다.
Sphere 구성을 위한 확인사항 Canvas 를 활용하여 원을 그리는 방법을 이전 포스트 글에서 구성해 보았습니다. sin, cos 함수를 사용하면, 그리 어렵지 않게 원을 구성할 수 있었습니다. 구는 입체이기 때문에 x,y 좌표외에 z 좌표가 필요합니다. 반지름이 1인 구를 기준으로 생각해 보면 x,y 가 0,0 일때 z 좌표는 1 인 경우 WebGL 에서는 앞으로 튀어나오는 방향이고, -1 인 경우 뒤에 있는 구 지점으로 판단할 수 있습니다. 불 투명일 경우 뒤에 있는 영역은 그려지지 않을 겁니다.
Phong Lighting 3D 관련하여 빛에 대한 자료를 찾아 보면, Phong 모델에 관한 글을 쉽게 접합 수 있습니다. 그만큼 많이 사용되고, 개념을 이해하는데 도움이 되기 때문에 많이 언급되는 것 같습니다. Phong 모델에서 이야기 하는 난반사(Diffuse), 정반사(Specular), 배경광(Ambient), 발산광(Emit) 을 간단하게 정리해 보고 WegGL로 어떻게 구현할 수 있는지 정리해 보고자 합니다.
이곳에서 적용된 예제를 확인할 수 있습니다.
난반사 ( Diffuse ) 빛이 물체에 부딛혀 여기저기로 흩어지는 상황을 모사하는 방법 입니다.
쉽게 생각해서 정오의 태양이 머리에 있을 때(머리와 직각)일 때 빛을 가장 많이 받을 수 있다는 가정에서 출발하고 있습니다.
WebGL 에서 Texture 란 ? WebGL 에서 해주는 것은 어떤 특정 pixel 이 무슨 색을 입혀서 출력해야 하는 가를 판단하고, 표현하는 것이 어쩌면 가장 주요한 일이라고 볼 수 있을 것 같습니다. 그 공간에서 하는 일이 앞에 놓인것은 출력하고, 뒤에 있는 것은 출력하지 않고, 만약 투명하다면 색을 투명도에 따라 혼합하여 보여주는 등 내부적인 일은 복잡합니다. 그래도 주어진 좌표를 기준으로 해당 위치에 어떤 색을 출력해야하는지 결정하는 일은 변하지 않습니다. Texture 는 사용에 따라 여러 가지 일을 할 수도 있지만, 가장 본질적인 것은 특정 좌표의 색을 texture 에 기록된 값으로 보정하여 출력하는데 사용되는 것일 겁니다.
WebGL 에서 Camera 란 ? 우리가 사진기( 아마도 핸드폰이겠지요 ^^ )로 물체를 찍는 다고 가정해 보겠습니다. 핸드폰을 들고, 물체를 보면, 핸드폰 화면에는 찍을 대상이 출력되고 있을 겁니다. 이때 카메라 위치가 눈에 해당하고, 찍을 물체가 대상이되고, 핸드폰을 위로 혹은 약간 기울여서 보게 되는게 사진에 찍힐 모습이 될 것 같습니다. 이를 단순화 하면, eye (사진기위치), at( 사진찍을 물체), up ( 핸드폰을 어떻게 기울였는지 - 대부분 위로 ) 에 따라 사진속의 내용이 어떻게 표현될지가 결정 될 것 같습니다.
삼각함수 응용 앞서 정리한 내용을 바탕으로 물체의 회전에 적용되는 행렬을 정리해 보고자 합니다.
먼저 몇가지 사항을 확인해 보겠습니다.
원점 0,0 에서 반지름 R(구체적으로 1이라 하겠습니다.)로 시작하는 각을(theta) 0 ~ 360 도로 증가하면서 좌표 ( cos(theta), sin(theta) ) 를 연결하면 원을 그릴 수 있습니다. ( 그림 - 소스는 하단에 설명 )
두점 사이의 거리 그림에서 O 와 P 의 거리를 (선분 OP) 는 반지름이 1 이라면, 알파(alpha) 가 45도 라고 가정할 때 1 * Math.
Html5 Canvas Web 에서 일반적인 언어의 Graphics 를 사용하는 것과 유사한 작업을 가능하게 해주는 모듈이 추가된지도 꽤 오랜 시간이 흘렀습니다. 돌이켜 보면 SVG 라는 도형을 그리는 표준이 d3.js 라는 뛰어난 라이브러리로, Chart 등에서 맹위를 떨치던 시간이 그리 오래 전이 아닌데 벌써, 트랜드의 한축이 넘어가는 느낌이 듭니다.
현재 많은 차트 라이브러리에서 SVG 에서 점차 CANVAS 로 옮겨가는 추세 입니다. svg는 web 에서 느린 자원이 아닙니다. 게다가 각 도형별, shape 별 event 처리가 canvas 에 비해 훨씬 수월 합니다.
프로그램 Rendeing 과정 앞서 WebGL 사용 방법에 대해 간단히 정리해 보았습니다. 다시 한번 정리하면
canvas 객체를 구성합니다. GL 객체를 가져옵니다. ( Canvas 를 통해 webgl2 를 가져옵니다. ) GLSL Shader 소스(문자열) 을 Vertex Shader, Fragment Shader 를 구성합니다. Shader Program 을 각각 만들어 두개의 쌍을 사용할 GL Program 을 만들고 Compile 합니다. 일반적으로 프로그램 소스를 구성해서 Compile 하는 것과 유사한 흐름 입니다.
당연히 프로그램을 구성할 때 사용한 소스에서 정의한 input 과 output 규칙은 따라야 합니다.
WebGL 에서 행렬이란 ? $$ \begin{bmatrix}1&2&3\\4&5&6\\7&8&9 \end{bmatrix} \begin{bmatrix}1\\4\\7\\ \end{bmatrix} \begin{bmatrix}1&2&3 \end{bmatrix} $$
위 표에서 전체 행렬이 1 ~ 9 까지의 내용을 담은 3 x 3 행렬 이라면, 1,4,7 은 열( Column ) 이고 1,2,3 은 행(Row) 라고 불립니다. 위 표의 행렬은 행 3개와 열 3개로 이뤄진 3 x 3 행렬인 셈입니다.
WebGL(3D 프로그램) 에서 행렬이 왜 사용되는 걸까요? 어떤 물체가 100개의 꼭지점을 갇고, 그 꼭지점을 연결한 위치 정보를 지니고 있다고 가정하겠습니다.
백터의 사칙 연산 벡터의 사칙연산(더하기, 빼기, 곱하기, 나누기) 은 일반 수의 연산과 거의 동알하다고 생각하면 될 것 같습니다. 약간의 차이란, Vector 안에 있는 순서에 맞게 계산해 주는 부분만 조금 다를 뿐입니다.
가령 [1,2,3] 의 a vector 가 있고, [4,5,6] 의 b vector 가 있을 때 a + b = [1+4, 2+5, 3+6 ] 으로 표현할 수 있습니다. a-b = [1-4, 2-5, 3-6] 이고, a*b, a/b 도 동일한 연산을 사용한다고 보면 될 것 같습니다.
WebGL 벡터란 ? 프로그래밍 관점에서 보면, WebGL 에서 사용하는 벡터란 , 대부분 x,y 로 표기되는 원소가 두개인 배열 혹은 x,y,z 으로 표기 되는 원소가 3개인 배열 정도로 이해 할 수 있을 것 같습니다. 배열을 기준으로 보면 1차원 배열의 원소의 갯수만 차이가 있는 것이고, 데이터가 [1,2,3] 이 있을 때 행(Row) 을 기준으로 보면 행백터 이고, 열(Column) 을 기준 으로 보면 열백터로 지칭하고 있습니다. 아래의 예에서와 같이 세로, 가로로 이해하면 편할것 같습니다.