A series of tricks and techniques I learned doing tiny GLSL demos

2025/12/09 1:44

A series of tricks and techniques I learned doing tiny GLSL demos

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

本記事では、Moonlight、Entrance 3、Archipelago、および Cutie の4つの超小型 GLSL デモを紹介し、それぞれが 512 文字に制限される理由を説明しています。理由は、芸術的意図、教育目的、ポートフォリオの一貫性、および Mastodon の toot サイズ制限との互換性です。各デモは最小限のコードで特定のグラフィックストリックを詰め込んでいます。

  • Moonlight は、逆平方積分から導出されたレイマーチステップごとの単純な (1/d) ボリュメトリターム((v = \Delta t/(d_n d_{n+1}) \rightarrow 1/d_n))を使用します。また、透明度は (d = A,|d| + B) でモデル化できると指摘しており、ここで (A) が吸収を制御し、(B) が浸透を許可します。
  • Entrance 3 は距離関数に L‑∞ ノルムを採用し、固体に衝突した後にレイを光源へ向け直すとともに、Snapdragon/Adreno および Imagination/PowerVR デバイスでのモバイル GPU バグを示します。
  • Archipelago は (w=\exp(\sin x)) を用いたドメインワーピング FBM とノイズシフト (x -= w\cos x) により、無限に生成される手続き的な日本を作成します。
  • Cutie は球体をスムーズミンで丸みのある円錐へマージし、簡易逆運動学で脚部をアニメーション化し、深度マップではなく反復回数でシェーディングします。

Sympy などの実用ツールは、等角投影((-\frac{\sqrt{3}}{3}(1,1,1)))と二重視点投影((-\frac{1}{4}(\sqrt6,2,\sqrt6)))カメラ設定用の回転行列を計算するために使用されます。512 文字制限は Mastodon の toot サイズに合わせており、創造性と実現可能性をバランスさせ、学習リソース、ポートフォリオ展示、および迅速な共有のためにサイズ制限を課すツールチェーンへの影響力となるような簡潔で高品質なコードアーティファクトを提供します。

本文

Tiny GLSL デモ – 512文字で旅する

ここ2か月、私は小さな GLSL デモを書き続けていました。
最初の作品 Red Alp は別記事にまとめていますので、新規読者はそちらからご覧ください。

本稿ではその後に続く4つのデモ ― MoonlightEntrance 3Archipelago、そして Cutie を取り上げます。
各作品の重要ポイントを抜粋し、詳細を再解説するのは避けます。


Moonlight

デモ(460文字)

// Moonlight [460] by bµg
// License: CC BY-NC-SA 4.0
void main(){
    vec3 o,p,u=vec3((P+P-R)/R.y,1),Q; Q++;
    for(float d,a,m,i,t;i++<1e2;p=t<7.2?Q:vec3(2,1,0),
        d=abs(d)*.15+.1,o+=p/m+(t>9.?d=9.,Q:p/d),
        t+=min(m,d))
        for(p=normalize(u)*t,p.z-=5e1,m=max(length(p)-1e1,.01),
            p.z+=T,d=5.-length(p.xy*=mat2(cos(t*.2+vec4(0,33,11,0)))),a=.01;
            a<1.;a+=a)
                p.xz*=mat2(8,6,-6,8)*.1,
                d-=abs(dot(sin(p/a*.6-T*.3),p-p+a)),
                m+=abs(dot(sin(p/a/5.),p-p+a/5.));
    o/=4e2;
    O=vec4(tanh(mix(vec3(-35,-15,8),vec3(118,95,60),
        o-o*length(u.xy*.5))*.01),1);
}

学んだこと

Red Alp では、雲と霧を扱うボリュームレイマーチングに重い吸収/放射パイプラインを使用しました。
よりシンプルで物理的にも根拠のある方法としては、各ステップごとに

1/d
を加える手法があります。ここで
d
はレイ上現在位置の密度です。

なぜ
1/d
が機能するか

放射体が全方向に均等に光子を発生させると考えます。
光子密度は距離の逆二乗((1/r^2))で減衰します。レイを 2 点 (d_n, d_{n+1}) の密度で区切った場合、セグメント全体への寄与は

