2017-12-24 15 views
1

私は古いOpenGL 1.2ビットマップフォントレンダリングコードを最新のOpenGL(少なくともOpenGL 3.2以上)に移植しています.GLSLシェーダを使用して手動で行っていたことを達成できるかどうかは疑問です。OpenGLシェーダは、最も近いスケーリングとリニアスケーリングを組み合わせて使用​​できますか?

特定のサイズにスケールされた文字列 "123"を描画したい場合は、以下のスプライトで以下の手順を実行します。

enter image description here

  1. 私は画面にスプライトを描画し、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、Y + 0、COLOR(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最近傍アップスケーリングとその後の線形サンプリング"の効果を達成することができます。次に、双一次補間を手動で実装する必要があります。 OpenGL 4+をターゲットにしていた場合はを念頭に置きながら、textureGather()が便利です。私の提案する解決策では、textureGather()ではなく、のように4 texelFetch()コールを使用しています。かなり複雑になります。

すでに存在するグリフの周りに黒い枠線を持つスケーリングされていないテクスチャがあるとします。

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 = ...の座標持っていると仮定しましょう
関連する問題