본문 바로가기
Graphics/GLSL

01. Shader란 무엇인가?

by Lein_ 2021. 12. 29.

Fragment Shader란?

 

컴퓨터로 무언가를 그려본 경험이 있을 것이다. 원하는 이미지를 그리기 위해 원을 그리고, 사각형을 그리고, 선을 긋고 했을 것이다. 이 과정은 손으로 직접 편지나 책을 쓰는 것과 비슷하다. 이건 한 과정이 끝나면 다음 과정으로 넘어가는 일련의 명령들이라고 할 수 있다.

 

쉐이더 또한 명령들의 집합이다. 그러나 하나가 끝나면 다음으로 넘어가는 것이 아닌, 한꺼번에 모든 픽셀에 대해 실행되는 명령이라는 것에 차이가 있다. 우리가 작성한 코드는 픽셀의 위치를 넘겨받고 색깔을 리턴하는 함수로서 동작한다. 이는 컴파일되면 어마어마하게 빨라진다.


쉐이더는 왜 빠른가?

 

이에 답하기 위해 병렬 처리(Parallel Processing)의 위대함을 보여주고자 한다.

 

컴퓨터에 있는 CPU를 거대한 산업용 파이프라고 가정해보자. 각각의 작업(task)은 공장 라인처럼 통과하는 것이라고 생각하자. 어떤 일들은 다른 일들에 비해 처리하는데 더 많은 시간과 에너지를 필요로 할 수 있다.

이 경우 시스템의 아키텍처 때문에 작업은 직렬로 실행되어야 하고, 각 작업은 한 번에 하나씩 완료되어야 한다. 현대의 컴퓨터들은 보통 이러한 파이프와 같이 작동하는 4개의 프로세서 그룹을 가지고 있으며, 매끄럽게 돌아가도록 유지하기 위해 차례대로 작업을 완료한다. 각 파이프는 쓰레드(thread)라고도 한다.

즉 CPU라는 일 잘하는 사람한테 모든 일을 다 떠맡기는 것이다. 일을 하나씩밖에 수행못하는 단점이 있다.

 

800 x 600의 스크린이 있다고 생각해보자. 한 장면을 그리려면 총 480,000개의 픽셀을 업데이트 해야 한다. 만약 60fps라면 1초동안 288,000,000번의 연산을 수행해야 한다. 이 일을 CPU가 해야 한다면 어쨌든 한 번에 한 작업 밖에 수행하지 못하므로 1초에 혼자 약 3억 번의 연산을 수행해야 한다. 이정도의 연산량이면 같은 프로그램 내에서 다른 작업을 할 수 없을 뿐더러 굉장히 비효율적일 것이다. 이런 경우에 GPU가 필요하다.

 

CPU가 큰 대포 하나라면 GPU는 작은 대포가 여러 개로 구성된 것이다.

 

GPU는 수많은 코어들로 구성되어 있으며, 각각의 코어는 CPU만큼의 뛰어난 성능을 갖고 있진 않다. 하지만 픽셀 하나를 그리는데 그리 대단한 연산들이 필요한 것은 아니므로, 오히려 간단한 작업들을 각 코어에 나눠서 작업하면 순식간에 처리할 수 있다. 따라서 800 x 600의 스크린을 60fps로 업데이트해도 퍼포먼스 저하 없이 스무스하게 처리할 수 있다. 이것이 GPU의 힘이다.

 

허나 이렇게 뛰어난 성능을 보이는 만큼 GPU 방식에도 단점이 존재한다. 쉐이더가 어렵다고 악명이 높은 이유와도 직결된다. 이유는 다음과 같다.

 

1. 각 작업을 맡는 코어는 독립적이다. 즉, 한 스레드(A)가 다른 스레드(B)에서 무슨 일을 하고 있는지 알 길이 없다. 따라서 다른 스레드의 결과값을 체크한다든가, 인풋값을 수정한다든가, 다른 스레드의 결과값을 또다른 스레드로 넘기는 것은 불가능하다. 스레드와 스레드 간의 통신을 허용하는 것은 데이터의 무결성 보장을 깨는 것이라 너무나 위험하다.

 

2. GPU는 병렬 마이크로프로세서를 지속적으로 busy 상태로 유지시킨다. free 상태가 되자마자 처리할 새로운 정보를 받는다. 따라서 이전까지 무엇을 하고 있었는지, 값이 어땠는지 아는 것은 불가능하다.

 

3. 각 픽셀에서 하나의 동일한 코드를 실행하지만 색상은 각각 달라야 한다. 이러한 논리를 설계하는 것 자체가 초보자에게는 굉장히 쉽지 않다.

 

하지만 익숙해지면 웬만한 것은 표현할 수 있고 오히려 추상적이고 난해한 이미지들을 단 몇 줄로 쉽게 그릴 수 있다. 기초부터 차근차근 해보면 된다.

 

 

CPU vs GPU 영상 : https://youtu.be/-P28LKWTzrI

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

06. Shapes  (0) 2022.01.02
05. Colors  (0) 2021.12.31
04. Shaping functions  (0) 2021.12.30
03. Uniforms, gl_FragCoord  (0) 2021.12.30
02. Hello world!  (0) 2021.12.29

댓글