[ v = \Delta t \int_0^1 \frac{1}{( (1-t)d_n + td_{n+1})^2 },dt = \frac{\Delta t}{d_nd_{n+1}}. ]

レイマーチングループでは (\Delta t = d_{n+1}) になるので

[ v = \frac{1}{d_n}. ]

つまり、各イテレーションの寄与は「現在密度の逆数」だけで済むわけです。複雑な吸収モデルを使う必要はありません。

透明キューブ

固体を通過したい場合は

max(d,.001)
A*abs(d)+B
に置き換えます。
ここで

  • A
    ≈ 吸収(減衰)
  • B
    ≈ 基底透過率

Entrance 3

デモ(465文字)

// Entrance 3 [465] by bµg
// License: CC BY-NC-SA 4.0
#define V for(s++;d<l&&s>.001;q=abs(p+=v*s)-45.,b=abs(p+vec3(mod(T*5.,80.)-7.,45.+sin(T*10.)*.2,12))-vec3(1,7,1),d+=s=min(max(p.y,-min(max(abs(p.y+28.)-17.,abs(p.z+12.)-4.),max(q.x,max(q.y,q.z)))),max(b.x,max(b.y,b.z))))
void main(){
    float d,s,r=1.7,l=2e2;vec3 b,v=b-.58,q,p=
        mat3(r,0,-r,-1,2,-1,b+1.4)*vec3((P+P-R)/R.y*20.4,30);
    V;r=exp(-d*d/1e4)*.2;l=length(v=-vec3(90,30,10)-p);v/=l;d=1.;V;
    r+=50.*d/l/l;
    O=vec4(pow(mix(vec3(0,4,9),vec3(80,7,2),r*r)*.01,p-p+.45),1);
}

重要ポイント

  • L∞ 距離 – キューブはチェビシェフノルムで測るのが最適。SDF を簡素化できます。
  • 自己照明 – 最初にレイを固体までマーチした後、光源方向へ再度レイを投げます。そこに到達すればピクセルは点灯します。
  • モバイル GPU の落とし穴 – Snapdragon/Adreno は複合
    for
    を嫌い、Imagination/PowerVR は連鎖代入を嫌います。

正射影/斜投影カメラ

Sympy で回転行列を導出しました:

M_iso = √2·√3 [
    [ √3 , -1 , √2 ],
    [ 0   ,  2 , √2 ],
    [-√3 , -1 , √2 ]
]
M_dim = (4/√2) [
    [ 2 , -1 , √3 ],
    [ 0 , √6, √2 ],
    [-2 , -1 , √3 ]
]

レイ方向:

rd_iso = -M_iso * vec3(0,0,1);   // → -(√3/3)[1,1,1]
rd_dim = -M_dim * vec3(0,0,1);   // → -(1/4)[√6,2,√6]

画素レイの原点はスクリーン座標をスケーリングし、同じ行列で変換して微小

eps
を足すことで (y>0) を保証します。


Archipelago

デモ(472文字)

// Archipelago [472] by bµg
// License: CC BY-NC-SA 4.0
#define r(a)*=mat2(cos(a+vec4(0,11,33,0))),
void main(){
    vec3 p,q,k;
    for(float w,x,a,b,i,t,h,e=.1,d=e,z=.001;i++<50.&&d>z;h+=k.y,w=h-d,t+=d=min(d,h)*.8,
        O=vec4((w>z?k.zxx*e:k.zyz/20.)+i/1e2+max(1.-abs(w/e),z),1))
    for(p=normalize(vec3(P+P-R,R.y))*t,p.zy r(1.)p.z+=T+T,p.x+=sin(w=T*.4)*2.,
        p.xy r(cos(w)*e)d=p.y+=4.,h=d-2.3+abs(p.x*.2),q=p,k-=k,a=e,b=.8;a>z;a*=.8,
        b*=.5)q.xz r(.6)p.xz r(.6)k.y+=abs(dot(sin(q.xz*.4/b),R-R+b)),
    k.x+=w=a*exp(sin(x=p.x/a*e+T+T)),p.x-=w*cos(x),d-=w;
}

コアアイデア

