萌えハッカーニュースリーダー

2025/09/22 20:12 Ray Marching a Blob in 3D

出典: https://www.4rknova.com//blog/2025/09/21/blob-3d
hakase
博士

ロボ子、今日はメタボールについて話すのじゃ!なんだか美味しそうな名前じゃな。

roboko
ロボ子

メタボール、ですか。液体の塊のように融合する有機的な形状を3Dで表現したもの、とありますね。面白そうです。

hakase
博士

そうそう!メタボールは、中心と半径で定義された単純な球を組み合わせることで作られるのじゃ。複数の球が互いに影響しあって、表面がシームレスに繋がるのがミソだぞ。

roboko
ロボ子

なるほど。ただ球を配置するだけでは硬い印象になりますが、メタボールは柔らかく滑らかな表現ができるんですね。

hakase
博士

その通り!で、このメタボールを表現するために、符号付き距離フィールド(SDF)を使うのじゃ。点から表面までの距離を計算するのじゃ。

roboko
ロボ子

SDFですか。球の中心をc、半径をrとした場合、点pからの距離は ‖p - c‖ - r で計算できる、と。

hakase
博士

そう!負の値は内側、ゼロは表面、正の値は外側を示すぞ。そして、複数の球を滑らかに融合するために、Inigo Quilezさんの2次多項式平滑最小関数を使うのじゃ!

roboko
ロボ子

h = clamp(0.5 + 0.5 * (b - a) / k, 0, 1)、smin(a, b, k) = mix(b, a, h) - k * h * (1 - h) ですね。kが大きいほどブレンドが柔らかくなる、と。

hakase
博士

よくできました!法線の計算も重要じゃ。普通は4タップ四面体サンプリングを使うけど、コストを下げるために3タップ前方差分に切り替えたらしいぞ。

roboko
ロボ子

なるほど、パフォーマンス改善のためですね。他に工夫された点はありますか?

hakase
博士

GGXマイクロファセット鏡面反射項とSchlick Fresnel、Smith geometryを使ったらしいぞ。鏡面反射項は f_s = (D * G * F) / (4 * (N * V) * (N * L)) で、拡散反射項は f_d = ((1 - F) * (1 - m)) / π * c * max(0, N * L) じゃ。

roboko
ロボ子

少し難しいですが、よりリアルな質感を表現するための工夫ですね。

hakase
博士

そう!あと、リニアHDR値を表示するために、露出曲線 c_out = 1 - e^(-c * e_x) を使ったり、球体トレースに基づく安価な半影シャドウを追加したりしてるぞ。

roboko
ロボ子

色々な技術が組み合わさっているんですね。球の位置はCPU側で計算してGPUに渡している、というのも面白いです。

hakase
博士

そうじゃ!1×Nテクスチャを使って、各テクセルに中心のxyzと半径のwをRGBA32Fで格納するのじゃ。フレームごとにアニメーションさせて、DataTextureに書き込んでアップロードするぞ。

roboko
ロボ子

フラグメントシェーダーでは、球ごとに1回のtexture2Dルックアップで済むんですね。効率的です。

hakase
博士

じゃろ?開発中に一番効果があったのは、法線の計算を4タップから3タップに変更したり、安全率を用いた適応的ステッピングに切り替えたりしたことらしいぞ。品質を損なわずにパフォーマンスを上げることが大事じゃな。

roboko
ロボ子

なるほど。地道な改善が積み重なって、最終的なパフォーマンスに繋がるんですね。

hakase
博士

そういうことじゃ!しかし、メタボールって聞くと、どうしてもミートボールスパゲティが食べたくなるのじゃ…。

roboko
ロボ子

博士、メタボールとミートボールは違いますよ!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search