# Houdini Solaris Render-Time Procedurals 技術白皮書 ## 1. 系統概述 (System Overview) 本文件描述一種進階的 Houdini Solaris/USD 流程,旨在實現 **渲染時 (Render-Time) 的幾何體動態生成**。此技術不依賴將幾何體「烘焙 (Bake)」到 USD 緩存中,而是將 SOP 節點網絡 (Node Graph) 編碼為輕量級的數據,由渲染器 (Husk/Karma) 在渲染當下即時解算。 ### 核心價值 * **極致的記憶體效率**:USD Stage 僅儲存生成邏輯與參數,而非龐大的頂點數據。 * **無限細節潛力**:支援 Fractal、海量實例 (Instances) 或程式化植被,細節僅受限於渲染時的 RAM。 * **動態參數驅動**:允許在 LOP 層級透過屬性控制 SOP 內部的生成邏輯。 --- ## 2. 核心架構 (Core Architecture) 此流程依賴於將「運算邏輯」視為「幾何數據」的轉換機制: 1. **SOP Subnet (Generator)**: 定義幾何體生成規則的封裝容器。 2. **Attribute from Parameters SOP (Encoder)**: 將上述 Subnet 轉換為「點雲數據」,每個點代表一個節點,連線代表數據流 。 3. **Husk / Invoke Graph (Executor)**: 渲染器讀取上述點雲,利用 `invokegraph` 機制在記憶體中重建並執行該網絡。 --- ## 3. 實作流程詳解 (Implementation Guide) ### 第一階段:SOP 資產封裝 (The Generator) 在 SOP 層級建立生成邏輯,並將其輸出為 `.bgeo` 檔案。 1. **建立 Subnet**:將所有生成邏輯放入一個 `Subnet` 中。 2. **編碼網絡 (Encoding)**: * 連接 **Attribute from Parameters SOP**。 * **Method**: `Points from Subnetwork`。 * **Target Node**: 指向你的 Subnet。 * **Create Inputs/Outputs**: `Enable`。 3. **數據清理 (Cleanup)**: * 連接 **Blast SOP**。 * 刪除多餘的 Input 標記點,確保網絡封閉自洽。 4. **輸出檔案**:使用 `File Cache` 將結果存為 `.bgeo.sc`。這份檔案即是你的「程序化程式碼」。 ### 第二階段:LOP 場景配置 (The Stage) 在 Solaris (LOPs) 中調用該程序化資產。 1. **掛載 Procedural**: * 使用 **Feather Procedural** 或自定義的 USD Procedural Schema。 * 將 `File` 參數指向步驟一輸出的 `.bgeo` 檔。 2. **定義邊界框 (Bounding Box)**: * **極為關鍵**:設定 Prim 的 `ExtentsHint`。 * USD 必須在執行 Procedural 前知道物件的影響範圍,否則會被視錐剔除 (Frustum Culling) 導致物件消失。 3. **參數傳遞 (Overrides)**: * 透過 Dictionary Attribute (`parms`) 傳遞參數(詳見下節)。 --- ## 4. 參數驅動機制詳解 (Dictionary Attribute & Parms) 在 Render-Time Procedural 流程中,由於幾何體是在渲染當下生成的,標準的 Channel Reference (`ch()`) 無法從 SOP 內部讀取到 LOP 外部的參數。因此,我們必須依賴 **Dictionary Attributes** 進行「依賴注入 (Dependency Injection)」。 ### 4.1. 核心原理 系統利用一個名為 `parms` 的 **Detail Dictionary Attribute** 來攜帶所有參數數據。當 Procedural 被調用時,系統會自動查找這個字典,並將其中的 Key-Value 對應到 SOP Subnet 上 **Promoted Parameters** 的數值 。 ### 4.2. 建立參數字典 (The Data Source) 你可以使用兩種方式來準備這個字典: #### 方法 A:手動構建 (Attribute Adjust Dictionary) 這是最常用的方法,適合動態控制。 1. 建立 **Attribute Adjust Dictionary SOP**。 2. **Attribute Name**: 設定為 `parms`(必須完全一致)。 3. **Class**: 設定為 `Detail`。 4. **Add Key/Value Pairs**: * **Key**: 輸入 SOP Subnet 上參數的 **Parameter Name** (非 Label)。 * **Value**: 輸入你想要覆蓋的數值。 * *範例*: `Key: "seed"`, `Value: 12345`。 #### 方法 B:自動擷取 (Attribute from Parameters) 如果你想直接複製另一個節點的所有參數狀態: 1. 使用 **Attribute from Parameters SOP**。 2. 指向目標節點,它會自動生成一個包含該節點所有參數的 `parms` 字典 。 ### 4.3. 綁定驅動關係 (The Binding) 這是最容易出錯的步驟。單純建立 `parms` 屬性是不夠的,你必須告訴 Procedural 節點「去哪裡讀取這個字典」。 1. **新增 Spare Input**: 在你的 SOP 節點上,增加一個 **Spare Input** (通常是 Input -1) 。 2. **連接幾何流**: 將帶有 `parms` 屬性的幾何體連接到這個 Spare Input。 3. **建立索引參數 (`spare_parminputindex`)**: * 點擊節點的 **Edit Parameter Interface**。 * 新增一個 **Integer** 參數。 * **Name**: 必須命名為 `spare_parminputindex` 。 * **Label**: 任意 (例如 "Parms Source Index")。 4. **設定索引值**: * 將此參數設為對應的 Spare Input 索引編號。 * 通常第一個 Spare Input 的索引為 `-1` 。 ### 4.4. 數據類型對應表 為了確保參數能被正確覆蓋,字典內的數值類型必須與 SOP 參數類型匹配: | SOP Parameter Type | Dictionary Value Type | 範例 | | --- | --- | --- | | **Float / Integer** | Float / Integer | `size = 1.5` | | **Vector 3** | Array of 3 Floats | `pos = [0.0, 1.0, 0.0]` | | **String** | String | `texture = "diffuse.rat"` | | **Toggle** | Integer (0 or 1) | `enable_noise = 1` | | **Ramp** | *不支援直接覆蓋* | 建議改用 Texture 或 Array 傳遞 | --- ## 5. 技術限制與注意事項 (Limitations & Guidelines) ### 🔴 嚴格限制 * **無外部參考 (No External References)**: Subnet 內部嚴禁使用 `ch()`, `opinputpath()`, `object merge` 讀取 Subnet 外部的節點。所有數據必須自給自足或透過 `parms` 傳入。 * **Python SOP 線程安全**: 若 Subnet 內包含 Python SOP,必須確保代碼是 Thread-safe 的(Husk 是高度多線程環境)。避免使用 Global 變數。 ### 🟡 效能優化 * **邊界框 (Bounding Box)**: 這是最常見的錯誤來源。若 LOP 層級的 Extents 設置過小,渲染器會因為 Optimization 提早剔除物件,導致渲染結果為空。 * **幾何複雜度**: 雖然是動態生成,但生成過程仍佔用渲染時間。避免在 Procedural 內進行極其昂貴的布林運算 (Boolean) 或大型 VDB 轉換。 ### 🔵 動畫與動態模糊 * **時間變數**: 不要依賴 `$F`。應將時間作為參數 (`parms['time'] = @Time`) 傳入。 * **Motion Blur**: 為了正確的動態模糊,生成的幾何體拓撲 (Topology) 必須在幀之間保持一致。建議計算 `v` (Velocity) 屬性以實現 Velocity Blur,這比 Sample Blur 更高效且穩定。 ### 🟣 除錯建議 * **SOP 優先測試**: 永遠先在 Geometry Context (SOPs) 中使用 `Invoke Graph` 節點手動測試 `.bgeo` 檔案與參數字典的交互。如果在 SOP Viewport 跑不出來,在 Karma 裡絕對跑不出來。 * **路徑依賴**: 發佈到 Render Farm 時,確保 `.bgeo` 檔案路徑正確(建議使用 `$JOB` 或 `$HIP` 相對路徑)。