조명

3 minute read

조명

재질

빛이 물체의 표면과 상호작용하는 방식을 결정하는 속성들의 집합

반사, 흡수하는 빛의 색상, 표면 아래 재질의 굴절률, 표면의 매끄러운 정도, 투명도 등이 재질의 속성이다.

재질이 흡수한 빛을 제외하고 반사한 빛의 양에 따라 관찰자는 물체의 색을 인식한다.

국소모형조형

각 물체를 다른 물체와는 독립적으로 처리,다른 물체에 반사되어 현재 물체에 도달한 빛은 무시하는 조형

전역 조명 모형

직접광뿐만 아니라 다른 물체에서 반사된 간접광도 고려하는 조형

하나의 물체에 조명을 가할 때 장면 전체의 모든 것을 고려해야 한다.

법선 벡터

다각형의 모든 점에 수직인 단위 벡터

표면 법선은 표면의 한 점의 접평면에 수직인 단위벡터이다.(표면의 한 점이 면한(facing) 방향을 결정)

정점 법선은 정점에 지정한 표면 법선이다.

삼각형 메시의 정점 법선들을 구할 때에는 정점 법선 평균 기법(vertex normal averaging)을 사용한다.

조명의 주요 벡터

빛 벡터는 표면의 점에서 광원을 가리키는 방향이다.

시점 벡터는 점 p에서 시점 E로의 단위벡터이다.

반사 벡터는 HLSL의 내장 함수 reflect를 이용하여 구할 수 있다.

람베르트 코사인 법칙

복사조도는 표면의 한 영역이 받는 빛의 양을 결정하는 것

빛이 표면을 정면으로 때리는 표면을 A1, 빛이 비스듬하게 때리는 표면이 A2라 하면 A2의 복사조도는 A1의 복사조도에 n·L=cosΘ을 곱한것이다.

이를 람베르트 코사인 법칙이라고 부른다.

분산 조명

빛이 표면의 한 점을 때렸을때 표면 바깥으로 나와 흩어지는 것을 분산 반사라고 부른다.

분산 조명 계산은 시점에 독립적이다.

분산 조명의 계산은 빛의 색상과 분산 반사율(diffuse albedo)을 이용하여 반사된 빛의 양을 구한다. 그 후 람베르트 코사인을 도입해서 빛의 양을 보정한다.

주변 조명

실생활에서 접하는 빛의 상당 부분은 간접광인데 이를 근사적으로 흉내내기 위해 주변광을 도입한다.

주변광은 실질적인 물리 계산에 관여하지 않고 장면 전체에서 반사, 분산되어 도달한 간접광들이 물체를 모든 방향에서 고르게 비춘다는 가정을 깔고 있다.

반영 조명

굴절률이 다른 두 매질 사이의 경계면에 빛이 도달하면 빛의 일부는 반사되고 나머지는 굴절되는데 이를 반영 반사라고 부르고, 반사된 빛을 반영광(specular light)이라 부른다.

굴절 벡터 방향으로 나아가는 빛이 매질을 떠나서(반대쪽으로) 눈에 들어오면 물체가 투명해 보인다.(빛이 투명한 물체를 통과하는 것)

반영광은 특정 방향으로만 반사되므로 반영 조명은 시점 의존적이다.

프레넬 효과

반사광의 양은 법선과 빛 벡터 사이의 각도와 재질에 의존한다.

각도가 90도에 가까워질수록 반사광의 양이 증가한다.

표면 거칠기

표면이 들쭉날쭉한 정도

수학적으로 모형화하기 위해 미세면(microfacet) 모형을 도입

시점벡터v와 빛벡터 L이 주어졌을 때 L을 v방향으로 반사하는 미세면들의 비율은 반영 반사에 의해 눈에 도달하는 빛의 양을 말해준다.

L을 v로 반사하는 미세면이 많을수록 눈에는 더 밝은 반영광이 도달한다.

평행광(지향광)

지향광은 아주 멀리 있는 광원에서 빛을 근사한다.

아주 멀리 있는 광원에서 온 빛을 근사하기 때문에 모든 입사광선이 서로 평행하다고 가정한다.

방향벡터는 하나이다.

모든 점에 대해 동일한 빛 벡터를 사용한다.

대표적으로는 광원은 태양이다.

점광(point light)

점광의 예는 전구이다.

점광은 점마다 빛 벡터를 달리 계산해야한다.

빛의 세기는 I(d) = I/d^2이다 (거리의 역제곱에 비례해 약해진다)

거리 계산으로 인해 지향광보다 비용이 높다.

점광의 세기는 밑의 이미지와 같은 선형 감쇠 함수를 사용한다.

pointLight1 pointLight2

점적광

점적광의 예는 손전등이다.

점적광은 위치 Q에서 d방향으로 뻗어 나가는 원뿔 형태의 빛이다.

점광을 구하는 공식에 점적광 계수를 곱해야하기 때문에 점광보다 비용이 높다.

예제 연습

연습문제 1번 - 빨간빛만 방출하는 지향광

Default.hlsl의 픽셀 셰이더 내부의 값을 조정하여 빨간 빛만 방출하도록 수정하였다,

directLight.y = 0;
directLight.z = 0;

sin 함수를 이용하여 점멸하는 연출 또한 포함하여 구현하였다.

 directLight = directLight * sin(gTotalTime);

아래의 두 스크린샷은 위의 빨간 빛 방출과 sin함수를 적용한 결과이다.

red1

red2

연습문제 4번 - 점광원

기둥 위에 놓인 각 구의 중심에 점광원을 추가하는 예제를 구현하였다.

light1

연습문제 5번 - 점적광원

기둥 위에 놓인 각 구의 중심에 아래쪽을 향한 점적광원을 추가하는 예제를 구현하였다.

UpdateMainPassCB 함수 내부에 아래와 같은 코드를 추가하여 점적광원을 사용하였다.

연습문제 4번의 예제는 아래의 코드와 유사하다.

	for(int i = 0; i < 5; i++){
		mMainPassCB.Lights[i].Strength = { 0.6f, 0.6f, 0.6f };
		mMainPassCB.Lights[i].Position = XMFLOAT3(-5.0f, 3.5f, -10.0f + i * 5.0f);
		mMainPassCB.Lights[i].Direction = XMFLOAT3(0, -2, 0);
		mMainPassCB.Lights[i].FalloffStart = 2;
		mMainPassCB.Lights[i].FalloffEnd = 5;
		mMainPassCB.Lights[i].SpotPower = 1;
	}

	for(int i = 0; i < 5; i++){
		mMainPassCB.Lights[i + 5].Strength = { 0.6f, 0.6f, 0.6f };
		mMainPassCB.Lights[i + 5].Position = XMFLOAT3(+5.0f, 3.5f, -10.0f + i * 5.0f);
		mMainPassCB.Lights[i + 5].Direction = XMFLOAT3(0, -2, 0);
		mMainPassCB.Lights[i + 5].FalloffStart = 2;
		mMainPassCB.Lights[i + 5].FalloffEnd = 5;
		mMainPassCB.Lights[i + 5].SpotPower = 1;
	}

light2

연습문제 6번 - 툰셰이딩

LightingUtil.hsls의 BlinnPhong 함수 내부 값 specAlbedo와 mat.DiffuseAlbedo의 값을 이산함수를(구현시에는 if문으로 하였다) 통해 변환하여 툰셰이딩을 적용하도록 구현하였다.

specAlbedo는 반영광, matDiffuseAlbedo 분산광을 계산하는데 사용된다.

cartoon