mesh_scatter_boulders — 3D terrain op

• 資料種類:mesh → mesh

• 呼叫: import fullseye as fs; fs.ledger.mesh_scatter_boulders(V, F, *, density: 'float', d_min: 'float', d_max=None, exponent: 'float' = 3.1, seed: 'int' = 0, region_weights=None, aspect=(1.0, 0.7, 0.5), embed: 'float' = 0.35, subdiv: 'int' = 1, shape: 'str' = 'ellipsoid', orientation: 'str' = 'normal', burial=(0.3, 0.6), max_count=None, hull_points=None, return_info: 'bool' = False)(要直接呼叫實作,import render3d; render3d.mesh_scatter_boulders(V, F, *, density: 'float', d_min: 'float', d_max=None, exponent: 'float' = 3.1, seed: 'int' = 0, region_weights=None, aspect=(1.0, 0.7, 0.5), embed: 'float' = 0.35, subdiv: 'int' = 1, shape: 'str' = 'ellipsoid', orientation: 'str' = 'normal', burial=(0.3, 0.6), max_count=None, hull_points=None, return_info: 'bool' = False);從台帳取用則 ops3d.get("mesh_scatter_boulders"))

用法

在網格上散布半埋的岩塊(冪律尺寸,帶 seed)→ (V, F)。

(或在 return_info=True 時回傳 (V, F, info))。

shape='ellipsoid'(預設,行為不變):icosphere 橢球,半軸為 D/2 × aspect(1 : 0.7 : 0.5,最短軸沿局部表面法線),繞法線旋轉並依 embed 下沉(0 = 擱在面上,1 = 中心位於表面)。shape='hull':稜角分明的岩塊 —— 在長寬比相同、帶 20 % 徑向抖動的橢球上取帶 seed 的隨機點並求凸包(平坦的小面、銳利的稜邊,呈現 Itokawa 巨礫的樣貌),每塊 hull_points 個點(預設隨尺寸變化: 10 + 8·log2(D/d_min),10..40)。orientation='random' 給每塊一個均勻隨機旋轉,而不是讓其短軸與法線對齊。對於凸包,下沉量

是 sample_boulders 給出的隨尺寸變化的 burial 比例(預設岩塊高度的 30–60 % 位於表面以下;embed 被忽略)。max_count 透過依同一規律提高 d_min 來限制期望個數(參見 sample_boulders;info['d_min_effective'] 回報實際值)。

位置與尺寸來自 sample_boulders(卜瓦松過程,N(>D) ∝ D^-exponent);岩石放在*依原樣傳入*的網格上 —— 請傳入已位移/ 細分的地形,使岩石落在最終表面上。來自 terrain_region_mask 的 region_weights 讓「海」區域保持平滑。岩石作為真實幾何體附加,因此與地形經由同一條光柵化器/ 光線投射路徑產生自陰影、投射陰影並產生遮擋。info = 取樣 dict 加上 faces_per_boulder 和 n_boulders。在 seed 下為確定性。Fail-closed。

步驟:以 sample_boulders 抽取位置(面上的均勻點)、面法線與直徑 D,為每塊岩石產生一個小網格並串接在輸入網格之後(頂點附加到末尾,面 index 已做偏移)。輸入的頂點與面原樣保留,因此可以根據 info['faces_per_boulder'] 和原本的面數只切出岩石的面。

• density:每單位面積(網格單位²)中 D ≥ d_min 的岩石期望個數。實際個數由卜瓦松分布決定,也可能為 0 個(此時回傳輸入的副本)。

• d_min < d_max(None = 10·d_min)、exponent > 0、aspect 為 3 個正元素、embed ∈ [0, 1]、subdiv ∈ [0, 3] (橢球的 icosphere 細分)、hull_points 在 [6, 200] 內。任何一項超出範圍都會拋出 ValueError。

• shape='ellipsoid':把半軸為 D/2·aspect 的橢球以最短軸沿法線的朝向放置,並把中心沿法線方向抬高 semi_z·(1 − embed)。

• shape='hull':橢球上隨機點的凸包。沿法線方向的高度範圍中,burial (預設 0.3〜0.6,岩石越小越深)比例的部分沉到面下。embed 被忽略。

• orientation='random' 為均勻隨機旋轉(4 元數,即四元數)。'normal' 為繞法線的隨機旋轉。旋轉的亂數使用以 seed + 1 初始化的 generator。

岩石是真實幾何體,因此 ambient_occlusion / cast_shadow / shadow_raycast 的光線會正常命中它們。放置的面就是傳入的網格本身,因此請在 mesh_displace_spectrum 或 mesh_subdivide 之後 呼叫(若先呼叫,岩石會浮在地面上方/埋入地面)。

參考(範例資料、文獻)

• 範例資料目錄(下載 URL / 授權) —— 2-D 用 skimage.data(BSD/公有領域)加合成圖,3-D 給出真實資料源(Stanford/PDS 等)的下載 URL。

• 運算子來歷與參考文獻 —— 該運算子族所依據的研究/方法出處。

可執行的範例(實際呼叫該運算子並已驗證的樣例)

• itokawa_regolith_hero — py -3.11 examples_3d/itokawa_regolith_hero.py

型別可銜接的下一個運算子(可接受 mesh 作為輸入)

mesh_to_voxel · mesh_to_points · to_points · fuse_to_voxel · ambient_occlusion · cast_shadow · supersample_mesh · render_beauty

同類別(terrain)

mesh_displace_fbm · terrain_region_mask · mesh_edge_lengths · mesh_subdivide · displacement_band_weights · mesh_displace_spectrum · bump_normals_fbm


*Provenance: render3d.py — 3D 運算子登記表。本條目由 tools/opdocs.py md 自動產生(請勿手動編輯)。*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.