スポンサーリンク

GLSLを試す (4) グレイスケールテクスチャを着色する

グレイスケールデータの定義

グレイスケール(1画素が輝度値で表現されている)データをテクスチャとして使用することを考える。RGB(A)に変換しないでできれば何かと便利になる。

グレイスケールデータの定義

typedef GLshort gray_t;
const int P_COUNT = 4;
gray_t texdata[P_COUNT];

//テクスチャ(画像)作成
// 2*2のグレイスケール画像
texdata[0] = 255;
texdata[1] = 128;
texdata[2] = 50;
texdata[3] = 0;

GL_R8UI等を使う

GL_LUMINANCEなどを指定すればよいのだが、これは最近では非推奨らしい。

代わりに、GL_R8I,GL_R8UI,GL_R16I,GL_R16UI,GL_R32I,GL_R32UI等を使えば、RGBではなくグレイスケールとしてテクスチャを転送できる。

例1 テクスチャがunsigned charの場合

glTexImage2D(
  GL_TEXTURE_2D,
  0,
  GL_R8UI,          //8bitのunsinged int
  TEXWIDTH,     //テクスチャ画素数
  TEXHEIGHT,    //テクスチャ画素数
  0,
  GL_RED_INTEGER,   //整数
  GL_UNSIGNED_BYTE, //unsigned の 1byte
texdata
);

例2 テクスチャがsigned shortの場合

glTexImage2D(
  GL_TEXTURE_2D,
  0,
  GL_R16I,           //16bitのsigned int
  TEXWIDTH,    //テクスチャ画素数
  TEXHEIGHT,   //テクスチャ画素数
  0,
  GL_RED_INTEGER,    //整数
  GL_SHORT,          //signed の 2byte
  texdata
);

フラグメントシェーダ

sampler2Dを使うと、データ範囲が0.0~1.0の間で正規化されて取得できる。それでいい時も多いと思うのだが、グレースケールデータの値を正確に参照したい場合は不便というか、元の値を正確に得られる保証がない。そこでisampler2Dを使うと、テクスチャのデータをもとのままで参照できる。

#version 460 core

out vec4 FragColor; //色の出力はfloatでいい

uniform isampler2D uTex; //データをint型で受け取る。符号なしintのときはusampler2D
  
in vec2 vTexCoord; //テクスチャ座標

void main()
{
  int c = texture(uTex,vTexCoord).x;

  //分岐はどうのとか今はいい。本題ではない。
  if( c == 255)
      FragColor =vec4( 1.0,0,0,1);
  else if( c == 128)
      FragColor =vec4( 0.0,1.0,0,1);
  else if( c == 50)
      FragColor =vec4( 0.0,0.0,1.0,1);
  else
      FragColor =vec4( float(c)/255.0,float(c)/255.0,float(c)/255.0,1.0);
}
unsigned byteをそのまま輝度として表示
(上記 例1)
unsinged byteに着色して表示
(上記 例1+上記フラグメントシェーダ)

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: