C++로 연산한 Phongshader의 코드만을 가져와서 기록
호출되는 함수의 내부를 보면 해당 연산으로 구성되어 있는데 하나씩 뜯어보겠다.
- 첫번째 문단
* 첫번째 Lighting은 현재 렌더링 되어질 공간에 존재하는 광원을 가져오는 것이다. 주석에 적힌대로 방향광을 전제로 하였으며 광원은 하나만 존재하도록 하였다.
- l_DirLight : 방향광의 방향을 나타내는 벡터
- ldotPixNor : 내적을 통해 방향광과 픽셀노말이 이루는 사잇각의 값을 구한 것이다. 이때 사용된 픽셀 노말은 구체를 생성할 때 물체 중심부의 중점과 정점을 이용해 정점의 노말을 구하고, 픽셀을 포함하고 있는 폴리곤의 정점노말 값과 폴리곤의 무게중심좌표계를 이용하여 각 픽셀의 노말값을 구한 것이다. 정점을 이용해 외적하여 구한 노말값보다는 정확도가 떨어지지만 미리 구해놓을 수 있고 연산량을 줄일 수 있다는 이유에서 사용. 고폴리곤의 물체로 갈수록 오차가 줄어들 수 있다.
- v_ObjToCamera : 카메라에서 물체로 향하는 벡터를 구한 값.
- a_Shining : 광원이 가질 상수값을 나타내는 값이다.
- Ambient, Diffuse, Specular : 퐁으로 구해야할 값을 선언함. 원래라면 Color같은 구조체로 표시되어야하나 Vector3등의 구조체를 3D라이브러리 없이 직접 제작하여 사용하는 탓에 RGB의 세 float 값을 사용하는 Color값도 Vector3를 이용해 선언함
- 두번째 문단
- ldotPixNor을 기준으로 0보다 클때와 작을때로 나누어 연산식을 달리했다. ldotPixNor이 0보다 작은 경우는 광원과 픽셀이 마주보고 있는 경우이고 0보다 클 경우는 광원과 픽셀이 바라보는 방향이 같은 경우이다. 픽셀과 광원이 바라보는 방향이 같은 경우는 픽셀이 광원의 빛을 반사시킬 수 없는 경우이고 마주보는 경우는 빛을 반사시킬 수 있는 경우로 나뉘기 때문.
- Ambient : GetKAmb()는 상수값을 얻는 함수이고 전달받은 변수의 _PD.Ambient값은 물체에 기본적으로 설정된 Ambient, Diffuse, Specular값 들이다. Ambient는 기본적으로 색을 표현하기위해 게임에서는 연산대신에 상수처럼 어느정도 값을 주기때문에 복잡한 연산대신 상수와 기본값을 이용해 구해진다.
- Diffuse : 지금 연산이 ldotPixNor의 값이 0보다 큰 경우라 빛을 받을 수 없는 상태라 연산 공식이 의미가 없다. 0이 나올것이고 검은색으로 처리될 것. 빛을 받아 연산이 이루어지는 부분에서 공식을 자세히 풀어보겠다.
- Specular : 이 부분 역시 현재 빛을 받을 수 없는 상태이기때문에 0으로 임의 처리하였다.
- 세번째 문단
- r_ReflectVec: 이름 그대로 반사벡터다.
그림에 따라서 반사벡터의 공식은 P+2n(-P dot n)이 되는데 ldotPixNor로 이미 (P dot n)을 구해 놓았기에 그대로 사용하고 괄호 내부의 -기호만 밖으로 빼내어 -2를 곱해주었다.
- Ambient : 여기서는 광원과 마주보고 있는 경우의 연산이나 Ambient는 여전히 기본값과 같은 개념이기 때문에 연산 없이 기본값들로 간단히 계산하여 준다.
- Diffuse : 앞부분은 상수과 이미 설정되어 있던 물체의 값을 연산하지만 max(-1 * Dot(PixelNormal, l_DirLight), 0.f)은 실제 연산부. 앞부분으로 강도를 조절할 수 있다.
그림으로 확인 가능한데 0.707과 -0.707은 90도의 법선을 기준으로 서로 대칭이다. 이를 이용해 광원의 입사각과 픽셀의 노말 벡터를 이용해 내적값을 구하고 -1을 곱해주면 반사벡터를 구할 수 있으므로 위의 공식으로 반사벡터를 구해준다.
- Specular : GetKSpec()과 _PD.Specular는 적용할 Specular의 기반이 되는 값이고 이후에 연산되는 값에 따라 그 강도가 정해진다. max(-1 * Dot(r_ReflectVec, v_ObjToCamera), 0.f)의 값은 Diffuse와 원리가 같은 공식이고 사용되는 벡터만 달라졌다. 물체를 향하는 카메라의 벡터와 광원의 반사벡터를 이용한다. 그렇게 구한 값을 미리 설정된 광원의 상수값만큼 Pow로 제곱하여 적용하면 Specular값이 연산된다.
- 네번째 문단
이렇게 연산된 값을 각 XYZ는 RGB에 1:1 대응하는데 각 X는 X끼리, Y는 Y끼리, Z는 Z끼리 더하여 색깔 값으로 전달한다. 이렇게 전달된 색데이터를 기반으로 DotPixel하여 Phongshader를 구현하였다.
'3D Rendering' 카테고리의 다른 글
TBR(Tile-based Render) (0) | 2023.09.28 |
---|---|
Deffered Render 메모리 대역폭 문제 (0) | 2023.09.28 |
Light Pre-Pass (0) | 2023.09.28 |
Deffered Render (0) | 2023.09.28 |
Forward Render (0) | 2023.09.28 |