LoginSignup
2
2

【GLSL】bit演算お絵描き

Last updated at Posted at 2024-02-13

概要

GLSLのuintは、bit列を2進数表示した数値で表されます。これを利用して、16進数で指定した値でお絵描きをします。

なお、GLSLのビット演算はES 3.0以降で利用できます。

https://nemutas.github.io/webgl-sketch/20240208/
63f16fd4-1454-451e-836c-a9b06fcbe3a6.gif

進数計算

10進数,16進数,2進数は、それぞれ下表で対応付けされます。
スクリーンショット 2024-02-13 204959.png
一般に、n進数を10進数に直す場合、数をnのべき乗の和に直すことによって表現されます。
例えば、2進数から10進数の場合、

1101_2 = 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 8 + 4 + 0 + 1 = 13

となり、16進数では対応表により、Dとなります。

👾

space invader👾を描画する場合。

スクリーンショット 2024-02-13 205719.png

例えば、下列の4bitでは、
■☐☐☐
であるので、

1000_2 = 1 * 2^3 + 0 * 2^2 + 0 * 2^1 + 0 * 2^0 = 8 + 0 + 0 + 0 = 8_{10} = 8_{16}

となります。
次の4bitは、
■■☐■
なので、

1101_2 = 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 8 + 4 + 0 + 1 = 13_{10} = D_{16}

となります。
この調子で計算すると、下列は16進数で、

0x0d8u

となり、全体のbitmapは次のようになります。

uint[8] rows = uint[](
    0x0d8u,
    0x505u,
    0x5fdu,
    0x7ffu,
    0x376u,
    0x1fcu,
    0x088u,
    0x104u
);

表示

vec2 iuv = floor(uv * 32.0);

uint[8] rows = uint[](
    ...
);

if (int(iuv.y) < rows.length()) {
    uint b = rows[int(iuv.y)];
    b = (b << uint(iuv.x)) >> 31;
    float c = float(b);
}

uintは32bitの2進数bit列なので、uvを32倍してfloor()をとることで、0~31の整数に変換します。
iuv.yで対象のbit列bを取得して、iuv.x分を左シフトします。
その後に、31bit分右シフトすると対象のセルに対するbit値を取得できます。

例えば、0x0d8uの場合、bit列は、

0000 0000 0000 0000 0000 0000 1101 1000

なので、8bit目の1を取得する場合、

b = 0000 0000 0000 0000 0000 0000 1101 1000
b << 23 // 31 - 8
b = 1101 1000 0000 0000 0000 0000 0000 0000
b >> 31
b = 0000 0000 0000 0000 0000 0000 0000 0001

となります。

bitシフトは、左シフトした場合は、あふれた分が下位bitに表示されます。

b = 1000 0000 0000 0000 0000 0000 0000 0001
b << 1
b = 0000 0000 0000 0000 0000 0000 0000 0011

右シフトした場合は、あふれた分が削除され上位bitは0で埋められます。

b = 1000 0000 0000 0000 0000 0000 0000 0001
b >> 1
b = 0100 0000 0000 0000 0000 0000 0000 0000

作品

画面右下のsourceからコードを参照できます。

作品はすべてローカル環境で作成していますが、twiglでも再現できます。(おそらく)
https://twigl.app/

twiglを使用する場合は、Regulationをclassic(300es)にします。
スクリーンショット 2024-02-13 222236.png

Reference

リアルタイムグラフィックスの数学 ― GLSLではじめるシェーダプログラミング

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2