조명 연산
앰비언트 라이트(간접광) + 디퓨즈(난반사) + 스페큘러(정반사) + ...
= 최종 조명.
빛 처리는 하나하나 구한 뒤에 모두 더해서 구한다.
디퓨즈, 스페큘러는 구현하는 유명한 방법이 있다.
현재도 이 방법에서 크게 변하진 않았다.
요즘에 '때깔이 좋다.' 라고 하는 것은 앰비언트 라이트가 많이 발전했기 때문이다.
디퓨즈(난반사) 구하기
디퓨즈를 구현하는 가장 유명하고 간단한 방법이 있다.
램버트, 하프 램버트 모델이다.
요즘 물리 기반 렌더링에서는 Oren-Nayar 모델로 디퓨즈를 구현한다고 한다.
램버트 (Lambert)
1. 빛을 직접 연구해보니까 Cos그래프와 비슷하더라. (램버트가 연구함.)
2. 우리에게 주어진 것은 벡터 2개이다. (Light 벡터, Normal 벡터)
3. 이 2개로 Cos을 어떻게 구할까.
4. 내적을 해보자. |A| * |B| * cosθ
5. |A| 와 |B| 를 1로 만들면 cos만 남겠구나. 1 * 1 * cosθ
6. 두 벡터를 Normalize하고, 내적을 하면 Cos 그래프가 구해지겠다!!
내적을 하는 것이 램버트 공식이 아니라 (맞긴 한데...)
Cos 그래프를 구하려다보니 내적을 하게 되었다. 라고 이해하는 게 맞다.
하프 램버트 (Half Lambert)
왼쪽이 램버트, 오른쪽이 하프 램버트이다.
램버트를 적용했을 때, 너무 어둡게 나오는 부분을 개선하기 위해 나온 것이다.
Steam을 만든 Valve에서 하프 램버트를 발표했다.
developer.valvesoftware.com/wiki/Half_Lambert
램버트, 하프램버트 공식
// 라이트 방향 구하기. 이 방향에 따라 벡터 내적할 때 방향을 뒤집냐 안뒤집느냐 결정함.
float3 lightDir = normalize(input.worldPosition - lightPosition);
// 램버트
float3 NdotL = dot(worldNormal, -lightDir); // (-1 ~ 1)
NdotL = saturate(NdotL); // (0 ~ 1), 0 이하는 어차피 어두운 부분이므로 짜름.
// 하프 램버트할거면 램버트에 아래 공식 추가.
NdotL = (NdotL * 0.5f) + 0.5f; // (0.5 ~ 1)
NdotL = pow(NdotL, 2); // 제곱해서 하프 램버트의 강도 조정. 2제곱이라서 (0.25 ~ 1)
// 적용.
float4 final = NdotL * color;
return final;
그래프로 나타내면,
1. 내적하기.
2. 0 이하인 값은 짜르기. (램버트 완성!)
3. 어두운 부분을 조금 더 밝게 하기. (하프 램버트 완성!)
4. 하프 램버트 강도 조절하기. (제곱하면 됨.)
위에는 풀어서 썼지만, 쓸 때는 간단하게 한 줄로 쓰면 된다.
// 램버트
float3 NdotL = saturate(dot(worldNormal, -lightDir));
// 하프 램버트 (램버트 공식에 추가된 것. 이거만 쓰는 거 아님.)
NdotL = pow((NdotL * 0.5f) + 0.5f, 2);
// 적용.
float4 final = NdotL * color;
return final;
작성한 코드
- Depth 버퍼 적용.
- 디퓨즈 만들기. (램버트, 하프램버트 사용.)
mingyu243/STL_GraphicsEngine2
Contribute to mingyu243/STL_GraphicsEngine2 development by creating an account on GitHub.
github.com
조명을 왼쪽 오른쪽으로 이동시켜보았다.
하프 램버트로 조명 연산 적용.
'기타 > DirectX' 카테고리의 다른 글
[DirectX11] 14일차 (타이머 만들기 / 노멀맵 적용하기) (0) | 2021.03.05 |
---|---|
[DirectX11] 13일차 (스페큘러 구하기 / 림 라이트 구현하기) (0) | 2021.03.04 |
[DirectX11] 11일차 (View, Projection 행렬 / 키 입력받아 카메라 이동, 회전) (0) | 2021.03.02 |
[DirectX11] 10일차 (인덱스 버퍼 만들기 / 클래스 정리하기) (0) | 2021.02.26 |
[DirectX11] 9일차 (DirectXTK, assimp 라이브러리 추가 / Mesh 불러오기) (0) | 2021.02.25 |