Chapter 5.0, 5.1과 동일한 부분은 제외하고 설명 드립니다.
아래 내용을 참고하세요
https://graphicsimon.tistory.com/109
Chapter 5.1 Phong Shader
퐁 셰이딩은 픽셀 단위에서 보간된 노말 벡터를 사용해 조명 계산을 수행하는 방식.부드럽고 자연스러운 하이라이트 표현이 가능함.Vertex Shading ( Gouraud ) VS Fragment Shading ( Phong ) Vertex Shading ( Gourau
graphicsimon.tistory.com
다중 광원
- 빛을 여러개 렌더링 하는 기법을 배워 본다.
- diffuse 컬러 (빨강, 초록)으로 구성된 light를 4개를 배치한다..
4개의 라이팅 색상 값, 위치 값 정의
다중 광원의 diffuse color와 위치를 저장할 배열을 만들어 준다.
glUniform3fv 사용하여 vec3를 여러개 보낼 수 있다.
void ObjLoader::InitMultiLight() {
// 쉐이더 프로그램에서 uniform 배열 "LightPositionArray[0]"의 위치를 가져옴
// 주의: (char*) 캐스팅은 C스타일이며, const char* 또는 std::string을 쓰는게 안전함
char LightPositionArray = ProgramManagerObj->ProgramGetUniformLocation(program, (char*)"LightPositionArray[0]");
char LightDiffuseArray = ProgramManagerObj->ProgramGetUniformLocation(program, (char*)"LightDiffuseArray[0]");
// 4개의 광원 위치 지정 (각각 x, y, z 3요소씩 총 12개)
float lightpositions[12] = {
-30.0, 0.0, 5.0, // 광원 1 위치
0.0, 10.0, 5.0, // 광원 2 위치
10.0, 0.0, 5.0, // 광원 3 위치
0.0, -10.0, 5.0 // 광원 4 위치
};
// 4개의 광원 색상 (각각 r, g, b 3요소씩 총 12개)
float lightdiffusecolors[12] = {
1.0, 0.0, 0.0, // 광원 1 색상: 빨강 (Red)
0.0, 1.0, 0.0, // 광원 2 색상: 초록 (Green)
1.0, 0.0, 0.0, // 광원 3 색상: 빨강 (Red)
0.0, 1.0, 0.0 // 광원 4 색상: 초록 (Green)
};
// uniform 변수 위치가 유효하면, 해당 uniform에 데이터 전송
if (LightPositionArray >= 0) {
// 3개의 float 값으로 구성된 4개의 벡터 → 총 12개
glUniform3fv(LightPositionArray, 4, lightpositions); // count = 4 (vec3 개수)
}
if (LightDiffuseArray >= 0) {
glUniform3fv(LightDiffuseArray, 4, lightdiffusecolors); // count = 4 (vec3 개수)
}
}
Vertex Shader
버텍스 셰이더는 동일
#version 300 es
// Vertex information
layout(location = 0) in vec4 VertexPosition;
layout(location = 1) in vec3 Normal;
// Model View Project matrix
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
out vec3 normalCoord;
out vec3 eyeCoord;
void main()
{
normalCoord = NormalMatrix * Normal;
eyeCoord = vec3 ( ModelViewMatrix * VertexPosition );
gl_Position = ModelViewProjectionMatrix * VertexPosition;
}
Fragment Shader
빛의 위치가 달라지면, 빛의 방향이 달라진다.
Light diffuse 달라진다.
구한 컬러값을 더해서 출력 해 본다.
//=====================//
// Fragment Shader
//=====================//
#version 300 es
precision mediump float;
// ===== 재질 속성 =====
uniform vec3 MaterialAmbient;
uniform vec3 MaterialDiffuse;
uniform vec3 MaterialSpecular;
uniform float ShininessFactor;
// ===== 광원 속성 =====
uniform vec3 LightAmbient; // 공통 환경광
uniform vec3 LightSpecular; // 공통 정반사광
uniform vec3 LightPositionArray[4]; // 각 광원의 위치
uniform vec3 LightDiffuseArray[4]; // 각 광원의 난반사광 색상
// ===== 인터폴레이션된 값 =====
in vec3 normalCoord; // 뷰 공간 노멀
in vec3 eyeCoord; // 뷰 공간 정점 위치
layout(location = 0) out vec4 FinalColor;
vec3 PhongShading(int index) {
// 정규화된 벡터 계산
vec3 N = normalize(normalCoord); // 노멀
vec3 L = normalize(LightPositionArray[index] - eyeCoord); // 광원 방향
vec3 V = normalize(-eyeCoord); // 카메라 방향
vec3 R = reflect(-L, N); // 반사 벡터
// 각 조명 성분 계산
float diff = max(dot(N, L), 0.0); // 난반사 세기
float spec = pow(max(dot(R, V), 0.0), ShininessFactor); // 정반사 세기
// 각 조명 성분 결과
vec3 ambient = MaterialAmbient * LightAmbient;
vec3 diffuse = MaterialDiffuse * LightDiffuseArray[index] * diff;
vec3 specular = MaterialSpecular * LightSpecular * spec;
return ambient + diffuse + specular;
}
void main() {
vec3 finalColor = vec3(0.0);
// 4개의 광원에 대해 조명 계산 후 누적
for (int i = 0; i < 4; i++) {
finalColor += PhongShading(i);
}
// 밝기 조절용 스케일 (필요 시 조절)
FinalColor = vec4(finalColor / 2.0, 1.0);
}
'Opengles 3.0 with Android' 카테고리의 다른 글
Chapter 6.1 Pattern Effect - Circle (0) | 2025.04.16 |
---|---|
Chapter 6.0 Warble Effect (0) | 2025.04.16 |
Chapter 5.1 Phong Shader (0) | 2025.03.24 |
Chapter 5.0 Vertex lighting (0) | 2025.03.24 |
Chapter 4. OBJ Loader (0) | 2025.03.08 |