2017-12-24 21 views
1

일부 오래된 OpenGL 1.2 비트 맵 글꼴 렌더링 코드를 최신 OpenGL (최소 OpenGL 3.2 이상)로 포팅하고 있습니다. GLSL 셰이더를 사용하여 수동으로 수행 한 작업을 수행 할 수 있는지 궁금합니다.OpenGL 쉐이더는 가장 가까운 스케일링과 선형 스케일링을 혼합 할 수 있습니까?

문자열 "123"을 특정 크기로 축소하여 그려야 할 때 아래의 스프라이트를 사용하여 다음 단계를 수행합니다.

  1. enter image description here

    내가 화면에 스프라이트를 그릴, GL_NEAREST로 2 배 확장. 그러나 검은 윤곽선을 얻으려면 실제로 스프라이트를 여러 번 그립니다.

    1. X + 1, Y + 0, BLACK
    2. X + 0, Y + 1, BLACK
    3. X - 1, Y + 0, BLACK
    4. X + 0, Y - 1 스프라이트 한 후 BLACK
    5. X + 0 + 0 (Y), 색상 (RED)

    enter image description here

  2. 화면에 그려지면 glCopyTexSubImage2D를 통해 화면을 텍스처로 복사합니다.

  3. 그 텍스처를 다시 화면에 그으나 GL_LINEAR로 그립니다.

최종 결과는보다 시각적으로 매력적인 픽셀 스프라이트 크기 조정 방법입니다. GL_NEAREST (오른쪽 아래) 또는 GL_LINEAR (왼쪽 아래)를 사용하여 작은 픽셀 스프라이트를 임의의 크기로 업 스케일링하면 좋지 않은 효과가 있습니다. GL_NEAREST를 사용하여 픽셀을 두배로 늘린 다음 GL_LINEAR을 사용하여 나머지 크기를 조정하면 내가 선호하는 결과를 얻을 수 있습니다 (맨 위).

enter image description here

내가 GLSL이 검은 윤곽을 할 수있는 확신 (따라서 그립니다 많이 할 필요에서 저를 저장)뿐만 아니라 GL_NEAREST와 GL_LINEAR 스케일링의 조합을 할 수 있습니까?

답변

1

현실감있는 텍스처에서 4 텍셀 이웃을 샘플링하는 동안 "2x nearest-neighbor upscaling 및 선형 샘플링"효과를 얻을 수 있습니다. 그런 다음 수동으로 쌍 선형 보간을 구현해야합니다. OpenGL 4+를 타겟팅하는 경우 this issue을 염두에두고 textureGather()이 유용 할 것입니다. 아래 제안 된 솔루션에서 textureGather()이 아닌 4 texelFetch() 호출을 사용합니다. textureGather()은 상당히 복잡합니다.

이미 존재하는 글리프 주위에 검정 테두리가있는 비 눈금 텍스처가 있다고 가정합니다.

ivec2 origTexSize = textureSize(sampler, 0); 
int upscaleFactor = 2; 

// Floating point texel coordinate into the upscaled texture. 
vec2 ptu = pn * vec2(origTexSize * upscaleFactor); 

// Decompose "ptu - 0.5" into the integer and fractional parts. 
vec2 ptuf; 
vec2 ptui = modf(ptu - 0.5, ptuf); 

// Integer texel coordinates into the upscaled texture. 
ivec2 ptu00 = ivec2(ptui); 
ivec2 ptu01 = ptu00 + ivec2(0, 1); 
ivec2 ptu10 = ptu00 + ivec2(1, 0); 
ivec2 ptu11 = ptu00 + ivec2(1, 1); 

// Integer texel coordinates into the original texture. 
ivec2 pt00 = clamp(ptu00/upscaleFactor, ivec2(0), origTexSize - 1); 
ivec2 pt01 = clamp(ptu01/upscaleFactor, ivec2(0), origTexSize - 1); 
ivec2 pt10 = clamp(ptu10/upscaleFactor, ivec2(0), origTexSize - 1); 
ivec2 pt11 = clamp(ptu11/upscaleFactor, ivec2(0), origTexSize - 1); 

// Sampled colours. 
vec4 clr00 = texelFetch(sampler, pt00, 0); 
vec4 clr01 = texelFetch(sampler, pt01, 0); 
vec4 clr10 = texelFetch(sampler, pt10, 0); 
vec4 clr11 = texelFetch(sampler, pt11, 0); 

// Bilinear interpolation. 
vec4 clr0x = mix(clr00, clr01, ptuf.y); 
vec4 clr1x = mix(clr10, clr11, ptuf.y); 
vec4 clrFinal = mix(clr0x, clr1x, ptuf.x); 
:의 당신은 내가 그것을 테스트하지 않았습니다하지만 표준화 된 텍스처, 다음 코드는 원하는 효과를 달성한다 0과 1 사이 pn.xpn.y 그 질감에 vec2 pn = ...의 좌표가 있다고 가정하자