본문 바로가기
3D웹 프로그래밍/WebGl

웹지엘 ? WebGL ?? 기본원리-2

by 디찌s 2020. 11. 6.
728x90
반응형

웹지엘 그래픽 파이프라인


웹지엘 그래픽 파이프라인은 아래 순서와 같다.

 

(웹 애플리케이션 HTML + CSS + 자바스크립트 + 셰이더 소스코드 + 3차원 모델링 데이터) ->웹지엘(자바스크립트 API) -> 버텍스 셰이더 -> 프리미티브 어셈블리 -> 레스터화 -> 프래그먼트 셰이더 -> 가위테스트 ->멀티샘플 프래그먼트 연산 ->스텐실 테스트 -> 깊이 버퍼 테스트 -> 블렌딩 -> 디더링 ->그리기 버퍼

 

 

이중 사실 웹지엘 프로그래머에게 가장 중요한 단게는 버텍스 셰이더와 프래그먼트 셰이더이다.

 

 

 

버텍스 셰이더

(웹 애플리케이션 HTML + CSS + 자바스크립트 + 셰이더 소스코드 + 3차원 모델링 데이터) ->웹지엘(자바스크립트 API) -> 버텍스 셰이더 -> 프리미티브 어셈블리 -> 레스터화 -> 프래그먼트 셰이더 -> 가위테스트 ->멀티샘플 프래그먼트 연산 ->스텐실 테스트 -> 깊이 버퍼 테스트 -> 블렌딩 -> 디더링 ->그리기 버퍼

 

 

실감나는 3D 장면을 그리기 위해선 특정한 위치에 오브젝트를 그리는 것만으로 충분하지 않고, 빛이 오브젝트를 비출떄 오브젝트의 노출 방법도 고려해야한다.

다양한 재질에 빛이 반사 될떄 나타나는 광원 효과를 결정 짓도록 처리하는 것을 셰이딩 이라 부른다.

 

 

웹지엘의 셰이딩은 두 단계로 진행된다.

 

하나는 버텍스 셰이더고 두번째는 프래그먼트 셰이더다

 

 

첫번째 단계는 버텍스 셰이더다. 버텍스 셰이더란 이름은 기하학적인 오브젝트의 모서리나 교차점의 3D 점을 버텍스라 

 

부르는 데서 유래한다. 버텍스 셰이더는 파이프라인에서 버텍스에 셰이딩 효과를 입히는 단계이다.

 

 

 

 

 

버텍스 셰이더는 다음과 같은 입력값을 사용함.

  - ES 셰이딩 언어(GLSL ES)에 기반하여 작성

  - 각 버텍스에 적용되는 유저가 정의한 Attribute는 버텍스의 위치와 색상값 등이있다.

  - 모든 버텍스에 적용되는 유니폼 상수이며, 변환행렬,광원의 위치등이 해당한다.

  - 유저가 정의한 varying 변수를 포함한다.

 

varying 변수는 버텍스 셰이더가 프래그먼트 셰이더로 정보를 전송할떄 사용한다.

 

 

 

(웹 애플리케이션 HTML + CSS + 자바스크립트 + 셰이더 소스코드 + 3차원 모델링 데이터) ->웹지엘(자바스크립트 API) -> 버텍스 셰이더 -> 프리미티브 어셈블리 -> 레스터화 -> 프래그먼트 셰이더 -> 가위테스트 ->멀티샘플 프래그먼트 연산 ->스텐실 테스트 -> 깊이 버퍼 테스트 -> 블렌딩 -> 디더링 ->그리기 버퍼

 

프리미티브 어셈블리

버텍스 셰이더에 넘어온 버텍스를 조립해 삼각형이나,선 ,포인트 스프라이트 등의 가하 프리미티브를 생성하는 단계이다. 또한, 해당 프리미티브가 모니터상에 표시될 3D 공간안에 위치하는 결정을 해야하며, 이러한 가시적인 3D 공간을 뷰 절두체(view frusturm)이라 한다. 

 

https://m.blog.naver.com/PostView.nhn?blogId=hermet&logNo=52167752&proxyReferer=https:%2F%2Fwww.google.com%2F 참조