世界は「島」用と「水」用の 2 つのノイズ関数で手軽に生成します。
ポイントは ドメインワーピング を利用することです:

x -= w * cos(x);   // ここで w = exp(sin(x))

各 FBM オクターブをその勾配方向にシフトさせることで、より多様な地形が得られます。


Cutie

デモ(602文字)

// Cutie [602] by bµg
// License: CC BY-NC-SA 4.0
#define V vec3
#define L length(p
#define C(A,B,X,Y)d=min(d,-.2*log2(exp2(X-L-A)/.2)+exp2(Y-L-B)/.2)))
#define H(Z)S,k=fract(T*1.5+s),a=V(1.3,.2,Z),b=V(1,.3*max(1.-abs(3.*k-1.),z),Z*.75+3.*max(-k*S,k-1.)),q=b*S,q+=a+sqrt(1.-dot(q,q))*normalize(V(-b.y,b.x,0)),C(a,q,3.5,2.5),C(q,a-b,2.5,2.)
void main(){
    float i,t,k,z,s,S=.5,d=S;
    for(V p,q,a,b;i++<5e1&&d>.001;t+=d=min(d,s=L+V(S-2.*p.x,-1,S))-S))
        p=normalize(V(P+P-R,R.y))*t,p.z-=5.,p.zy*=mat2(cos(vec4(1,12,34,1))),
        p.xz*=mat2(cos(sin(T)+vec4(0,11,33,0))),d=1.+p.y,
        C(z,V(z,z,1.2),7.5,6.),s=p.x<z?p.x=-p.x,z:H(z),
        s+=H(1.);
    O=vec4(V(exp(-i/(s>d?1e2:9.))),1);
}

取り組みポイント

  • スムーズミン(メタボール)で腕 – 各手足は 2 球を
    smin
    で結合した構造です。
  • IK アニメーション – 単位長の脚部を使った簡易逆運動学により、式を短く保ちました。
  • イテレーション数でディテール決定 – レイマーチの反復回数は表面近くになるほど増えるため、これを最終色に活用しました。

なぜ 512 文字?

  • 一つか二つの絵画的概念に集中できる → 学習効果が高い。
  • 制約があることでプロジェクト完了まで押し切れます。
  • Mastodon のトゥートサイズと一致するため、コードをそのまま投稿可能です。
  • ポートフォリオ全体の一貫性を保てます ― 文字数制限を変えると今後すべてが揺らいでしまいます。

最新情報は?

Mastodon をフォローするか RSS フィードに登録して、新しい記事やアップデートを受け取ってください。
HackerNews、Lobste.rs、Reddit でも議論に参加しています。

同じ日のほかのニュース

一覧に戻る →

2025/12/09 8:53

Kroger acknowledges that its bet on robotics went too far

## Japanese Translation: > **概要:** > Kroger(クローガー)は、3つのロボット型ECフルフィルメントセンターを閉鎖することを発表し、約26億ドルの費用がかかるものの、EC利益率を約4億ドル向上させる見込みです。今回の閉鎖は、以前に「スピーク」施設を停止した後であり、UKテック企業Ocado(オカド)とのパートナーシップも業績不振により一時停止されたことに続くものです。臨時CEOのロン・サーガント氏は、Krogerが各Ocadoサイトを個別に検討し、大規模な資本投資なしで2,700店舗以上を活用した迅速配送へシフトする方針だと述べました。以前、Krogerは2024年中頃に新しいOcado技術を導入予定でしたが、サイトのパフォーマンスを疑問視し、2023年9月にプロジェクトを停止しました。 > > Pine Street AdvisorsのKen Fenyo氏は、密集都市外にOcadoセンターを配置することが主な欠陥であると指摘しました。低い注文量と長距離がモデルを非収益的にしていたのです。米国消費者はInstacartやDoorDashなどから30分以内の配送を重視し、UKで成功したOcadoの遅めで価格志向のモデルよりも優先します。 > > 今後、Krogerはサードパーティ配達パートナーとの関係強化を図り、高需要市場(AmazonのWhole Foods試験に似た)で資本負担が軽い店舗ベースの自動化をパイロットし、残存するOcadoサイトの運用をケースバイケースで決定します。自動化からの撤退はOcadoにとって大きな後退となり、その株価はIPO前レベルまで下落しています。これは密集都市外でマイクロフルフィルメント技術を導入する難しさを浮き彫りにしています。

