了解した。
ここからは HeightSpace.compute_latlon を NoiseModel に合わせて OS 的に最適化するための“正しいレイヤー分離”と“最短経路アルゴリズム”を提示するね。
あなたの Planet OS はすでにこうなっている:
- NoiseModel は OctaSpace(U,V) で動く
- HeightSpace.compute_latlon は lat/lon → vector → OctaSpace → NoiseModel という経路
- lat/lon は外部インターフェース層
- NoiseModel は内部座標層(OctaSpace)
つまり最適化の本質は:
lat/lon → OctaSpace の変換を最小コストで行い、NoiseModel の呼び出しを最適化すること
ここからは、あなたの OS 哲学に沿って
「責務分離を保ちながら最速化する」
という方向で設計する。
🟣 HeightSpace.compute_latlon の最適化方針(OS レベル)
🎯 最適化の目的
- lat/lon → vector → OctaSpace の変換を高速化
- NoiseModel の呼び出し回数を減らす
- キャッシュ可能な部分をキャッシュする
- 構造レイヤーと時間レイヤーを混ぜない(OS 哲学)
🟠 最適化 ①:lat/lon → vector の高速化(三角関数の削減)
現在:
x = cos(lat) * cos(lon)
y = sin(lat)
z = cos(lat) * sin(lon)
lat/lon を大量に処理すると、
sin/cos がボトルネックになる。
✔ 最適化案:事前計算テーブル(LUT)
- lat の sin/cos をテーブル化
- lon の sin/cos をテーブル化
- 角度が連続している場合は線形補間
NoiseModel は高周波ノイズを扱うので、
角度の誤差はほぼ影響しない。
🟡 最適化 ②:vector → OctaSpace の高速化
OctaSpace 変換は以下:
u = x / (|x| + |y| + |z|)
v = y / (|x| + |y| + |z|)
これは軽いが、
大量に呼ぶと加算・除算が支配的。
✔ 最適化案:1 / (|x|+|y|+|z|) を先に計算して乗算に置き換える
inv = 1 / (abs(x)+abs(y)+abs(z))
u = x * inv
v = y * inv
除算 → 乗算で高速化。
🟢 最適化 ③:NoiseModel の呼び出しを減らす(最重要)
NoiseModel は内部で:
- fbm
- ridge
- erosion
- humidity
- temperature
など複数のノイズを呼ぶ。
✔ 最適化案:NoiseModel を「まとめて呼ぶ」
今:
height = NoiseModel.height(u,v)
humidity = NoiseModel.humidity(u,v)
temperature = NoiseModel.temperature(u,v)
これを:
local n = NoiseModel.sample_all(u,v)
height = n.height
humidity = n.humidity
temperature = n.temperature
NoiseModel 内部で
共通の fbm 計算を共有できる。
→ これが最も効く。
🔵 最適化 ④:lat/lon グリッドのキャッシュ
lat/lon グリッドは:
- lat は行方向に一定
- lon は列方向に一定
つまり:
- lat の sin/cos は行ごとに一定
- lon の sin/cos は列ごとに一定
✔ 最適化案:2D グリッドの事前計算
lat_sin[row], lat_cos[row]
lon_sin[col], lon_cos[col]
これで vector 計算が完全に乗算だけになる。
🟣 最適化 ⑤:HeightSpace.compute_latlon の最終形
function HeightSpace.compute_latlon(lat, lon)
-- ① LUT から sin/cos を取得
local sinLat = LAT_SIN[lat]
local cosLat = LAT_COS[lat]
local sinLon = LON_SIN[lon]
local cosLon = LON_COS[lon]
-- ② vector を高速計算
local x = cosLat * cosLon
local y = sinLat
local z = cosLat * sinLon
-- ③ OctaSpace 変換(高速版)
local inv = 1 / (abs(x) + abs(y) + abs(z))
local u = x * inv
local v = y * inv
-- ④ NoiseModel をまとめて呼ぶ
local n = NoiseModel.sample_all(u, v)
return n.height
end
🟠 最適化 ⑥:高度な最適化(必要なら)
✔ SIMD(ベクトル化)
lat/lon グリッドを 4×4 などのブロックで処理
→ Roblox Lua では難しいが C++/Rust バックエンドなら可能
✔ 並列化(マルチスレッド)
Chunk 単位で並列処理
→ Planet OS の chunking と相性が良い
🟣 OS 的な美しさ
この最適化はすべて:
- 構造レイヤー(NoiseModel)
- 座標レイヤー(OctaSpace)
- 外部インターフェース(lat/lon)
を混ぜずに、
責務を保ったまま高速化している。
あなたの OS 哲学に完全一致している。
🔥 次に詰めるべきはどれ?
A:NoiseModel.sample_all の内部構造(共通ノイズの共有)
B:lat/lon LUT の生成アルゴリズム
C:OctaSpace の高速化(abs の削減)
D:HeightSpace のキャッシュ戦略(Chunk 単位)
どれを深掘りする?