- DirectX의 조명 모델에서 광원이 만들어 내는 빛은 아래의 3가지 요소로 구성되어 있습니다.
- 아래 3가지 요소를 적절하게 합쳐 자연스러운 빛 효과를 낼 수 있습니다.
Material 간단 설명
- Material은 3D 그래픽스에서 물체의 표면 특성을 정의하는 데 사용되는 개념입니다.
- 빛의 상호 작용, 색상, 반사 등을 제어하여 물체가 어떻게 렌더링 되는지를 결정합니다.
- 앞으로 나오는 Material은 간단히 물체에 적용될(흡수하는) 색상 정도로 생각해주시면 되겠습니다.
- Ambient는 환경광으로 광원이 불분명한 빛을 의미합니다.
- 즉, 이곳 저곳 반사되어 돌아다니다 최종적으로 물체에 맞는 빛입니다.
- 특징 : 일정한 밝기와 색으로 표현
Ambient Light의 공식
float4 color = LightAmbient * MaterialAmbient;
- 빛의 세기와 Material에서 설정한 Ambient의 값을 곱해주면 완성됩니다.
- Diffuse Light는 특정한 방향으로 진행하며, 표면에 닿으면 모든 방향으로 동일하게 반사됩니다.
- 간단히 생각했을 때의 가장 일반적인 빛 형태라고 생각할 수 있습니다.
- 특징 : 각도에 따라 밝기가 다르다.
Diffuse Light 공식
// 공용 셰이더에서 설정한 SamplerState를 적용시켜줍니다. float4 color = DiffuseMap.Sample(LinearSampler, input.uv); // 출력될 색상을 조명의 연산에 따라 추가 연산해줍니다. float value = dot(-LightDir, input.normal); color = color * value * LightDiffuse * MaterialDiffuse;
- Specular Light는 Diffuse Light와 비슷하지만 반짝임 효과를 내기 위해 사용합니다.
- 물체의 Normal벡터에 반사된 빛 벡터와 물체에서 눈(Camera)으로 가는 벡터를 구해 둘 사이의 값에 따라 반짝임(눈부심 효과)을 조정합니다.
- 특징 : 한 방향으로 완전히 반사되는 빛
Specular Light 공식
// 반사된 빛의 벡터를 구해줍니다. // 1. 내장 함수 이용하기 reflect() // 2. 직접 구하기 //float3 R = reflect(LightDir, input.normal); // * dot(LightDir, input.normal)와 input.normal을 곱해준 이유 // -> dot(LightDir, input.normal)의 결과는 스칼라 값 -> 벡터로 변경해주기 위함 float3 R = LightDir - (2 * input.normal * dot(LightDir, input.normal)); // 카메라의 위치를 구해줍니다. // * View 행렬의 4-1,2,3 인자를 꺼내 -부호를 붙여준 것이 카메라의 위치입니다. float3 cameraPosition = -V._41_42_43; // 물체에서 카메라까지 가는 방향 벡터를 구해줍니다. // * 월드상의 (카메라 위치 - 물체 위치)의 정규화 float3 E = normalize(cameraPosition - input.worldPosition); // 구한 방향벡터들을 내적해 값을 추출합니다. (R, E) // * 항상 0 ~ 1 사이의 값을 남기기 위해 saturate() 함수 사용 // * saturate() : 0 ~ 1 사이를 유지시켜주는 함수입니다. 0이하로 내려가면 0, 1이상으로 넘어가면 1로 유지시켜줍니다. float value = saturate(dot(R, E)); // Specular 값으로 연산해 넣어줍니다. // * 연산이 필요한 이유 : 0 ~ 1 사이의 값을 사용하면 너무 넓은 범위가 설정됩니다. // * 0 ~ 1 사이의 값이므로 제곱을 통해 값을 줄여 범위를 줄여줄 수 있습니다. float specular = pow(value, 10); // 최종적으로 반환하기 위한 색상을 구해줍니다. // * 다른 빛들은 텍스처와 상관있게 표현했지만, Specular는 눈부심을 적용하기 위해 주로 사용하므로, 텍스처의 샘플링 없이 진행합니다. float4 color = LightSpecular * MaterialSpecular * specular;
- 어떤 물체가 받을 여러 종류의 빛의 총 합은 간단히 덧셈을 통해 구해주면 됩니다.
ex) return ambientColor + diffuseColor + specularColor;