뷰절두체는 위 그림과 같이 직사각형을 밑면으로하는 피라미드 모양을 가지며, 뷰절두체 안에있는 프리미티브는 다음 단계 파이프라인으로 보내진다. 반대로 절두체 밖에 있는 프리미티브는 완전히 제거되고 경계에 있는 프리미티브는 절두체안쪽 부분만 형태가 남아있는다.

 

래스터화(단편화)

 

(웹 애플리케이션 HTML + CSS + 자바스크립트 + 셰이더 소스코드 + 3차원 모델링 데이터) ->웹지엘(자바스크립트 API) -> 버텍스 셰이더 -> 프리미티브 어셈블리 -> 레스터화 -> 프래그먼트 셰이더 -> 가위테스트 ->멀티샘플 프래그먼트 연산 ->스텐실 테스트 -> 깊이 버퍼 테스트 -> 블렌딩 -> 디더링 ->그리기 버퍼

 

 

전송 온 프리미티브를 선,삼각형,포인트 스프라이트등으로 조깬뒤 프래그먼트 셰이더에 전송하는 단계이다. 프래그먼트를 화면상에 그려지는 픽셀이라고 생각할수도있다.

 

프래그먼트 셰이더

(웹 애플리케이션 HTML + CSS + 자바스크립트 + 셰이더 소스코드 + 3차원 모델링 데이터) ->웹지엘(자바스크립트 API) -> 버텍스 셰이더 -> 프리미티브 어셈블리 ->레스터화-> 프래그먼트 셰이더 -> 가위테스트 ->멀티샘플 프래그먼트 연산 ->스텐실 테스트 -> 깊이 버퍼 테스트 -> 블렌딩 -> 디더링 ->그리기 버퍼

 

 

기본적으로 하나의 프래그먼트는 화면의 하나의 픽셀에 대응한다. 그러나 모든 프래그먼트가 그리기 버퍼의 픽셀이 되는것은 아니며, 일부 프래그먼트는 파이프라인 마지막단계에서 프래그먼트 연산에서 제외될수있다. 프래그먼트는 최종적으로 그리기 버퍼에 저장되어야만 픽셀이라고 부른다.

 

프래그먼트 셰이더의 입력값은 다음과 같다.

 

 - opengl es 셰이딩 언어로 작성된 코드

 - 내장된 특별 변수 (gl_pointCoord,gl_fragcoord)

 - vertex shader 에서 넘어온 유저가 정의한 varying 변수

 - uniform 상수 변수

 - 텍스처링에 사용하는 특별 타입인 샘플러 

 

 

--그림 --

 

 

버텍스 셰이더에서도 봤지만 varying 변수는 버텍스 셰이더의 결과를 프레그먼트 셰이더로 보낼때 사용한다.

 

 

프래그먼트들은 위 그림처럼 어느 도형(현재는 삼각형으로 보이는) 안에 들어있는 픽셀이라고 생각해도된다. 위 그림을 보듯이 일반적으로 프래그먼트가 버텍스보다 훨씬 많은 숫자들로 구성되어있다는것을 볼수 있으며, 버텍스 셰이더에서 정의된 varying 변수는 프래그먼트 셰이더에 선형보간되어 전달된다. varying 변수가 프래그먼트 셰이더에서 읽히면, 그값은 선형보간되어 있기에 버텍스 셰이더의 값과 다르다.

 

즉, 버텍스 셰이더에서 작성한 varying 과 프래그먼트에서 받은 varying은 값이 다르다는것이다. 나중에 코드를 보면 이해가 될것이다.

 

 

프래그먼트 셰이더의 출력 값은 개별 프래그먼트의 색상 값을 저장하고 있는 내장 변수인 gl_FragColor이다.

 

precision mediump float;
	varying vec4 vColor;
    void main() {
    	gl_FragColor = vColor;
       }

위코드는 프래그먼트 셰이더 예제이다.

 

셰이더 예제는 정밀도 선언이 붙은 변수를 선언하며 시작한다 precision mediump float;

 

이렇게 접두어를 붙이면 셰이더 컴파일러로 변수나 데이터 타입에 최소한의 정밀도를 보장할수 있도록 제공한다.

 

그다음은 varying 변수 vColor;를 선언하고 있다. main 함수 안에서 vColor는 내장 변수인 gl_Fracolor에 담긴다.

 

