Graphics/DX11 물방울책 연습문제 풀이

DirectX 11을 이용한 3D게임 프로그래밍 입문 연습문제 7

득과광 2021. 4. 3. 14:03

문제 1

이번 장의 조명 예제를,지향 광원이 빨간빛만 방출하고 점광원은 녹색 빛만,점적 광원은 파란빛만 방출하도록 수정하라.

 

설명 및 해결

조명은 크게 3가지 종류로 나뉜다.

입사광이 거친 포면을 때린다고 가정할 때 빛은 그 표면에 의해 무작위 방향으로 반사될 것이다. 이를 분산 반사라고 하며 반사된 빛을 분 산광이라고 한다. DirectX에서는 무작위로 반사되는 빛을 일 정도록 구현하기 때문에 플레이어의 시점이 어디든 눈에 보이는 빛의 양은 항상 일정하다.

주변 광은 빛이 사방으로 반사되어 물체의 모든 면을 비추는 빛이다. 예를 들어 집에 있는 컵을 향해 빛을 비춘다고 해서 반대쪽 면이 깜깜해지진 않다.

반영 광은 물체의 매끄러움을 나타내는 빛이다. 반영 광은 원뿔 형태로 반사되기 때문에 일부 각도에서는 보이지 않을 수도 있다. 분산광과 반대로 플레이어 시점에 따라 반영광의 양이 변한다.

 

 

입사광의 각도에 따라 눈에 보이는 빛이 세게 보일수도, 약하게 보일 수도 있다. 90도에 가까울수록 반사되는 빛의 양이 많아 눈이 부시고 0도에 가까울수록 빛이 희미하게 보인다. 람베르트의 코사인 법칙이 이 기능을 유도할 수 있다.

출처 : 위키피디아

빛과 재질의 값, 그리고 이 법칙을 연산하여 조명을 구현할 수 있다. 

 

 

분산 광은 분산광의 색과 표면의 분산광 재질 색상에 의해 값을 구한 후 람베르트의 코사인 법칙에 의거하여 값을 조정한다. 분산광의 색과 분산광 재질 색상은 float4이며 rgba성분으로 이루어져 있다. 이는 주변광과 반영광도 마찬가지이다.

두 벡터를 곱한 값과 빛 벡터와 표면법선의 내적 값을 인자로 넣은 람베르트의 코사인 결괏값을 곱하면 분산광 결괏값이 나오게 된다. 여기서 내적을 구하는 이유는 원래 람베르트의 코사인 함수의 인자는 코사인이지만 내적을 통해 코사인 값을 구할 수 있기 때문에 내적으로 대체한 것이다. 참고로 빛 벡터와 표면 법선은 단위 벡터이다.

 

주변 광은 단순히 주변광의 양과 주변광 재질 색상을 곱하면 된다. 계산이 단순한 이유는 물체를 사방에서 비추기 때문에 물리적 계산이 필요하지 않기 때문이다. DirectX에서 주변광은 모든 방향에서 빛을 고르게 비추고 있다는 설정이다.

 

반영광이 표면에 닿았을 때 표면 법선을 기준으로 원뿔형태의 빛이 반사된다. 이 반사벡터를 기준으로 각도가 0에 가까우면 빛이 세지고 그 반대로는 약해진다. 반영광을 구현할때 반영지수 값을 조정해서 p값이 클수록 더더욱 매끄러움을 나타낼 수 있다. 값이 클수록 매끄러움이 강조되므로 원뿔 또한 작아진다. 카메라위치와 정점위치값을 뺀 값 벡터 v와 반사벡터 r을 내적한 값을 람베르트의 코사인 함수 인자값으로 넣는다. 그리고 반영광의 양과 반영광 재질 색상을 곱한값과 곱한다. 그러나 빛벡터와 표면법선을 내적 했을 때의 값이 음수일 수도 있다. 이는 빛이 도달하지 않는 영역에도 영향을 끼칠 수 있으니 음수일 경우 0으로 고정한다.

 

 

 

조명을 계산할 때 공통적으로 들어가는 연산은 빛 벡터와 재질 색상의 곱셈이다. 벡터 값을 잘 조절하면 프로그래머가 유도하는 색상이 나오도록 할 수 있다.

 

 


문제 2

이번 장의 조명 예제를,표면의 광택도를 제어하는 반영 지수를 여러 가지로 변경해서 실행해 보라. 이를테면 p = 8과 p = 32, p = 64, p= 128, p = 256,p = 512를 시도해 볼 것.

 

설명 및 해결

반영 지수에 값을 조정함으로써 매끄러움의 정도를 나타낼 수 있다. 반영광 재질 값을 가진 구조체 Material의 float4자료형인 Specular 멤버변수는 w값에 반영지수 p를 넣는다. 그래서 w값을 조절하면 매끄러움의 정도를 조정할 수 있다.

 

 왼 land와 wave의 반영광 p=8 일 때, 오 p = 512 일 때


문제 3

카툰 렌더링(cartoon rendering)을 위한 조명의 주된 특징 하나는,표면의 색이 한 색조에서 다른 색조로 매끄럽게 전이되는 것이 아니라 갑자기 변한다는 것이다.  카툰 렌더링을 수행하도록 이번 장의 조명 예제를 수정하라. 

 

해결

명암은 어두운 부분에서 밝은 부분으로 자연스러운 그러데이션이 있기 마련이지만 카툰 렌더링은 경계가 명확하다. 요즘 핫한 게임 원신에서도 카툰 렌더링을 적용했다. 구현하는 방법은 람베르트 코사인 값이 일정 범위의 값일 때 대신 상수값을 던져주는 것이다. 예를 들면 0~5라면 값을 0.2라던가 0.4로 던져주는 방식이다.

 

 

 

왼 : 적용 전, 오 : 적용 후

이로서 명암의 경계선이 명확해져 카툰 렌더링이 적용되었다.

 

문제 4

점적광 원뿔의 각도가 사용자의 키보드 입력에 따라 증가하고 나 감소하도록 수정하라.

 

설명 및 해결

점적 광은 쉽게 생각해서 손전등을 떠올리면 된다. 손전등의 불을 켜면 원뿔의형태로 빛이 나아가는데 이게 바로 점적광이다.

점적광은 각도에 따라 빛의 크기가 매끄럽게 증가하거나 감소한다. Spot 지수값으로 인해 각도 조절이 가능해지며 이를 조절하면 게임 플레이 중에서도 원하는 대로 값을 조절할 수 있을 것이다. 예를 들어 Spot값이 8이라면 원뿔의 각도는 45도가 되는 것이다.