terrain op• 資料種類:normalmap × pointmap → normalmap
• 呼叫: import fullseye as fs; fs.ledger.bump_normals_fbm(normals, positions, wavelengths=(0.002, 0.001), amplitudes=(0.0002, 0.00012), *, seed: 'int' = 0, rotation=None, step=None, local_edge=None, nyquist: 'float' = 2.0, fade: 'float' = 1.0) -> 'np.ndarray'(要直接呼叫實作,import render3d; render3d.bump_normals_fbm(normals, positions, wavelengths=(0.002, 0.001), amplitudes=(0.0002, 0.00012), *, seed: 'int' = 0, rotation=None, step=None, local_edge=None, nyquist: 'float' = 2.0, fade: 'float' = 1.0) -> 'np.ndarray';從台帳取用則 ops3d.get("bump_normals_fbm"))
用帶 seed 的多倍頻高度場的梯度擾動法線圖。
這是幾何上無法承擔位移的次面片起伏 → 單位法線 (H, W, 3)。
h(x) = Σ_k A_k n_k(x) 與 mesh_displace_spectrum 位移時所用的 value-noise 場相同(相同 seed ⇒ 相同格點),因此傳入位移的頻帶閘控所拒絕的倍頻程,著色就會在面片尺寸以下延續*同一*振幅頻譜(不是偽造的砂紙:波長 λ 處振幅為 A 的倍頻程最多使法線傾斜約 2πA/λ)。bump 後的法線為 normalize(n − ∇_t h)(表面上高度場的一階著色法線; ∇_t = 以中心差分求得的切向梯度,step = min(λ)/64)。positions 是世界座標 (H, W, 3)(NaN = 背景, 保持不變);若給出 rotation(3×3,world → 法線座標系,例如 pose[:3,:3]), 則法線在該座標系中取得。
local_edge(選用,每個像素下方網格局部邊長的 (H, W) 圖)使 bump 恰好成為位移頻帶閘控的補集:倍頻程 k 以權重 1 − gate_k 做 bump,其中 gate_k 是採用相同 nyquist / fade 的 displacement_band_weights 的規則 —— 因此幾何在某像素已承載的倍頻程不會被加兩次,而幾何無法承載的倍頻程則完全由 bump 補上。沒有它時每個倍頻程都以全振幅做 bump。確定性;fail-closed。
輸入和輸出都是 (H, W, 3) 影像。positions 含 NaN 的像素,或法線長度在 1e-12 以下的像素,作為背景保持原值(render3d.render_mesh 的空像素)。若一個有效像素都沒有,則回傳輸入的副本。
• wavelengths / amplitudes:以網格(= positions)的單位表示、長度相同(1〜32)的正數序列。不一致或為負時拋出 ValueError。
• rotation:3×3(world → 法線的座標系)。給出時以 N @ R 把法線轉回 world 再求梯度,再以 @ R.T 轉回原座標系。render_mesh 的法線在相機空間,因此傳入 pose[:3,:3]。非有限、形狀不正確時拋出 ValueError。
• step:中心差分的步長(預設 min(wavelengths)/64)。0 以下拋出 ValueError。
• local_edge:(H, W) 的邊長圖。形狀與法線不同,或有效像素下存在非正、非有限值時拋出 ValueError。
高度場按 3 個軸做中心差分求導,因此每 1 像素評估 6 次。法線的傾斜約為 max |∇h| ≈ 2π A_k / λ_k,所以振幅越接近波長,法線傾倒得越厲害(預設 A/λ = 0.1 左右)。結果可直接傳給 phong_shade / brdf_hapke 等的法線圖輸入。
• 範例資料目錄(下載 URL / 授權) —— 2-D 用 skimage.data(BSD/公有領域)加合成圖,3-D 給出真實資料源(Stanford/PDS 等)的下載 URL。
• 運算子來歷與參考文獻 —— 該運算子族所依據的研究/方法出處。
• itokawa_regolith_hero — py -3.11 examples_3d/itokawa_regolith_hero.py
normalmap 作為輸入)fuse_to_voxel · render_shaded · phong_shade · matcap_shade · brdf_lommel_seeliger · brdf_hapke · integrate_normals · render_lambertian
terrain)mesh_displace_fbm · terrain_region_mask · mesh_scatter_boulders · mesh_edge_lengths · mesh_subdivide · displacement_band_weights · mesh_displace_spectrum
*Provenance: render3d.py — 3D 運算子登記表。本條目由 tools/opdocs.py md 自動產生(請勿手動編輯)。*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.