2017-03-18 18 views
1

나는 약간의 gamedev 라이브러리를 개발 중이다. 이 라이브러리의 요소 중 하나는 OpenGL 프레임 버퍼를 통해 구현되는 캔버스 (오프 스크린 드로잉 영역)입니다. 지금까지 모든 것이 잘되고, 텍스처를 생성하고, 프레임 버퍼에 첨부하고, 렌더링 한 다음 프레임 버퍼의 텍스처를 Texture2D로 사용합니다.OpenGL - 멀티 샘플 프레임 버퍼로 그리는 방법과 결과를 일반 텍스처로 사용하는 방법?

이제 라이브러리에 앤티 엘리 어싱을 추가하고 싶습니다. Canvas에서 멀티 샘플링을 설정할 수 있기를 바랍니다. 이제는 멀티 샘플 텍스처를 사용하도록 쉐이더를 변경해야한다는 것을 알았 기 때문에 혼란 스럽습니다.

그렇다면 프레임 버퍼의 멀티 샘플링을 활성화하여 나머지 라이브러리 코드 변경을 최소화하려면 어떻게해야합니까? 가능하다면 렌더링 결과를 일반 Texture2D로 사용하고 싶습니다.

답변

2

그냥 혼란이 없는지 확인하십시오. x 배 더 큰 텍스처를 생성 한 다음 필터가 마법을 수행하기를 바랄 수는 없습니다. GL_LINEARaverages the four texels closest to the center of the pixel being textured 만.

멀티 샘플 텍스처를 만들려면 glTexImage2DMultisample() (3.2부터 코어에서 사용 가능)을 사용하십시오. 이런 식으로 세웠 잖아.

glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex); 
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, width, height, false); 

는 단정 samples는 멀티 텍스처 샘플 량 것으로해야한다. 또한 internalformat을 변경하십시오.

텍스처를 프레임 버퍼에 첨부하려면 똑같이 glFramebufferTexture2D()을 사용하십시오. 그러나 textargetGL_TEXTURE_2D으로 설정하는 대신 GL_TEXTURE_2D_MULTISAMPLE으로 설정하십시오.

glBindFramebuffer(GL_FRAMEBUFFER, fbo); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0); 

프레임 버퍼의 상태를 확인하십시오.

셰이더에서 멀티 샘플 텍스처에 액세스하려면 sampler2DMS을 사용해야합니다. 그러나 멀티 샘플 텍스처는 일반 텍스처와 아주 다르게 작동합니다. 텍스처에서 읽으려면 texelFetch()을 사용해야합니다.

따라서 멀티 샘플 텍스처에서 샘플링하려면 texture()을 사용할 수 없지만 texelFetch()과 같은 것을 사용해야합니다. 정규화 된 좌표를 고려하지 않습니다

uniform int texSamples; 
uniform sampler2DMS tex; 

vec4 textureMultisample(sampler2DMS sampler, ivec2 coord) 
{ 
    vec4 color = vec4(0.0); 

    for (int i = 0; i < texSamples; i++) 
     color += texelFetch(sampler, coord, i); 

    color /= float(texSamples); 

    return color; 
} 

texelFetch(), 당신은 같은과 함께이 문제를 회피 할 수 있습니다 : 당신이 선명 앤티 앨리어싱 결과를 표시하려는 경우 하루의 끝에서

vec2 uv = vec2(0.5, 0.5); // normalized coordinates 
ivec2 texSize = textureSize(tex, 0); 
ivec2 texCoord = ivec2(uv * texSize); 
vec4 color = textureMultisample(tex, texCoord); 

, 당신 그것을 화면에 블리치해야합니다. 당신은 멀티 깊이 버퍼가 필요한 경우

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); 
glDrawBuffer(GL_BACK); 
glBlitFramebuffer(0, 0, src_width, src_height, 0, 0, dst_width, dst_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); 

다음 glRenderbufferStorageMultisample()로 본다.

glEnable(GL_MULTISAMPLE)도 확인하십시오. 그러나 오늘날 대부분의 드라이버는 기본적으로이 드라이버를 활성화합니다.

재미있는 멀티 샘플링과 관련된 몇 가지 다른 Stack Overflow/Exchange 질문이 있습니다. 정교한 답변

+0

감사합니다! 그래서, 만약 내가 올바르게 이해한다면, 멀티 샘플링 된 텍스쳐를 그려서 그 결과를 일반적인 텍스쳐로 사용하고 싶다면 먼저 멀티 샘플링 된 텍스쳐 (프레임 버퍼)를 비 멀티 샘플링 된 것으로 블릿해야합니다. 아니면 그 주위에 방법이 있습니까? – faiface

+0

'sampler2DMS'와'texelFetch()'/'textureMultisample()'으로 살 수 있다면 쉐이더에서 일반적인 텍스쳐처럼 사용할 수 있습니다. 하지만 멀티 샘플 텍스처를 일반 샘플 텍스처로 변환하려면 2 프레임 버퍼 사이에 블릿해야합니다. – Vallentin

+0

왜 [여기] (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/texture.xhtml)에서 gsampler2DMS에 대해 texture()가 지원된다고 설명 할 수 있습니까? 문서 오류? – Bim