주변광 Ambient Light 알고리즘
목차
인사말
주변광이 무엇인가?
주변광 알고리즘
인사말
해당 글은 [DoronFeinstein13] 책의 내용을 저의 방식대로 정리하고 재해석하였습니다.
해당 책에 오타가 많고, 설명이 매우 적어서 저에게는 중간중간에 겪는 문제들이 있었습니다.
이러한 문제들에 대한 해답과 정제된 내용이 여러분에게 도움이 됬으면 좋겠네요.
주변광이 무엇인가?
현실세계에서는 수많은 종류의 빛이 존재하며 산란광, 반사광 또 우리가 알아볼 주변광이 거기에 속하죠.
어떠한 빛이 물체를 때리면 해당 물체의 재질(Material)에 따라 특정 비율로 반사되거나 굴절되거나 물체 내부로 들어가 산란하는데 이때 여러경로로 나아가면서 다수의 물체를 때리면서 주변을 밝게 비추어주는 빛이 우리가 이번에 알아볼 주변광입니다.
우선 주변광은 그 물체가 가지는 최소한의 색을 우리에게 보여줍니다.
사실 게임에서 이 주변광을 현실세계에 근사하게 표현하려면 막대한 계산량이 소요됩니다.
그래서 우리는 그래도 봐줄만하면서 얼추 비슷한데 연산량이 그렇게 많지 않은 방법을 이용할것입니다.
주변광 알고리즘
이전까지 저가 공부했던 주변광 알고리즘들은 그냥 단순하게 단일 색을 CPU에서 지정해서 입혀주기만 했습니다.
하지만 이번에 소개할 알고리즘은 노말값을 이용합니다.
노말값을 이용하면서 좀 더 입체적인 주변광을 구현할 수 있습니다.
위와 같이 어떠한 폴리곤이 정점마다 자신의 노말값들을 가지고있습니다.
그리고 그 노말값들은 그 버텍스가 바라보는방향으로 되어있죠.
어쩌면 기울기를 나타낸다고도 볼수있죠.
평평할수록 밝기값이 크거나 가파를수록 밝기값이 작아지기도하죠.
주변광 알고리즘은 이러한 성질을 이용해서 입체적인 주변광을 표현할 것입니다.
노말값에 따라 주변광이 어두워지거나 더 밝아지거나 해야되겠죠.
따라서 우리는 이때 제일 어두운 색깔과 제일 밝은 색깔을 미리 CPU로 지정해주어야합니다.
[CPU]
AmbientMinColor = (0.1, 0.1, 0.1, 1.0)
AmbientMaxColor = (1.0, 1.0, 1.0, 1.0)
AmbientRange = AmbientMaxColor - AmbientMinColor
이때 주변광의 색깔범위도 미리 구해주어야합니다.
왜냐하면 [0, 1]사이로 매핑된 노말값을 통해 선형으로 보간하여 최종 색상을 셰이더에서 지정해야하기 때문입니다.
따라서 최종 셰이더 코드는 다음과 같이 만들어집니다.
최종 셰이더 코드
// normal: World좌표계에서의 노말값[-1, 1]
// color: 물체의 본래색상
loat3 CalculateAmbient(float3 normal, float3 color)
{
// 노말값의 범위를 [-1, 1]에서 [0, 1]사이로 바꿔준값을 저장한다.
// 이유는 주변광의 범위에 맞게 선형으로 보간할것이기 때문
float up = normal.y * 0.5 + 0.5;
// 선형 보간
float3 ambient = AmbientDown + up * AmbientRange;
// 물체의 원래 색상값을 곱해준다.
return ambient * color;
}