Quick Flow
지원 샘플 수·형식 확인 → 다중 샘플 색·깊이 첨부 구성
→ 동일 크기·샘플 조건으로 그리기
→ 단일 샘플 FBO로 resolve → 후처리·읽기·표시MSAA는 샘플 저장소를 필요로 합니다. MULTISAMPLE 상태를 켠다고 단일 샘플 이미지를 자동으로 다중 샘플로 바꾸지는 않습니다.
설정과 관계
| 항목 | 선택·기본 조건 | 잘못된 조합 |
|---|---|---|
| GLFW_SAMPLES | 기본 0, 생성 전 요청 | 기존 창에 힌트만 바꿔 적용하려 함 |
| multisample storage | 지원되는 양의 samples | 형식마다 가능한 수를 무시 |
| FBO 첨부 | 샘플 수·고정 샘플 위치 조건 일치 | completeness 실패 |
| GL_MULTISAMPLE | 기본 활성 | 저장소 준비와 혼동 |
| alpha-to-coverage | 기본 비활성 | 일반 알파 합성과 동일시 |
| sample shading | 별도 상위 기능 | 픽셀별 shading과 비용이 다름 |
일반 2D 텍스처 대신 TEXTURE_2D_MULTISAMPLE 또는 다중 샘플 renderbuffer를 사용합니다. 다중 샘플 텍스처에는 일반 min/mag filter·wrap 설정을 적용하지 않습니다. 셰이더에서 직접 샘플을 읽으려면 sampler2DMS와 샘플 인덱스 경로를 사용합니다.
다중 샘플 첨부 준비
GL 3.3에서 생성·바인딩한 msaaFbo에 색과 깊이·스텐실 renderbuffer를 붙입니다. width·height는 양수이고, samples는 두 형식이 지원하는 같은 샘플 수입니다. 새 저장소의 내용은 정의되지 않으므로 그리기 전에 clear합니다.
GLuint colorMs = 0, depthMs = 0;
glGenRenderbuffers(1, &colorMs);
glBindRenderbuffer(GL_RENDERBUFFER, colorMs);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMs);
glGenRenderbuffers(1, &depthMs);
glBindRenderbuffer(GL_RENDERBUFFER, depthMs);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, depthMs);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
// status가 COMPLETE가 아니면 이 FBO에 그리지 않습니다.GL_MAX_SAMPLES는 전체 상한이고 형식별 지원과 같은 값이라고 단정하지 않습니다. glGetRenderbufferParameteriv(..., GL_RENDERBUFFER_SAMPLES, ...)로 각 renderbuffer의 실제 샘플 수를 확인하고 FBO의 샘플 조건을 맞춥니다. GL 4.2 이상에서는 glGetInternalformativ의 NUM_SAMPLE_COUNTS·SAMPLES로 형식별 지원 목록을 조회할 수 있습니다. 실패하면 지원되는 더 낮은 공통 수나 단일 샘플 경로를 선택합니다.
resolve 대상 resolvedFbo는 같은 크기의 단일 샘플 색 텍스처를 FBO 연결 방식으로 붙입니다. 마지막 사용 뒤 두 FBO·색 텍스처·colorMs·depthMs의 소유권을 각각 정리합니다.
Resolve 호출
// GL 3.3 Core: 두 FBO가 COMPLETE이며 동일한 width/height입니다.
glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
GL_COLOR_BUFFER_BIT, GL_NEAREST);소스는 다중 샘플, 대상은 단일 샘플 색 첨부인 예입니다. resolve와 크기 변경을 한 번의 blit로 무조건 합치지 않습니다. 다중 샘플 관련 blit은 사각형 크기·샘플 수·형식 조건을 만족해야 합니다. 깊이·스텐실 blit은 필터와 형식에 더 엄격한 조건이 있으므로 색 resolve 규칙을 그대로 일반화하지 않습니다.
품질과 비용
샘플 수가 늘면 저장·대역폭 비용이 증가합니다. MSAA는 삼각형 경계의 coverage를 주로 개선하며 셰이더 내부의 고주파 무늬나 모든 시간적 떨림을 해결하지는 않습니다. alpha-to-coverage는 잘라내는 표면의 coverage를 다루는 데 활용할 수 있지만 일반 투명도 정렬을 대체하지 않습니다.
버전과 표시 경계
다중 샘플링의 코어 경로는 1.3, FBO 다중 샘플·blit은 3.0, multisample texture는 3.2, sample shading은 4.0 조건을 구분합니다. 기본 창 버퍼는 창 시스템의 샘플 요청·표시 과정과 연결되며 사용자 FBO resolve 코드와 동일한 책임을 애플리케이션에 요구하는 것은 아닙니다.
픽셀 읽기나 후처리에 넘길 때는 소비자가 단일 샘플 이미지를 기대하는지 확인합니다.
참고 링크
4 sources