응애맘마조
Directional Light, Spot Light, Point Light 본문
Directional Light
디렉셔널 라이트는 무한히 먼 거리에 있는 광원에서 오는 빛을 흉내 내는 것입니다.

광원이 빛을 쏘는 방향을 벡터로 나타내고 이 방향벡터를 조명에 계산할 때 빛 벡터로 사용하면 됩니다. 각 방향벡터가 회전한 만큼 방향이 업데이트되고 이 정면 벡터를 빛의 방향벡터로 사용하면 됩니다.
입력으로 정점, 노멀, 색상을 받기에 이 요소들을 적절한 공간으로 이동시키는 연산을 수행시키면 됩니다.
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output;
output.Pos = mul(float4(input.Pos, 1), WorldViewProjection);
output.WPos = mul(float4(input.Pos, 1), World);
output.Color = input.Color;
output.Normal = normalize(mul(input.Normal, (float3x3) World));
return output;
}
이것을 가지고 PS에서는 Diffuse와 Specular을 구하고 이를 합쳐서 최종적인 색상으로 출력을 합니다.
우선 Diffuse를 구하려면 빛의 방향벡터(LightDir)와 현재 픽셀의 노멀이 필요합니다. 두 데이터의 공간은 일치해야 하고 노멀은 정점 셰이더에서 월드 공간으로 변환이 되었으므로, 다시 노멀라이즈만 한 번 더 해줍니다.
LightDir은 회전 및 이동이 적용되어 월드 공간으로 이동된 상태로 넘어오기 때문에 월드 변환은 불필요합니다. 따라서 노멀과 동일하게 노멀라이즈만 적용한다. 다음 Diffuse를 구하기 위해 LightDir와 노멀을 내적 합니다.
Diffuse가 음수면 안되므로, max 함수를 통해 결과가 음수일 경우 0으로 설정합니다. 최종적으로 Diffuse에 대한 색상 값 계산을 위해 빛의 색상, 빛의 강도, 현재 프래그먼트(픽셀)의 색상을 곱합니다.
매우 높은 곳에서 광선을 쏜다고 가정하기 때문에 광원의 위치는 조명에 영향을 끼치지 않습니다. Rotation은 광원이 빛을 쏘는 방향(벡터)을 변화시키기 때문에 영향을 미칩니다.
Spot Light
스포트 라이트는 특정한 위치에서 특정한 방향으로 원뿔 모양의 빛을 발사하는 광원입니다.

주로 위와 같은 사진과 같습니다.

위와 같이 cone 모양의 광원을 발사하는데, cone은 inner cone과 outer cone으로 구성됩니다.
inner cone에 속하는 픽셀들은 빛의 세기를 100% 적용받을 수도 있고 아닐 수도 있습니다. 그리고 inner cone과 outer cone 사이의 픽셀들은 감쇠된 빛을 받습니다. outer cone 외부의 점들은 해당 spotlight의 빛을 받지 못합니다.
먼저 기본적인 원뿔 형태의 빛을 발사할 수 있도록 inner cone의 angle과 outer cone의 angle을 설정합니다. 그러기 위해서는 이 빛의 방향을 나타내는 방향벡터가 필요합니다. 이 빛 벡터를 inner, outer cone angle 만큼 회전시키면 다음과 같이 전구로부터의 각 cone을 나타내는 방향벡터를 얻을 수 있습니다.
다음 VS에서는 월드 공간의 정점만 PS로 넘기면 됩니다.
가장 우선적으로 현재 픽셀의 위치가 outer cone의 영역 안에 있는지 밖에 있는지 계산해야 합니다. 만약 영역 밖에 있으면 현재 광원의 영향을 받지 않으므로 무시하면 됩니다.
광원으로부터 현재 픽셀까지의 벡터를 구한 뒤 이 벡터와 빛 벡터가 이루는 각이 outer cone angle보다 크면 밖에 있는 것이고 작으면 안에 있는 것입니다.
광원으로부터 현재 픽셀까지의 벡터인 CurDir을 구하고 LightDir과의 내적을 통해 cos값(θ)을 구합니다. 그리고 OutDir과 LightDir의 내적을 통해 cos값(θ)을 구합니다. cos은 각이 클수록 값이 작아지므로 CurDir과 LightDir과의 내적 값이 더 작다면 outer cone의 밖에 있는 것입니다.
Point Light
포인트 라이트는 어떤 Point로부터 모든 방향으로 동일한 세기의 빛을 뿜는 광원을 말합니다.

주로 전구와 같은 것을 표현하기에 적합합니다.
Directional Light처럼 빛을 한 방향으로만 비추는 것이 아니기 때문에 방향벡터는 필요하지 않습니다. 또한 Directional Light와 달리 광원의 위치가 조명 연산에 영향을 미칩니다. 따라서 방향벡터 대신 광원의 위치를 셰이더로 가져와 광원과 현재 정점의 관계를 통해 빛 벡터를 얻어야 합니다.
읽어주셔서 감사합니다.
'공부 > 3D과제' 카테고리의 다른 글
손전등 만들기 (0) | 2023.08.22 |
---|---|
렌더 투 텍스쳐, 포스트 이펙트, 블러 (0) | 2023.08.07 |
큐브 맵, 사운드 로드 (0) | 2023.07.28 |
다익스트라, 에이스타 (0) | 2023.07.12 |
GPGPU, 컴퓨트 셰이더 (0) | 2023.07.11 |