2

フラグメントシェーダーを使用してパレットスワップを実現する方法を整理しようとしています(この投稿を見てhttps://gamedev.stackexchange.com/questions/43294/creating-a-retro-style-palette-swapping-effect-in -opengl ) 私は gl を開くのが初めてなので、誰かが私の問題を説明してくれたらうれしいです。

再現しようとしているコードスニペットは次のとおりです。

http://www.opengl.org/wiki/Common_Mistakes#Paletted_textures

ウィンドウを作成し、テクスチャ、シェーダーをロードし、ウィンドウのコーナーにマップされた単一の正方形をレンダリングできるように、Open GL 環境をセットアップしました (ウィンドウのサイズを変更すると、イメージも引き伸ばされます)。

頂点シェーダーを使用して座標をスクリーン空間からテクスチャ空間に変換しているため、テクスチャも引き伸ばされます

attribute vec2 position;

varying vec2 texcoord;

void main()
{
        gl_Position = vec4(position, 0.0, 1.0);
        texcoord = position * vec2(0.5) + vec2(0.5);
}

フラグメントシェーダーは

uniform float fade_factor;
uniform sampler2D textures[2];

varying vec2 texcoord;

void main()
{
    vec4 index = texture2D(textures[0], texcoord);
    vec4 texel = texture2D(textures[1], index.xy);
    gl_FragColor = texel;
}

textures[0]インデックス付きのテクスチャです(色付けしようとしているもの)

インデックス付きテクスチャ

すべてのピクセルのカラー値は (0, 0, 0, 255)、(1, 0, 0, 255)、(2, 0, 0, 255) ... (8, 0, 0, 255) - 8 色全体的に、それがほとんど黒に見える理由です。「赤チャンネル」に保存されている値を使用して色をエンコードしたいと思います。

textures[1]色の表です (9x1 ピクセル、各ピクセルには固有の色があり、投稿用に 90x10 にズームされています)

ここに画像の説明を入力

フラグメント シェーダーの抜粋からわかるように、たとえば (5, 0, 0, 255) などの最初のテクスチャからインデックス値を読み取り、ポイント (x=5, y= 0) 2 番目のテクスチャ。ウィキに書いてある通り。

しかし、ペイントされた画像の代わりに、次のようになります。

結果

実際、vec2(1, 0)、vec2(2, 0)、vec2(4, 0)、vec2(8, 0) のように X ポイントを明示的に設定すると、2 番目のテクスチャからピクセルにアクセスできないことがわかります。しかし、vec2(0.1, 0) または vec2(0.7, 0) を使用すると、色を取得できます。これは、テクスチャ スペースが 9x1 ピクセルから (0,0)->(1,1) に正規化されているためだと思います。しかし、どうすればその機能を「無効」にして、単にパレット テクスチャをロードして、「(x,y) に格納されているピクセルのカラー値を教えてください」と尋ねることができるのでしょうか?

4

1 に答える 1

2

各ピクセルのカラー値は (0, 0, 0, 255)、(1, 0, 0, 255)、(2, 0, 0, 255) ... (8, 0, 0, 255)

違う。すべてのピクセルには、(0, 0, 0, 1)、(0.00392, 0, 0, 1)、(0.00784, 0, 0, 1) ... (0.0313, 0, 0, 1) のカラー値があります。

整数テクスチャまたは浮動小数点テクスチャを使用していない限り (そうでない場合)、色は正規化された浮動小数点値として保存されます。したがって、シェーダーからフェッチすると、「255」と思われるものは実際には「1.0」になります。

これを処理する正しい方法は、最初に正規化された値を正規化されていない形式に戻すことです。これは、値に 255 を掛けることによって行われます。次に、パレット テクスチャの幅 (- 1) で割ることによって、それらをテクスチャ座標に変換します。また、パレット テクスチャは 2D であってはなりません。

#version 330 //Always include a version.

uniform float fade_factor;
uniform sampler2D palattedTexture;
uniform sampler1D palette;

in vec2 texcoord;

layout(location = 0) out vec4 outColor;

void main()
{
    float paletteIndex = texture(palattedTexture, texcoord).r * 255.0;
    outColor = texture(palette, paletteIndex / (textureSize(palette).x - 1));
    gl_FragColor = texel;
}

上記のコードは GLSL 3.30 用に書かれています。以前のバージョンを使用している場合は、それに応じて翻訳してください。

また、パレット テクスチャに RGBA テクスチャを使用しないでください。1 チャンネルなので、GL_LUMINANCEまたはを使用してGL_R8ください。

于 2013-01-29T01:25:27.770 に答える