OpenGLES3.0_Example/Chapter_2/app/src/main/cpp/Scene/ManyCubes.cpp at main · dlgmlals3/OpenGLES3.0_Example
Contribute to dlgmlals3/OpenGLES3.0_Example development by creating an account on GitHub.
github.com
Culling()
컬링이라는 말은 잘라낸다는 의미이다.
우리가 볼수 없는 면의 대해서 렌더링할 필요없는 부분까지 전부 렌더링을 하게 되면 성능저하가 발생될 것이다.
컬링을 말하면 z(뎁스) 테스트라는 말이 자주 나온다.
컬링을 진행하는 단계는 파이프라인 거의 마지막 단계인 z ordering 후에 진행된다.
물체가 겹쳐있을때를 생각해보면, 선택된 픽셀이 카메라 기준으로 해당 픽셀 앞에 있는지 뒤에있는지를 알아야
해당 픽셀을 컬링할것인지 결정할 수 있기 때문이다.
컬링 관련 함수는 다음과 같다.
디폴트 값은 z값이 가까운 것만 업데이트하고, 뒷면을 컬링한다.
- glClearDepth : 1
- glDepthFunc : GL_LESS
- glCullFace : GL_BACK
if (toogle) {
LOGI("FRONT Face");
glClearDepthf(0.0f);
glClear(GL_DEPTH_BUFFER_BIT);
glDepthFunc(GL_GREATER);
glCullFace(GL_FRONT);
}
else {
LOGI("BACK Face");
glClearDepthf(1.0f);
glClear(GL_DEPTH_BUFFER_BIT);
glDepthFunc(GL_LESS);
glCullFace(GL_BACK);
}
glCullFace 인자값의 대해서 살펴보자.
GL_FRONT 는 카메라 기준으로 삼각형이 앞면인 경우만 컬링을 하게 되어 뒷면만 보이고,
GL_BACK의 경우 뒷면만 컬링을 하게 되어 삼각형 앞면만 보이게 된다.
glDepthFunc 인자 값의 대해서 살펴보자.
GL_GREATER 경우, 현재 값보다 z값이 큰 경우만 z buffer에 업데이트 하고
GL_LESS 경우, 현재 z 값 보다 작은 경우만 z buffer 에 업데이트 한다.
🔍 glDepthFunc() 값에 따른 Z 버퍼 변화
GL_NEVER | false (항상 실패) | ❌ 그리지 않음 | ❌ 업데이트 안 됨 |
GL_LESS (기본값) | New Z < Old Z (더 가까우면) | ✅ 그리기 | ✅ 업데이트됨 |
GL_EQUAL | New Z == Old Z | ✅ 같을 때만 그리기 | ✅ 업데이트됨 |
GL_LEQUAL | New Z ≤ Old Z | ✅ 같거나 가까우면 그리기 | ✅ 업데이트됨 |
GL_GREATER | New Z > Old Z (더 멀면) | ✅ 더 멀면 그리기 | ✅ 업데이트됨 |
GL_NOTEQUAL | New Z ≠ Old Z | ✅ 다르면 그리기 | ✅ 업데이트됨 |
GL_GEQUAL | New Z ≥ Old Z | ✅ 같거나 더 멀면 그리기 | ✅ 업데이트됨 |
GL_ALWAYS | true (항상 성공) | ✅ 무조건 그리기 | ✅ 항상 업데이트 |
주의 할점은
z buffer 초기 뎁스값은 1.0 이기 때문에,
GL_GREATER를 사용하여 뒷면만 그리고 싶은 경우는 glClearDepth 사용하여 z 버퍼 값은 1로 초기화 해주어야 한다.
======================================================================
참고 ) FBO 환경에서 뎁스 버퍼를 사용하는 방법
쉐이더에서 깊이값 샘플링 가능 | (depthTexture 사용) ✅ 가능 |
( RenderBuffer 사용) ❌ 불가능 |
렌더링 성능 | ❌ 약간 느림 (텍스처 저장 비용) | ✅ 빠름 (최적화된 버퍼) |
Z 버퍼 테스트 가능 | ✅ 가능 | ✅ 가능 |
그림자 맵핑(Shadow Mapping) 사용 가능 | ✅ 가능 | ❌ 불가능 |
메모리 사용량 | 🔼 높음 (텍스처 저장 필요) | 🔽 낮음 (렌더버퍼 최적화) |
컬러 렌더링과 함께 사용 가능 | ✅ 가능 | ✅ 가능 |
깊이값을 CPU에서 glReadPixels()로 읽기 | ❌ 불가능 (GL_DEPTH_COMPONENT 텍스처는 읽기 불가) | ✅ 가능 |
사용 예시 | 그림자 맵핑, 후처리 효과 (Post-processing) | 일반적인 3D 렌더링 |
1. 깊이 테스트 사용하는 방법
// 1️⃣ FBO 생성
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// 2️⃣ 깊이 텍스처 생성
GLuint depthTexture;
glGenTextures(1, &depthTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// 3️⃣ 깊이 텍스처를 FBO의 깊이 버퍼로 연결
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
// 4️⃣ 컬러 버퍼가 필요 없을 경우 (깊이 전용 FBO)
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
// 5️⃣ FBO 상태 확인
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
printf("FBO 설정 실패!\n");
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); // FBO 바인딩 해제
2. 렌더 버퍼 사용하는 방법
// 1️⃣ FBO 생성
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// 2️⃣ 컬러 텍스처 생성 (일반적인 렌더링 용도)
GLuint colorTexture;
glGenTextures(1, &colorTexture);
glBindTexture(GL_TEXTURE_2D, colorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
// 3️⃣ 깊이 렌더버퍼 생성
GLuint depthRenderbuffer;
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
// 4️⃣ 렌더버퍼를 FBO에 연결
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
// 5️⃣ FBO 상태 확인
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
printf("FBO 설정 실패!\n");
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); // FBO 바인딩 해제
'Opengles 3.0 with Android' 카테고리의 다른 글
Chapter 2.5 VAO ? VBO ? ( 참고 ) (1) | 2025.02.22 |
---|---|
Chapter 2.1 Shader Build (0) | 2025.02.22 |
Chapter 2.3 Transform and Projection (0) | 2025.02.21 |
Chapter 2.6 Touch Event ( Skip ) (1) | 2025.02.21 |
Chapter 2.2 VBO, EBO, VAO (0) | 2025.02.21 |