かなり遅く時刻に就寝。夕方に寝まくったから仕方がない。

11:15 起床。長く変な夢だ。業務でリアルダンジョンマスターになっている。同僚だろう者も数名いる。 敵を殲滅して、今思うと玄室(敵を退治するために自分で扉を閉めた)で突っ立ってやることがなくなる。 夢の中でもヒマとは。勤務時間終了になって控室というか更衣室みたいなところに帰還する。 室内に産卵している衣服の中から自分のものを探していると目が覚める。

納豆とハムマヨパンを食す。PC を開く。

  • 理論値を狙ってみる みかもだし - YouTube: 前半を聴取しつつ作業する。
  • WebGL2 GPGPU
    • 今回 canvas を動的を生成する。寸法を明示的に指定する都合がある。
    • テクスチャー座標バッファーを作らなくてよい。座標変換もない。アニメーションもない。楽だ。
    • ピック回で登場した readPixels が今回も活躍する。
    • 以前もやったように gl.pixelStorei は必要。1 バイト長単位で処理させるように指示する。 そうしないと ArrayBufferView not big enough for request エラーが出る。
    • 関数 log は自作しないで、ブラウザーの console.log でいいことにする。実際、これで事足りる。
    • 基礎編の src 側と dst 側とで寸法を合わせない版、キャンバスのほうが狭い。
    • ここから変換反響編。頂点シェーダーの入出力項目数が多い一方、他方で断片シェーダーは空だ。
    • シェーダーオブジェクトをリンクする直前に gl.transformFeedbackVaryings というのを呼び出す。 これは変換反響バッファーに記録する値を指示するものだ。 モード gl.SEPARATE_ATTRIBS では varying の各値が異なるバッファーに書き込まれる。
    • いつものように頂点属性を設定する。
    • 次に変換反響バッファーを仕掛ける。見慣れぬ API を次々に利用する。
      • gl.createTransformFeedbackgl.bindTransformFeedback のペアでバッファーを生成、初期化する。 これは他の WebGL オブジェクトを同じスタイルなのでわかる。
      • gl.bindBufferBase で変換反響バッファーと GPU の内部メモリーみたいなものを束縛する? おそらく本文のイラストの矢印部分を定義する処理と考えるのが自然。
      • 後続する gl.bindTransformFeedback, gl.bindBuffer の空呼び出しは EOF 的なものを告げる?
      • gl.enable(gl.RASTERIZER_DISCARD); で断片シェーダーを実質的に無効化する。
      • gl.drawArrays(gl.POINTS, 0, a.length); で頂点を描画するふりをする。 そのとき、変換反響をトランザクションのような感じで効かせる:

        gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
        gl.beginTransformFeedback(gl.POINTS);
        gl.drawArrays(gl.POINTS, 0, a.length);
        gl.endTransformFeedback();
        gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
        
      • 描画後、さきほど gl.bindBufferBase で指定したバッファーを参照し、 gl.bindBuffergl.getBufferSubData で結果を得る。 関数名にサブとあるが、ここでは全部取得する。

14:05 ここまでコードを書いて動作確認。おやつ休憩。

15:00 ビデオの途中だがもう観たところなのでやめても大丈夫。外出する。

イトーヨーカドー曳舟店で体温チェック。それから押上駅に直行。 地下鉄に乗る。押上駅から東日本橋駅へ。乗り換えて森下駅へ。 また乗り換えて牛込神楽坂駅で降りる。久しぶりだ。

地上に出て神楽坂交差点に出て飯田橋方面に歩く。

16:30 セガ神楽坂店。MJ プロ卓東風戦 6 クレ。 最後のゲームは東三局でリーチ後から跳満に放銃して途中退席。 捨牌一段目でシャンポンリーチ。対面の親とドラを対子で抱えている上家の巧みな連携でそうなってしまった。

【SCORE】
合計SCORE:-138.5

【最終段位】
四人打ち段位:十段 経験値:-140.1

【10/2の最新8試合の履歴】
1st|------*-
2nd|---*----
3rd|-**-**--
4th|*------E
old         new

【順位】
1位回数:1(9.09%)
2位回数:2(18.18%)
3位回数:6(54.55%)
4位回数:2(18.18%)
平均順位:2.82

プレイ局数:54局

【打ち筋】
アガリ率:18.52%(10/54)
平均アガリ翻:3.20翻
平均アガリ巡目:10.20巡
振込み率:12.96%(7/54)

【10/2の最高役】
・跳満

退店。飯田橋駅へ移動。大江戸線に乗れるだろうと進んでいくと、まあ歩かされる。 やっとの思いでプラットフォームへ。乗車して森下駅へ。乗り換えて住吉駅で降りる。

地上に出ると雨がポツポツと降っている。バスが来る直前にまともに降り出す。 錦糸町駅で降り、地下通路を伝って錦糸公園まで移動。雨の勢いにムラがある。 オリナス錦糸町へ駆け込む。

20:05 カスミオリナス錦糸町店。461 円。クーポン使用。

  • 八宝菜丼
  • ブラックチョコ (2)
  • ライス

外へ出ると雨が強い。雨合羽を着用。暑い。

20:35 ビッグエー墨田業平店。272 円。

  • 絹豆腐 (2)
  • 小粒納豆 (3)
  • カレーヌードル
  • ツイストドーナツ (3)

買い物を終えて退店すると雨が上がっている。ありがたい。

20:45 曳舟の部屋に戻る。荷物を整理。シャワーを浴びる。風呂から出る。 PC を開いて晩飯。

  • 【BPL 2021】ファイナルステージ APINA VRAMeS vs ROUND1 - YouTube: 今晩はこれに集中する。さっき電車で Twitter をチェックしたときにどちらが勝ったか知っているのだが。
  • WebGL2 GPGPU 粒子の運動から
    • 粒子の位置をシェーダーで更新するというのが主題のようだ。現在の位置と速度をシェーダー入力とする。 新しい位置は次のシェーダー呼び出しの入力とするので、変換反響に意味がある。
    • シェーダープログラムを二つ用意する。一方は物理計算用、他方は描画用。
    • 運動の初期条件の設定コードが JavaScript のモダンな書き方になっている。
    • 今回は変換反響バッファーオブジェクトも二つ生成する。
    • コードを書く。まず運動用シェーダーソースを作成する。 頂点シェーダーのコードは等速直線運動でなくても通じそうだ。 画面端でラップするため mod を利用する。
    • 粒子を描くシェーダーソースはきわめて単純。ただし gl.POINT で描くのでそれ用の属性設定があることに注意。
    • シェーダープログラムを複数ビルドするので、そういう関数を実装する。 createShadercreateProgram もこれまでの知識で理解できる。 物理シェーダーのほうをビルドするときに変換反響用の名前を指定する。
    • いつもの位置取得コードを書く。
    • 例のモダンなコードを書く。よく見ると randcreatePoints は普通に関数として定義して構わない。
    • VBO を生成・初期化、それから VAO を生成・初期化する。 粒子を表すバッファーに対しては gl.DYNAMIC_DRAW を最適化ヒントとする。
    • 共通部分を関数にしてから変換反響バッファーを二つ作成する。
    • render を書く。その前のコメント unbind left over stuff の処理が重要だと言っている。 ちなみに swap 処理は JavaScript では [current, new] = [new, current] のように書ける。 もっとも、本書のほうが実行効率はいいと思われる。描画は効率優先。

22:25 粒子終了。BPL のビデオを観よう。

23:50 ゲームが終了したところで、放送時間があと一時間あるのはなぜ?