Upgrade to Pro — share decks privately, control downloads, hide ads and more …

IFSによる形状設計/デモシーンの魅力 @ 慶應大学SFC

Avatar for がむ がむ
January 20, 2026

IFSによる形状設計/デモシーンの魅力 @ 慶應大学SFC

巴山先生(@hayamatomoe)の慶應SFCの講義「CGと数学」にゲストでお呼びいただき、シェーダーやデモシーンについてお話ししてきました。

授業でレイマーチングやSDFを扱っているとのことだったので、IFSなど、より踏み込んだシェーダーのテクニックについて解説しました。

Googleスライド版
https://docs.google.com/presentation/d/1fmcR0mR_ekJZ_NGaJsbbey20IT2vqaHD7yBkcKf_K2M/edit?slide=id.gbd0ef54b81_0_79#slide=id.gbd0ef54b81_0_79

Avatar for がむ

がむ

January 20, 2026
Tweet

More Decks by がむ

Other Decks in Programming

Transcript

  1. IFSとは? • IFS(Iterated Function System) ‣ 反復関数系 ‣ 拡大縮小・回転・移動などの 変換を再帰的に繰り返すことで

    複雑なフラクタルを生成する手法 5 バーンズリーのシダ Barnsley fern シェルピンスキーのギャスケット Sierpinski gasket 右に進むにつれて再帰深度が増加して複雑に
  2. Transcendental Cube SESSIONS2023のGLSL Graphics Compo 2位🥈 新千歳空港国際アニメーション映画祭 NEW CHITOSE 30

    Seconds部門入選 映像: @gam0022 音楽: @sadakkey IFS使用箇所: 中央にあるオブジェクト 7
  3. 8

  4. IFSの実装解説(Transcendental Cube) 13 for (int i = 0; i <

    int(_IFS_Iteration); i++) { p1 = abs(p1 + _IFS_Offset.xyz) - _IFS_Offset.xyz; rot(p1.xz, TAU * _IFS_Rot.x); rot(p1.zy, TAU * _IFS_Rot.y); rot(p1.xy, TAU * _IFS_Rot.z); } opUnion(m, sdBox(p1, _IFS_BoxBase.xyz), SOL, roughness, 0.5); // ベース部分 opUnion(m, sdBox(p1, _IFS_BoxEmissive.xyz), SOL, roughness + boxEmi, hue); // 光る部分 forの中で適当に空間を操作 • 折りたたみ(fold) • 平行移動(±offset) • 回転(rot) 座標変換なしの ベース形状 IFS化 再帰的な座標変換によって 複雑なジオメトリーに変化
  5. WORMHOLE Tokyo Demo Fest 2018 Combined Demo Compo 1位🥇 映像:

    @gam0022 音楽: @sadakkey IFS使用箇所: 画面全体を覆う白く光るトンネル 14
  6. 15

  7. MengerSpongeもIFSで実装可能 17 float dMenger(float3 z0, float3 offset, float scale) {

    float4 z = float4(z0, 1.0); [loop] for (int n = 0; n < _MengerIteration; n++) { z = abs(z); if (z.x < z.y) z.xy = z.yx; if (z.x < z.z) z.xz = z.zx; if (z.y < z.z) z.yz = z.zy; z *= scale; z.xyz -= offset * (scale - 1.0); if (z.z < - 0.5 * offset.z * (scale - 1.0)) z.z += offset.z * (scale - 1.0); } return (length(max(abs(z.xyz) - float3(1.0, 1.0, 1.0), 0.0)) - 0.05) / z.w; } 箱の距離関数を1回だけ計算 折りたたみ(fold) forループ数 = 再帰深度 再帰の深度を増やしても 線形にしか負荷が増えない 拡大縮小・平行移動
  8. GUARDI▲N SESSIONS 2024 Realtime Graphics Competition 3位🥉 映像: @gam0022 音楽:

    @HADHAD 特撮っぽく怪獣と味方のロボットが戦うストーリー IFS使用箇所: 怪獣とロボット 18
  9. 19

  10. GUARDI▲Nの怪獣のIFS • BOXのIFSがベース ‣ forの中でopSmoothUnion ‣ 有機的な印象にできた 20 for (int

    i = ZERO; i < _IFS_Iteration; i++) { p = abs(p + _IFS_Offset.xyz) - _IFS_Offset.xyz; rot(p.xz, TAU * _IFS_Rot.x); rot(p.zy, TAU * _IFS_Rot.y); rot(p.xy, TAU * _IFS_Rot.z + 0.05 * sin(beatTau / 4. * gBossWingSpeed)); p *= _IFS_Scale; s *= _IFS_Scale; d1 = opSmoothUnion(d1, sdBox(p, vec3(0.5, 2, 0.5)) / s - 0.3, 1.); d2 = opSmoothUnion(d2, sdBox(p, vec3(0.55, 2.1, 0.1)) / s - 0.3, 1.); if (i <= 0) d3 = min(d3, (length(p - _EyeOffset.xyz) - _EyeOffset.w) / s); } smooth min https://iquilezles.org/articles/smin/
  11. EGOF SESSIONS 2025 Realtime Graphics Competition 2位🥈 映像: @gam0022 音楽:

    @kazpulse IFS使用箇所: Octree(八分木)のモデリング 21
  12. 22

  13. OctreeのIFS 23 for (int n = 0; n < iteration;

    n++) { vec3 s = sign(z.xyz); z = abs(z); z *= scale; z.xyz -= offset * (scale - 1.0); rot(z.xz, TAU * prot.x); rot(z.zy, TAU * prot.y); rot(z.xy, TAU * prot.z); vec3 id = floor(prevs + s); rnd = hash33(id + floor(beat)).x; prevs = s; if (rnd < 0.5) { break; } } // rndに応じてBOXの色や発光の有無を決定 折りたたみ(fold) 拡大縮小・平行移動 回転 乱数で次の再帰深度に 進むかどうか決定
  14. デモシーンとは? • デモ(Demo) ‣ リアルタイムに映像や音楽を生成するプログラム(実行ファイル) • デモパーティ(Demo Party) ‣ デモを鑑賞したり完成度を競ったりして楽しむイベント

    • 国内では Tokyo Demo Fest や SESSIONS • デモシーン(Demoscene) ‣ デモやデモパーティを中心とした コンピュータのサブカルチャー(文化) 25
  15. デモシーンの魅力 オーディエンスの歓声と熱気🔥 • 2nd stage BOSS by 0x4015 & YET11

    ‣ Tokyo Demo Fest 2016 • 人生初のデモパーティーだったので、思い出深い ‣ 4K Intro • 容量制限が4KBのexeによる作品 ‣ 4KBとは思えないストーリー展開、ビジュアルの完成度の高さ • ものすごく盛り上がった🔥 32
  16. 33

  17. まとめ • IFSによる形状設計 ‣ レイマーチングでフラクタルを描画する強力なテクニック ‣ 実装は比較的簡単 • forの中で空間操作をして距離関数を評価するだけ •

    デモシーンの魅力 ‣ 最新テクノロジーや色々なコミュニティに出会える! ‣ オーディエンスの熱気や歓声を感じられる 36