여기서 vColor는 버텍스 셰이더의 varying 변수가 션형 보간되어 넘어온 값이다.

 

 

 

프래그먼트 연산

 

(웹 애플리케이션 HTML + CSS + 자바스크립트 + 셰이더 소스코드 + 3차원 모델링 데이터) ->웹지엘(자바스크립트 API) -> 버텍스 셰이더 -> 프리미티브 어셈블리 -> 레스터화 -> 프래그먼트 셰이더 -> 가위테스트 ->멀티샘플 프래그먼트 연산 ->스텐실 테스트 -> 깊이 버퍼 테스트 -> 블렌딩 -> 디더링 ->그리기 버퍼

 

프래그먼트 셰이더를 빠져나온 각 프래그먼트는 프래그먼트 연산이 진행되는 단계로 넘어간다.

 

프래그먼트는 큰틀로 6단계로 활성 또는 비활성 할수있다.

 

 

--6단계--

가위테스트 ->멀티샘플 프래그먼트 연산 ->스텐실 테스트 -> 깊이 버퍼 테스트 -> 블렌딩 -> 디더링 

 

 

가위 테스트

가위 테스트는 좌하단 좌표와 너비 높이로 설정된 가위 사각형 안에 프래그먼트가 위치하고 있는지를 결정하는 단계이다. 만약 프래그먼트가 가위 사각형안에 있다면 테스트 통과, 프래그먼트는 다음 단계로 나아가고 외부에 위치하면 프래그먼트는 다음단계로 진행되지 못해 그리기 버퍼로 도달할수없다.

 

멀티샘플 프래그먼트 연산

프래그먼트의 알파값을 조정하고 안티 앨리어싱을 적용을 위해 그값을 변환한다.

 

컴퓨터 그래픽에서 안티앨리어싱이란 폴리곤의 선을 들쭉날쭉 하지 않고 부드럽게 화면에 표현하도록 개선하는 기법을 말한다.

 

스텐실 테스트

스텐실 버퍼상에서 입력으로 들어온 프래그먼트를 제외시킬지 여부를 테스트한다. 

 

예를들어 사각형 한개를 스텐실에 그려놓고, 차후에 색상 버퍼에 그려지는것이 사각형의 안팎어디에 있는지에 따라 영향을 미치는 연산을 구분해 적용할수있다.

 

 

깊이 버퍼 테스트

깊이 버퍼 테스트는 깊이 버퍼에 쓰여진 값에 따라 프래그먼트를 제외하는 테스트이다.

3D 장면이 2D 색상 버퍼에 그려질 때, 색상 버퍼는 오직 특정 시간에 관찰자가 보는 장면에 포함된 오브젝트의 색상 값만을 가질 수 있다.

장면에서 오브젝트는 다른 오브젝트에 의해 가려질수 있으며, 깊이 버퍼와 깊이 버퍼 테스트는 색상 버퍼에서 어떤 픽셀이 그려져야 하는지를 결정한다.

깊이 버퍼는 개별 픽셀에 대해 현재 관찰자로부터 가장 가까운 프리미티브와의 거리를 저장한다.

입력되는 프래그먼트가 포함하는 z-value값이 현재 깊이 버퍼의 같은 위치에 쓰여진 값과 비교된다.

이때 z-value 값이 깊이버퍼의 값보다 작을 경우, 이미 색상 버퍼에 기록된 픽셀보다 가까운것이고 이런 프래그먼트는 테그스트 통과한다. 반대경우인 클경우에는 새로운 프래그먼트는 현재 그리기 버퍼에 있는 픽셀에 가려진다고 판단하고 단계에서 제외된다.

 

블렌딩

프래그먼트의 색상값과 색상 버퍼의 같은 위치에 이전에 쓰여진 색상값을 혼합하며, 불투명한 오브젝트를 만들때 유용하다.

 

 

디더링

색상 버퍼는 모든 컬러를 표현하기에 제한된 비트를 가지고있다.

디더링은 실제 표현 가능한 색상보다 많은 색상값을 가진 것처럼 보이는 착시현상과 같은 방식으로 색상을 조정한다.

따라서 표현 가능한 색상이 적은 색상 버퍼에 유용하다.

.

 

 

--계속 --

 

 

 

728x90
반응형

댓글