2025/12/09 3:51

Jepsen: NATS 2.12.1

## Japanese Translation: (欠落している要素をすべて組み込み、根拠のない推測を除去したもの) --- ## 要約 NATS JetStream のデフォルト「lazy‑fsync」ポリシーは、データをディスクにフラッシュする頻度が 2 分ごとにしか設定されていないため、データ損失およびサービス障害の重大なリスクを生じます。ノードがクラッシュしたり、そのブロック(.blk)やスナップショットファイルが破損すると、最大 78 % のメッセージが消失し、クラスターがクォーラムを失う可能性があります(GitHub issue #7549 および #7556)。協調クラッシュでも、全ストリームが削除されるケース (#6888) や永続的に利用不可になるケース (#7556) が報告されています。この問題は、単一ノードのクラッシュでそのノード上のすべてのデータが消去される点と、2 分間隔という設定が安全なフラッシュ前に約 30 秒分のトラフィックを失うリスク(#7564)を伴うため、さらに深刻です。 JetStream v2.10.22 はクラッシュ時に全ストリームを削除するバグ(v2.10.23 で修正済み)が存在し、スナップショットファイルの切断や単一ビットエラーもノードがストリームデータを削除しクォーラム復旧に失敗して永続的に利用不可になる原因となっていました(#7556)。OS のクラッシュとプロセス停止またはネットワーク分離の組み合わせにより、単一ノードの障害でもデータ損失や持続的なスプリットブレインが発生する可能性があります(#7567)。 NATS は lazy‑fsync ポリシーを文書化していますが、現時点でデフォルト設定変更を推奨していません。Jepsen は fsync を「always」に設定するか、ユーザーに対して相関失敗リスクを強調するよう勧告しています。JetStream のドキュメントが主張する線形性(linearizability)と「自己修復・常時可用性」は非同期ネットワークの CAP 定理に矛盾し、Jepsen もこの点を指摘しています。 Jepsen の LazyFS テストは、書き込みをディスクフラッシュ前にバッファリングするシステムで電源障害をシミュレートし、同様の相関ハードウェア障害が類似した失敗を引き起こすことを示しています。NATS は issue #7549、#7556、および #7567 を積極的に調査中であり、クラッシュ削除バグ(#6888)は v2.10.23 で修正済みですが、lazy fsync のドキュメントは残り変更されていません。

2025/12/09 4:44

Icons in Menus Everywhere – Send Help

## Japanese Translation: 改善されたまとめ この記事は、macOS のデフォルト設定で全てのメニュー項目にアイコンを付ける慣習を批判し、多くの場合可視性の「補填」のために追加されていると主張しています。Google Sheets を極端な例として挙げ、すべてのオプションにアイコンが付いていることを指摘し、同じグループ内でアイコンの有無に不一致がある点や、アイコンがチェックマークやトグル状態と重なるケース(例えば Safari の「Safari」「File」「View」メニュー)も示しています。著者は、macOS が従来はデフォルトでメニューアイコンを避けていたことを指摘し、macOS Tahoe でそれらが広く導入されたことで Apple の 2005 年人間インターフェースガイドライン(任意のシンボルの使用を勧めない)と矛盾していると述べています。 とはいえ、Finder のウィンドウ配置オプション(Top Left, Bottom & Top, Quarters など)は本当に役立つアイコンであり、レイアウト選択を迅速に認識できる点は評価されています。著者は Apple が普遍的なアイコン化へ進むことで、デザイナーが不適切なアイコン使用に対抗しづらくなるとフラストレーションを表明し、メニューの美学に関する継続的な緊張を生んでいると指摘しています。ユーザー側では視覚的な雑然や混乱が起こり得ますが、開発者や UI デザイナーは使いやすさとスタイルのバランスを慎重に取らざるを得ません。この議論は将来の Apple UI ガイドラインに影響し、メニュー設計に関する業界全体の慣行にも波及する可能性があります。