본문 바로가기
Opengles 3.0 with Android

Chapter 5.2 Multi Light

by SimonLee 2025. 4. 15.

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