파이썬으로 3D 그래픽스를 위한 라이팅 및 셰이딩 기법 개발

3D 그래픽스는 현실과 유사한 시각적 효과를 만들어내기 위해 라이팅 및 셰이딩 기법을 사용합니다. 파이썬은 다양한 라이브러리와 도구를 제공하여 3D 그래픽스 개발에 매우 유용합니다. 이번 블로그 포스트에서는 파이썬을 사용하여 3D 그래픽스를 위한 라이팅 및 셰이딩 기법을 개발하는 방법에 대해 알아보겠습니다.

1. 라이팅 기법

라이팅은 조명을 이용하여 3D 객체에 입체감을 부여하는 기법을 말합니다. 파이썬에서는 다양한 라이브러리를 사용하여 조명 효과를 시뮬레이션 할 수 있습니다. 예를 들어, PyOpenGL, Pygame, 또는 ModernGL과 같은 라이브러리를 사용하여 라이트 소스를 생성하고 조명 효과를 적용할 수 있습니다.

import ModernGL
import numpy as np

ctx = ModernGL.create_standalone_context()
prog = ctx.program(
    vertex_shader='''
        #version 330
        uniform vec3 light_pos;
        in vec3 in_vert;
        in vec3 in_norm;
        out vec3 out_norm;
        void main() {
            gl_Position = vec4(in_vert, 1.0);
            out_norm = in_norm;
        }
    ''',
    fragment_shader='''
        #version 330
        uniform vec3 light_color;
        in vec3 out_norm;
        out vec4 fragColor;
        void main() {
            vec3 norm = normalize(out_norm);
            vec3 light_dir = normalize(light_pos);
            
            float diffuse = max(dot(norm, light_dir), 0.0);
            fragColor = vec4(light_color * diffuse, 1.0);
        }
    '''
)

prog.uniforms['light_pos'].value = (1.0, 1.0, 1.0)
prog.uniforms['light_color'].value = (1.0, 1.0, 1.0)

vertices = np.array([
    -1.0, -1.0, 0.0,
    1.0, -1.0, 0.0,
    0.0, 1.0, 0.0
], dtype=np.float32)

normals = np.array([
    0.0, 0.0, 1.0,
    0.0, 0.0, 1.0,
    0.0, 0.0, 1.0
], dtype=np.float32)

vbo = ctx.buffer(vertices)
vao = ctx.simple_vertex_array(prog, vbo, 'in_vert', 'in_norm')

vao.render(ModernGL.TRIANGLES)

위의 코드는 ModernGL 라이브러리를 사용하여 라이팅 효과를 구현하는 예시입니다. vertex_shader에서는 정점 위치와 법선 벡터를 받아오고, fragment_shader에서는 법선 벡터와 조명의 위치를 이용하여 빛의 강도를 계산합니다. 마지막으로, vao.render() 함수를 호출하여 3D 객체를 렌더링합니다.

2. 셰이딩 기법

셰이딩은 객체의 표면을 다양한 재질과 효과로 표현하기 위한 기법을 말합니다. 파이썬에서는 셰이딩을 위해 다양한 라이브러리와 도구를 사용할 수 있습니다. 예를 들어, GLSL(OpenGL Shading Language)을 사용하여 셰이더를 작성하고, ModernGL 라이브러리를 사용하여 파이썬 코드와 통합할 수 있습니다.

import ModernGL
import numpy as np

ctx = ModernGL.create_standalone_context()
prog = ctx.program(
    vertex_shader='''
        #version 330
        in vec3 in_vert;
        in vec3 in_norm;
        out vec3 out_norm;
        uniform mat4 proj;
        uniform mat4 view;
        uniform mat4 model;
        void main() {
            gl_Position = proj * view * model * vec4(in_vert, 1.0);
            out_norm = in_norm;
        }
    ''',
    fragment_shader='''
        #version 330
        in vec3 out_norm;
        out vec4 fragColor;
        void main() {
            vec3 norm = normalize(out_norm);
            fragColor = vec4(norm, 1.0);
        }
    '''
)

proj = np.eye(4)
view = np.eye(4)
model = np.eye(4)

prog.uniforms['proj'].write(proj)
prog.uniforms['view'].write(view)
prog.uniforms['model'].write(model)

vertices = np.array([
    -1.0, -1.0, 0.0,
    1.0, -1.0, 0.0,
    0.0, 1.0, 0.0
], dtype=np.float32)

normals = np.array([
    0.0, 0.0, 1.0,
    0.0, 0.0, 1.0,
    0.0, 0.0, 1.0
], dtype=np.float32)

vbo = ctx.buffer(vertices)
vao = ctx.simple_vertex_array(prog, vbo, 'in_vert', 'in_norm')

vao.render(ModernGL.TRIANGLES)

위의 코드는 ModernGL 라이브러리를 사용하여 셰이딩 효과를 구현하는 예시입니다. vertex_shader에서는 정점 위치와 법선 벡터를 받아오고, fragment_shader에서는 법선 벡터를 이용하여 픽셀의 색상을 계산합니다. proj, view, model 행렬을 이용하여 객체의 위치, 회전, 크기를 조절할 수 있습니다.

결론

파이썬을 사용하여 3D 그래픽스를 위한 라이팅 및 셰이딩 기법을 개발하는 방법에 대해 알아보았습니다. 파이썬의 다양한 라이브러리와 도구를 활용하면 더욱 다양한 그래픽스 효과를 구현할 수 있습니다. 추가적으로 PyOpenGL, Pygame, ModernGL 외에도 다른 라이브러리를 사용하여 더욱 다양한 3D 그래픽스 개발을 시도해 보세요.


참고 자료: