Computer Graphics 110

OpenGL 정리 - 23. 인스터싱 (Instancing), 안티-앨리어싱(Anti-aliasing)

1. Instancing1.1 Instancing이란?Instancing은 동일한 오브젝트를 여러 번 렌더링해야 할 때 사용되는 최적화 기법이다. 예를 들어, 게임 속에서 풀이나 나무 같은 오브젝트가 수천 개 이상 반복해서 등장하는 경우를 생각해 보자. 각 오브젝트를 따로 드로우 콜을 호출하면 CPU와 GPU 간의 통신이 반복되어 성능이 저하된다.Instancing을 사용하면 한 번의 드로우 콜로 수천 개의 오브젝트를 동시에 그릴 수 있어, CPU와 GPU 간의 통신을 최소화하여 성능을 최적화할 수 있다.1.2 Instancing 구현 흐름과 예제 코드Instancing을 위해 주로 glDrawArraysInstanced() 또는 glDrawElementsInstanced() 함수를 사용하며, 인스턴스 ..

OpenGL 정리 - 22. GPU 데이터 관리 기법, UBO, Geometry Shader

1. OpenGL에서 VBO와 IBO 데이터 관리1.1 VBO 데이터 관리 기법glBufferData(): VBO에 데이터를 설정하는 기본 함수로, 메모리를 할당하고 데이터를 복사한다. nullptr을 인자로 넣으면 메모리 할당만 이루어지고 데이터 복사는 이루어지지 않는다. 이는 필요에 따라 이후 별도의 데이터 전송을 위해 미리 메모리를 할당할 때 유용하다.glBufferSubData(): 일부 데이터만 갱신하고 싶을 때 사용하는 함수로, 기존 메모리의 특정 위치부터 필요한 데이터 크기만큼 복사하여 성능을 최적화할 수 있다. 예를 들어, 매 프레임마다 전체 데이터가 아닌 변경된 부분만 업데이트할 때 사용할 수 있다.glMapBuffer(), glUnmapBuffer(): 데이터 포인터를 통해 버퍼 메모리..

OpenGL 정리 - 21. 큐브 맵 (Cubemap)

1. 큐브 맵 (Cubemap)1.1 큐브 맵이란?큐브 맵(Cubemap)은 6장의 2D 이미지를 하나의 정육면체(큐브) 형태로 붙인 텍스처 맵이다. 각 이미지는 큐브의 한 면을 담당하며, 결과적으로 6개의 면으로 이루어진 입체적인 텍스처가 된다. 이 큐브 맵을 사용하면 3D 장면에서 주변 환경을 감싸는 것처럼 보일 수 있고, 물체가 주변을 반사하는 효과를 자연스럽게 만들 수 있다.1.2 큐브 맵의 특징과 활용큐브 맵은 카메라를 중심으로 3차원 방향 벡터를 사용해 텍스처를 샘플링한다. 예를 들어, 카메라가 (1, 0, 0) 방향을 바라본다면 큐브의 오른쪽 면을 텍스처로 보여주는 식이다.이러한 큐브 맵은 보통 배경을 표현하는 Skybox와 물체의 반사나 굴절을 표현하는 환경 맵핑에 많이 활용된다.2. 큐브..

OpenGL 정리 - 20. 프레임 버퍼 (Frame Buffer)

1. 프레임 버퍼1.1 프레임 버퍼란프레임 버퍼는 OpenGL에서 렌더링된 이미지 데이터를 저장하는 버퍼로, 색상, 깊이, 스텐실 버퍼로 구성된 집합체이다. 일반적으로 OpenGL 컨텍스트를 생성할 때 기본 프레임 버퍼가 자동으로 생성되며, 화면에 그림을 그리기 위해 사용된다. 그러나 개발자가 직접 프레임 버퍼 객체(FBO)를 생성하여 렌더링 결과를 텍스처로 활용하거나, 포스트 프로세싱을 적용할 수도 있다.1.2 프레임 버퍼 목적프레임 버퍼는 다음과 같은 경우에 유용하게 사용된다:렌더링된 장면을 텍스처로 활용: 텍스처 매핑, 쉐도우 맵핑, 반사 효과 등.포스트 프로세싱: 렌더링 후 추가적인 효과(예: 블러, 감마 보정, 색상 반전 등)를 적용.2. 프레임 버퍼 사용 과정2.1 프레임 버퍼 생성 및 설정프..

OpenGL 정리 - 19. 스텐실(Stencil), 블랜딩(Blending), 컬링(Face Culling)

1. 스텐실(Stencil)1.1 스텐실 버퍼란?스텐실 버퍼는 컬러 및 깊이(depth) 버퍼 외에 특정 픽셀에만 그리기를 제한할 수 있는 8비트 정수형 버퍼이다. 이를 통해 렌더링할 영역을 선택적으로 제어할 수 있다.1.2 스텐실 테스트스텐실 테스트는 깊이 테스트 이전에 수행되며, 스텐실 버퍼에 저장된 값과 설정된 조건에 따라 해당 픽셀을 그릴지 여부를 결정한다. 다양한 연산을 지원하며, 아래와 같은 함수로 설정할 수 있다.활성화/비활성화: glEnable(GL_STENCIL_TEST); / glDisable(GL_STENCIL_TEST);스텐실 테스트 함수 설정: glStencilFunc(GL_EQUAL, 1, 0xFF); (비교 연산을 설정)스텐실 버퍼 업데이트 설정: glStencilOp(GL_K..

OpenGL 정리 - 18. Depth Buffer, 깊이값 왜곡, Z-fighting

Depth Testing1. Depth Buffer란?깊이 버퍼(Depth Buffer)는 렌더링 시 각 픽셀의 깊이값을 저장하는 버퍼로, 이를 통해 객체의 앞뒤 관계를 결정한다. 픽셀이 그려질 때마다 현재 그리려는 픽셀의 깊이값과 깊이 버퍼에 저장된 값이 비교되어, 조건에 맞으면 그리기를 수행하고 그렇지 않으면 무시한다.2. Depth Testing 사용하기깊이 테스트를 활성화하고 비활성화하는 방법은 다음과 같다.깊이 테스트 활성화: glEnable(GL_DEPTH_TEST);깊이 테스트 비활성화: glDisable(GL_DEPTH_TEST);깊이 테스트를 활성화하지 않으면, 객체가 그려진 순서대로 마지막 객체가 앞에 나타나며, 이전 객체는 덮어쓰여지게 된다.3. Depth Buffer 조작깊이 버퍼는..

HumanGL - 7. ImGui 추가

이번에는 ImGui를 이용해 사람 모델의 각 파츠를 실시간으로 조정할 수 있는 인터페이스를 추가했다. 이제 각 파츠의 계층적 구조를 더 직관적으로 확인할 수 있게 되었고, 다양한 조정이 가능해졌다. ImGui 추가하기렌더링 함수에 ImGui를 추가하면서, 사람 모델의 각 파츠의 변형 값을 실시간으로 조정할 수 있도록 했다. Context::Render() 함수에서 ImGui 위젯을 사용해 각 파츠의 스케일, 색상, 회전 등을 다룰 수 있는 슬라이더와 버튼을 배치했다.void Context::Render() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // ImGui 인터페이스 추가 if ..

HumanGL - 6. Animation 적용

이제 사람 모델에 애니메이션 기능을 적용했다. 각 파트의 움직임에 맞춰 회전 축(피벗)을 설정하고, 애니메이션 동작을 적용한 것이 주요 변경 사항이다.피벗 설정 및 Transform 계산 변경사람의 몸을 그리는 과정에서 파츠마다 회전할 때 피벗 위치가 달라야 했다. 그래서 각 파트에 맞는 회전 중심을 계산해 적용했다.DrawNode 함수 변경void Human::DrawNode(const Node& node, const Mesh* mesh, const Program* program, const sglm::mat4& transform) { sglm::vec3 rotationPivot; if (node.part->name == "body") { rotationPivot = sglm::..

HumanGL - 5. transform 행렬 계산식 변경

전에 발견한 문제를 해결하기 위해 transform 행렬 계산식을 수정했다. 이전 방식에서는 스케일이 translate에 영향을 주어 직관적이지 않았고, 이를 독립적으로 계산하려 했던 것이 문제의 원인이었다.문제 원인 분석기존에는 transform 계산식을 다음과 같이 적용했다:transform = projection * view * modelmodel = translate * rotate * scale그런데 상속을 받을 때, 스케일을 translate과 독립적으로 적용하려다 보니 다음과 같은 방식으로 계산했다:model = 부모 translate * 자식 translate * 부모 rotate * 자식 rotate * 부모 scale * 자식 scale이 방식으로는 부모와 자식의 좌표계가 서로 독립적으..

HumanGL - 4. 문제 발견

사람을 그리고 테스트하자마자 문제가 발생했다. static float scale = 1.0f;static float dir = 0.01f;scale += dir;if (scale >= 2.0f) dir = -0.01f;if (scale 렌더링될 때마다 스케일을 변하게 해줬는데, 영상에서 볼 수 있듯이 각각의 오브젝트가 동시에 커졌다. 자세히 살펴보면 위치는 고정된 상태로 크기만 변하는 걸 확인할 수 있다.이 현상이 꽤 이상해서 돌려봤는데...sglm::mat4 rotateModel = sglm::mat4(1.0f);static float angle = 0.0f;angle += 1.0f;if (angle >= 360.0f) angle = 0.0f;rotateModel = sglm::rotate(..