조명 및 셰이딩 (Computer Graphics Lighting and Shading)
광원의 종류 (Types of Light Sources)
소개 (Introduction)
광원은 3D 씬에서 객체를 비추어 현실감 있는 이미지를 생성하는 데 필수적인 요소입니다. 다양한 종류의 광원이 있으며, 각각의 특성과 사용법이 다릅니다.
개념 (Concept)
- 점광원 (Point Light): 한 점에서 모든 방향으로 빛을 발산하는 광원입니다. 전구와 같은 역할을 합니다.
- 평행광원 (Directional Light): 특정 방향으로 평행하게 빛을 발산하는 광원입니다. 태양빛과 유사합니다.
- 스포트라이트 (Spotlight): 특정 방향으로 원뿔 형태의 빛을 발산하는 광원입니다. 무대 조명과 유사합니다.
원리 (Principle)
- 점광원: 위치와 감쇠 계수를 사용하여 거리와 각도에 따른 빛의 강도를 계산합니다.
- 평행광원: 위치가 없고, 일정한 방향으로 빛을 발산하여 그림자와 조명이 일정하게 나타납니다.
- 스포트라이트: 점광원과 유사하지만, 빛의 범위를 원뿔 형태로 제한합니다. 원뿔의 각도와 방향을 고려하여 빛의 강도를 계산합니다.
예제 (Example)
// GLSL 예제: 점광원 struct PointLight { vec3 position; vec3 color; float constant; float linear; float quadratic; }; vec3 CalculatePointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir) { vec3 lightDir = normalize(light.position - fragPos); float diff = max(dot(normal, lightDir), 0.0); vec3 reflectDir = reflect(-lightDir, normal); float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); float distance = length(light.position - fragPos); float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); vec3 ambient = 0.1 * light.color; vec3 diffuse = diff * light.color; vec3 specular = spec * light.color; ambient *= attenuation; diffuse *= attenuation; specular *= attenuation; return (ambient + diffuse + specular); }
조명 모델 (Lighting Models)
소개 (Introduction)
조명 모델은 3D 장면에서 빛이 객체와 상호작용하는 방식을 정의합니다. 다양한 조명 모델이 있으며, 각각의 모델은 다른 특성과 계산 방식을 가집니다.
개념 (Concept)
- Phong: 반사광과 난반사를 고려한 고전적인 조명 모델입니다.
- Blinn-Phong: Phong 모델의 변형으로, 반사광 계산을 최적화하여 성능을 개선한 모델입니다.
- Lambert: 가장 간단한 조명 모델로, 난반사만을 고려합니다.
역사 (History)
- Phong: 1975년 Bui Tuong Phong에 의해 개발되었습니다.
- Blinn-Phong: 1977년 Jim Blinn에 의해 Phong 모델이 개선되었습니다.
- Lambert: 18세기 수학자 Johann Heinrich Lambert에 의해 정의된 빛의 반사 법칙을 따릅니다.
원리 (Principle)
- Phong: 반사광과 난반사를 각각 계산하여 최종 색상을 결정합니다.
- Blinn-Phong: Phong 모델의 반사광 계산을 개선하여 성능을 향상시킵니다.
- Lambert: 난반사만을 고려하여 각 픽셀의 색상을 결정합니다.
예제 (Example)
// GLSL 예제: Phong 조명 모델 vec3 CalculatePhongLighting(vec3 lightPos, vec3 viewPos, vec3 normal, vec3 fragPos, vec3 lightColor) { vec3 ambient = 0.1 * lightColor; vec3 lightDir = normalize(lightPos - fragPos); float diff = max(dot(normal, lightDir), 0.0); vec3 diffuse = diff * lightColor; vec3 viewDir = normalize(viewPos - fragPos); vec3 reflectDir = reflect(-lightDir, normal); float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); vec3 specular = spec * lightColor; return (ambient + diffuse + specular); }
그림자 생성 (Shadow Creation)
소개 (Introduction)
그림자는 3D 장면에서 객체가 빛을 차단하여 생기는 어두운 영역입니다. 그림자는 장면의 현실감을 높이는 중요한 요소입니다.
개념 (Concept)
- Shadow Mapping: 뷰포인트에서 보이는 객체의 깊이 정보를 사용하여 그림자를 생성하는 기술입니다.
- Shadow Volume: 객체의 실루엣을 이용하여 그림자를 생성하는 기술입니다.
원리 (Principle)
- Shadow Mapping: 빛의 시점에서 씬을 렌더링하여 깊이 맵을 생성한 후, 이 깊이 맵을 사용하여 픽셀이 그림자에 있는지 판단합니다.
- Shadow Volume: 객체의 실루엣을 이용하여 볼륨을 생성하고, 이 볼륨 내에 있는 픽셀을 그림자로 표시합니다.
예제 (Example)
// GLSL 예제: Shadow Mapping vec3 CalculateShadow(vec4 fragPosLightSpace, sampler2D shadowMap) { vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; projCoords = projCoords * 0.5 + 0.5; float closestDepth = texture(shadowMap, projCoords.xy).r; float currentDepth = projCoords.z; float shadow = currentDepth > closestDepth ? 0.7 : 1.0; return vec3(shadow); }
셰이더 기초 (Shader Basics)
소개 (Introduction)
셰이더는 GPU에서 실행되는 작은 프로그램으로, 3D 그래픽스 파이프라인의 특정 단계를 처리합니다. 주로 정점 셰이더와 프래그먼트 셰이더가 사용됩니다.
개념 (Concept)
- 정점 셰이더 (Vertex Shader): 3D 모델의 정점을 변환하고, 조명을 계산합니다.
- 프래그먼트 셰이더 (Fragment Shader): 각 픽셀의 색상을 계산하고, 텍스처 매핑을 적용합니다.
역사 (History)
- 초기의 그래픽스 파이프라인은 고정 기능으로 이루어져 있었으나, 2000년대 초반부터 프로그래머블 셰이더가 도입되었습니다.
원리 (Principle)
- 정점 셰이더: 각 정점을 처리하여 클립 공간으로 변환하고, 조명 계산을 수행합니다.
- 프래그먼트 셰이더: 각 프래그먼트를 처리하여 최종 색상을 결정하고, 텍스처 매핑을 적용합니다.
예제 (Example)
// GLSL 예제: 정점 셰이더 #version 330 core layout(location = 0) in vec3 aPos; uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { gl_Position = projection * view * model * vec4(aPos, 1.0); } // GLSL 예제: 프래그먼트 셰이더 #version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0, 0.5, 0.2, 1.0); // 주황색으로 출력 }
셰이더를 통해 3D 그래픽스 파이프라인의 다양한 단계를 사용자 정의하여 복잡한 그래픽 효과를 실현할 수 있습니다. 정점 셰이더와 프래그먼트 셰이더는 이러한 과정에서 핵심적인 역할을 합니다.