프로젝트를 수행하다보면, 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로 구현하는 것 보다는 추적하는 과정을 예제로 구성하여 추적해 보려고 합니다.
프로그램이 사용자와 상호 작용을 하기 위해서는, 해당 프로그램을 이용하는 사람이 물체 혹은 대상을 선택할 수 있어야 하고, 그 선택한 항목을 기준으로 특정한 일을 수행하도록 하는 것이 필요할 것 같습니다. 일반적인 Application 이나 Web 프로그램 등에서는 Button Click, 글 Click 같은 행위를 기반으로 사용자 Action 을 구성하게 됩니다. WebGL 프로그램에서도 사용자가 무엇인가를 선택한다면, 선택한 항목이 무엇인지 알 수 있어야 하고, 이를 통한 상호작용이 필요합니다. 물체를 선택하는 행위를 Picking 이라고 합니다. 문제는 우리가 화면에서 어떤 물체를 선택하기 위해 클릭하였을 때 확인할 수 있는 것은 Fragment 보간에 의해 구성된 특정 위치의 색상 이외는 알 수 있는 것이 없다는 점입니다.
Shadow Mapping 앞에서 Phong 모델에서 제시하는 빛에 대해 간단히 정리해 보았습니다. 빛이 비추는 방향이 물체에 어떻게 영향을 미치는가 하는 부분에서는 그럴듯하게 보이지만, 해당 모델에서는 처리하기 어려운 부분이 빛이 비추는 반대편의 그림자 들입니다. 우리는 빛이 비추면 반대편에 그림자가 지는 당연한 세상에 살고 있지만, 컴퓨터에서는 어떻게 빛과 그림자를 표현할 수 있을까요 ? 원리는 이해하기 그리 어렵지 않습니다. 다만, 프로그램에서 구현하는 부분은 조금 신경써야 할 부분이 있습니다. 그 내용을 정리해 보고자 합니다.
Texture 미포함 - 예제 사이트는 이곳을 클릭하여 확인해 보실 수 있습니다.
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 에 기록된 값으로 보정하여 출력하는데 사용되는 것일 겁니다.
Canvas Image Pixel 은 ? 앞서 간단히 정리한 Web 에서 이미지를 다루는 방법은 Image Pixel을 직접 다룰 수 있는 Typed Array 를 Canvas 가 제공해 준다는 것입니다. 이미지가 100 x 100 정도의 size 라면 10000 개의 pixel 정보가 있고, 10000 개의 pixel 에는 각각 r, g, b, a 의 값이 각 1byte 씩 저장되어 (각 pixel당 4byte) 개발자가 접근할 수 있도록 데이터를 제공합니다. 어쩌면 이것이 Canvas 가 지닌 가장 강력한 도구가 아닌가 합니다.
Image Kernel Image Processing 관련한 문서를 검색하면 일단 용어 자체가 그리 익숙하지 않은 상황에서 kernel, convolution matrix, mask 등의 용어를 접하기도 합니다. 사실 아주 오래전 Windows Application 을 구성하면서 데이터에 필터 ( 행렬 값 - kernel )를 적용하며, 시각화 하여 보여주는 프로그램을 개발한 적이 있었습니다. Application 에서만, 그것도 범용적이지 않은 프로그램에서 사용하던 기능들이었는데, 이제는 Web 에서 이런 기능이 가능한 것을 보면서, 개발환경의 변화를 새삼스레 느끼게 됩니다. Copy & Paste 의 대명사 였던 javascript 가 이제는 어떤면에서는 가장 첨단을 달리는 언어로 탈바꿈한것을 보면, 어쩌면 당연한 일인지도 모르겠습니다.
Canvas 에서 Image ? WebGL에서 Texture 부분을 정리하다 보면, Nearest, Bilinear 등의 용어를 접하게 됩니다. 프로그램을 개발하는 관점에서는 추출하는 방식을 지정한 후, GPU 에서 수행한 결과를 확인하면 되는 것이니, 구체적인 알고리즘을 굳이 확인하지 않아도 문제가 되지는 않습니다. 하지만, Web 특히 Canvas 에서 제공하는 강력한 기능중 하나가, Image 를 Uint8Array 의 8bit 이미지 배열로 다룰 수 있도록 데이터를 제공하고 있는 것입니다. 이런 데이터를 기반으로 간단한 Image Processing 작업, 더 나아가 OpenCV 에서 제공하는 기능도 일부 활용할 수 있는 수준에 있습니다.
WebGL 에서 Camera 란 ? 우리가 사진기( 아마도 핸드폰이겠지요 ^^ )로 물체를 찍는 다고 가정해 보겠습니다. 핸드폰을 들고, 물체를 보면, 핸드폰 화면에는 찍을 대상이 출력되고 있을 겁니다. 이때 카메라 위치가 눈에 해당하고, 찍을 물체가 대상이되고, 핸드폰을 위로 혹은 약간 기울여서 보게 되는게 사진에 찍힐 모습이 될 것 같습니다. 이를 단순화 하면, eye (사진기위치), at( 사진찍을 물체), up ( 핸드폰을 어떻게 기울였는지 - 대부분 위로 ) 에 따라 사진속의 내용이 어떻게 표현될지가 결정 될 것 같습니다.
Canvas Game Event 구성 도형 구성과 배치를 위한 UI 가 구성되었으면, 이제 사용자가 선택후 Drag & Drop 으로 위치를 맞추고, 그 결과를 담아 내기 위한 Event 처리가 필요합니다. 요즘은 PC 가 아닌, 핸드폰에서도 Web 접근이 가능하기 때문에 Phone Device 를 위한 Event 처리를 위해서는 touchstart 등의 이벤트도 정리하여야 하지만, 이 글에서는 다루지 않겠습니다.
다음주소 에서 확인해 보실 수 있습니다.
Initialize 시점에 Event 구성 초기화 과정에 Canvas 에 Mouse Event 를 할당 하는 과정 입니다.
Canvas 만들고자 하는 Game 은? HTML5 가 도입되면서, 정확히는 canvas 가 기술 표준으로 정해지면서, Web 에서 구성할 수 있는 Application 같은 프로그램을 만들 가능성이 많이 높아진것 같습니다. 하지만, 표(Table 같은 Grid) 와 이미지 정렬, Text 정보 등을 기반으로 하는 업무 시스템에서는 Canvas 와 같은 기술은 그렇게 많이 활용되지는 못하고 있는것 같습니다. 그나마, Chart 등에서 SVG 에서 Canvas 로 점차 기술적인 전환이 이뤄지고 있지만, 아직도 많은 시스템에서는 활용하고 있지 않은것도 사실입니다.
Canvas 아날로그 시계 Canvas 를 활용하여 구성할 수 있는 다양한 모듈이 있습니다. Canvas 는 Web 에서 Graphics 자원을 어느정도 사용할 수 있다는 장점이 있습니다. 일반적이진 않지만, Web 화면을 Application 처럼 구성할 수 있다는 장점 때문에 개인적으로 선호하는 Web 모듈 이기도 합니다.
시계는 Canvas 를 어떻게 활용할 수 있는지 확인해 볼 수 있는 좋은 소품이란 생각이 들어 간단히 구성해 보았습니다.
초침의 삼각형, 원에서 표현할 위치 등을 위해서는, 간단한 삼각함수를 활용하여야 하기 때문에 정리하기도 좋을것 같아서 선택해 보았습니다.
삼각함수 응용 앞서 정리한 내용을 바탕으로 물체의 회전에 적용되는 행렬을 정리해 보고자 합니다.
먼저 몇가지 사항을 확인해 보겠습니다.
원점 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을 처음 구성하려 할 때 가장 먼저 부딛히는 부분이 저 같은 경우, 익숙하지 않은 용어와 수식이 난무 하는 설명 이었습니다.
이미 수학적인 기초가 튼튼하게 다져진 분들은 상관이 없겠지만, 저처럼 익숙하지 않은 용어에, 덧붙인 수식 기호 등은 프로그램밍에 대한 접근을 막는 부분 이었습니다.
프로그램을 구현할 때 필요한 부분은 해당 수식에 대한 증명이 아니라, 원리에 대한 기본적인 이해와,
그 이해를 바탕으로 공식화된 수식을 활용할 수 있다면, 프로그램을 구성하는데 문제는 없어 보입니다.
프로그램을 위한 준비 제한사항 현재 WebGL2 는 IE를 제외한 대부분의 Browser 에서 사용가능합니다.
Web 에서 3D를 구현하는 방법도 OpenGL 기반의 WebGL 에서, 더 다양한 지원이 가능한
WebGPU 등의 표준화가 진행중입니다. 현재 사용중인 Web 에서 3D를 구성하는 방법에도 변화가 있을 수 있는 상황입니다.
언제나 그렇듯 변화가 많을 경우, API 하나 하나 공부하는 것은 그리 효율적인지 않은 방법 같습니다. 동작의 기본 원리를 이해해 두면, 향후 어떤 변화가 나타나도 적응하는데 유리할 것 같습니다. WebGL 관련 코드는 WebGL 2.
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) 을 기준 으로 보면 열백터로 지칭하고 있습니다. 아래의 예에서와 같이 세로, 가로로 이해하면 편할것 같습니다.
WebGL2 에 대한 간단한 소개 현재 Web에서 3D를 사용할 수 있는 방법은 WebGL2가 가장 최근에 확정된 규약이고, 해당 기술은 OpenGL ES 300 을 기준으로 구성되어 있습니다.
WEBGPU 라는 Spec 이 공표되고 테스트가 진행 중이지만, 현재까지 Chrome 등의 Browser 에서 Default 로 지원되지는 않습니다.
WebGL2 는 IE를 제외한 대부분의 Browser 에서 지원하고 있기 때문에, Web에서 3D를 구현하려면, WebGL2를 활용하는게 좋을 것 같습니다.
WebGL2 Library WebGL 을 사용하는 가장 간단한 방법은 잘 구성된, 모듈을 사용하는 것이 가장 빠르고 편한 방법입니다.