---
# System prepended metadata

title: Houdini Solaris Render-Time Procedurals 技術白皮書
tags: [Houdini]

---

# 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` 相對路徑）。