読者です 読者をやめる 読者になる 読者になる

S.F. Page

Programming,Music,etc...

WebGL + GLSLによる8色パレットカラーエミュレート画面がようやく完成 - PCグラフィックスを懐かしむ。楽しむ。(7)

いろいろなサイトを参考にしながらようやく完成した。runをクリックすると、8色の縞模様がスクロールしているように見えるはずだ。

デモページ:

http://github.sfpgmr.net/graphics/devver/20160406/index.html

ソースコード: github.com

このようなデモを昔よく見かけたものだ。というか私が店頭でPCをいじっているときにBASICでよくこんな縞模様を書いて、パレットを変えてアニメーションさせたものである。

これを作るにあたっては以下のサイトを参考にさせていただいた。

jsdo.it

wgld.org

WebGLの初期化コードはほとんどそのまま上記のものを使わせていただいた。おかげでWebGLの初期化方法を学ぶことができた。

この画面は以下の仕様になっている。

  • 320x240ピクセル。
  • ピクセル単位に8色が指定できる。
  • カラーパレットは32ビットカラーのうち8つの色が設定できる。

仕組みとしては、

  • バックバッファとして、512x256ピクセルの2Dテクスチャをgl.LUMINANCEで作る。バックバッファが320x240でないのは、テクスチャは2のべき乗のサイズでないと作れないからである。表示する際にはテクスチャ座標を調節して、バックバッファのうち320x240の部分だけを表示するようにする。gl.LUMINANCEにしているのは、1ピクセルに1バイトを割り当て、パレットインデックスとして使用するためである。
  • カラーパレット用として、8x1ピクセルの2Dテクスチャをgl.RGBAで作る。
  • 表示用のcanvasを作る。実画面サイズによって640x480もしくは320x240に切り替える。
  • 画面一杯に表示する矩形ポリゴンを1枚作る。
  • フラグメントシェーダーでバックバッファのテクスチャを読み出し、その値をインデックスとしてカラーパレット用のテクスチャを読み出し、ピクセルの色とする。
  • 描画時はバックバッファにパレットインデックスを書き込む。それをrequestAnimationFrameの周期で、毎回バックバッファとカラーパレットの情報をテクスチャに転送して、矩形ポリゴンを表示用のcanvasに描画する。

である。シェーダー部分のコードは以下のとおりである。

// パレットエミュレートシェーダー
// バーテックスシェーダー
var vshaderPSrc = 
`precision mediump float;
attribute vec2 position;
attribute vec2 texture_coord;
varying vec2 vtexture_coord;
 
void main(void) {
    gl_Position = vec4(position,0.0,1.0);
    vtexture_coord = texture_coord;
}
`;

// フラグメントシェーダー
var fshaderPSrc = 
`precision mediump float;

uniform sampler2D tex;
uniform sampler2D pallet_color;

varying vec2 vtexture_coord;

void main(void){
 vec4 sampcolor = texture2D(tex, vtexture_coord);
 vec4 color = texture2D(pallet_color,vec2(sampcolor.x * 32.0,0.5));
 gl_FragColor = color;
}
`;

私のコードはほとんどコピペレベルであるけれども、それでもシェーダーコードを書くのは楽しいなと思う。