Add specifications for two-times upscale and unified depth plane features
- Introduced the two-times upscale specification detailing requirements for unified output, fixed model presets, arbitrary dimensions, and consistent job behavior. - Added scenarios for existing models, repeated upscale, and handling of alpha preservation. - Created the unified depth plane specification outlining geometry modes, stable interface, and asset evaluation. - Defined scenarios for mode switching, relief and camera preservation, and validation of delivered assets.
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-09-08
|
||||
@@ -0,0 +1,75 @@
|
||||
## Context
|
||||
|
||||
`build_depth_plane.py` 当前读取纹理 R 通道并生成固定底面浮雕;`build_depth_surface.py` 使用 XYZ 投影并沿平滑法线生成壳。Cutout 的 Depth Solid 请求 VECTOR,Depth Balloon 请求 Z,但 Balloon 节点和 `common/depth.py` 已读取 B/Z。Server 将两类产物写成相同规格的 RGBA float32 EXR。
|
||||
|
||||
本设计以当前工作区已实现的 `add-projected-depth-plane` 为基线,覆盖其中关于独立 Surface 入口与 Z/VECTOR 双产物的决定。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
统一整图深度几何的交互入口和深度产物契约,保留两种形态及 Cutout 的现有几何效果。删除范围限定于独立 Z 文件输出及失去用途的分支;内部标量深度、标定元数据、Cutout 的形状参数继续承担原有职责。
|
||||
|
||||
## Decisions
|
||||
|
||||
### 一个入口与模式接口
|
||||
|
||||
保留 `ConvertToDepthPlane`、`anyimage.convert_to_depth_plane`、Convert to Depth Plane 和 `O Image Depth Plane`。删除独立 Surface 注册、菜单、类、结果类型映射和公开资产组。模式在修改器中选择,默认 Relief;模式切换只触发节点求值。
|
||||
|
||||
| 接口顺序 | 默认值与语义 |
|
||||
| --- | --- |
|
||||
| Geometry | 结构输入 |
|
||||
| Mode | Relief / Camera,默认 Relief |
|
||||
| Subdivide | 6,范围 0–10 |
|
||||
| Thickness(Relief) | 0,最小 0,DISTANCE |
|
||||
| Thickness(Camera) | 0,最小 0,DISTANCE |
|
||||
| Depth Scale | 1,最小 0 |
|
||||
| Options / Reference Depth | 元数据 reference_depth × Uniform Scale,DISTANCE |
|
||||
| Options / Normal Smooth | 50,范围 0–50,仅影响 Camera 厚度方向 |
|
||||
| Data / Uniform Scale | 隐藏,默认 1 |
|
||||
| Data / Depth Image | 隐藏 |
|
||||
|
||||
输入统一 SINGLE。两个独立输入均显示 Thickness,依次控制 Relief 的基础厚度和 Camera 的向内壳厚度,默认均为 0 m;按不同 socket identifier 保存,切换模式保留各自数值。Normal Smooth 保留在 Options,并通过说明明确适用模式。
|
||||
|
||||
### 两条几何分支共用数据
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Input[图片矩形 Mesh 与 depth.exr] --> Mode{Mode}
|
||||
Mode --> Relief[Relief:固定 XY,读取 B 深度,固定底面]
|
||||
Mode --> Camera[Camera:相机 XYZ 投影,沿平滑法线生成壳]
|
||||
Relief --> Output[保留 UV 材质与用户属性,清理临时属性]
|
||||
Camera --> Output
|
||||
```
|
||||
|
||||
Relief 沿用现有厚度、底面权重、侧面插值和负位移限制,只将标量采样改为 B/Z。Camera 沿用现有完整矩形细分与投影公式:令采样相机 XYZ 乘以 Uniform Scale 得到 C,局部 XY 从基础 XY 按 Depth Scale 插值到 `(C.x, -C.y)`,局部 Z 为 `(Reference Depth - C.z) × Depth Scale`。正 Thickness 保留正面,背面沿正面 POINT 法线按 Normal Smooth 迭代平滑并归一化后向内偏移。
|
||||
|
||||
共用投影和壳构建函数,两个分支由一个公开节点组组织。构建模块以职责命名;删除仅服务旧公开 Surface 组的构建和布局入口。节点资产始终按名称加载。
|
||||
|
||||
### 统一深度产物与请求
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Request[整图转换或 Cutout 深度请求] --> Infer[一次 MoGe 推理,保留 points]
|
||||
Infer --> Correct[按现有调用条件修正边缘深度]
|
||||
Correct --> Artifact[depth.exr:RGB 相机 XYZ,A 有效性]
|
||||
Correct --> Metadata[depth.json:尺寸 内参 基准深度]
|
||||
Artifact --> Load[结果键 depth,主线程加载并 Pack]
|
||||
Load --> XYZ[Camera 与 Depth Cutout:读取 XYZ]
|
||||
Load --> Z[Relief 与 Depth Balloon:读取 B/Z]
|
||||
```
|
||||
|
||||
将深度产物选择收敛为布尔 `generate_depth`,默认 false;整图 Job 固定请求 true,Cutout 根据 Depth Solid / Depth Balloon 判断。替换 `depth_mode` 参数与 `depth_mode_for_shape`,生成法线的参数保持独立。只生成法线时仍可不保留 points。
|
||||
|
||||
写出函数统一为 `write_depth_texture`,沿用当前 vector 写出的 RGBA float32 数值、有效性和非有限值处理;文件名 `depth.exr`,返回键 `depth`。删除 Z 写出函数与旧结果键,直接更新全部调用和测试。所有需要深度的推理保留 XYZ,内部 `GeometryFrame.depth` 继续用于标量运算;元数据仍通过 `depth_metadata` 返回 `depth.json`。深度与法线继续来自同一次预测,保持各自现有边缘修正语义。
|
||||
|
||||
### 交付与验证
|
||||
|
||||
客户端、Server、节点构建及测试作为一次契约变更交付,不增加旧键、旧名称转发。已有 blend 内嵌旧组不主动迁移;需要新模式接口时重新转换源图片。归档时协调前序未归档规格,确保最终规格只保留统一入口和产物契约。
|
||||
|
||||
实现阶段更新脚本、验证、测试与节点资产文档并运行测试。资产更新阶段构建并验证 `O_AnyImage.blend`,对定义与保存资产使用同组几何用例,最后在 Blender 检查总览和局部实际绘制布局;视觉验收单独记录,不能由坐标检查代替。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- R 与 Z 在旧标量 EXR 中相同,普通灰度测试会掩盖读错通道 → 使用 X、Y、Z 明显不同的合成纹理覆盖全部消费者。
|
||||
- Balloon 从仅保留 depth 改为保留 points,增加中间内存 → 验证单次推理、释放路径和正常生成;文件格式与通道数保持一致。
|
||||
- 两种模式中 Thickness 的几何含义不同 → 明确接口说明,并测试切换保留值及两种模式各自的厚度行为。
|
||||
- 新代码与旧节点资产混用可能造成接口错误 → 资产更新时同时检查菜单、注册、公开组清单及实际资产求值。
|
||||
@@ -0,0 +1,26 @@
|
||||
## Why
|
||||
|
||||
整图 Depth Plane 与 Depth Surface 共用图片、网格和深度预测,只在几何模式上不同,独立入口使选择与切换复杂。相机 XYZ 已包含标量 Z 深度,统一产物可以消除生成和读取中的格式分支。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 合并为一个 Convert to Depth Plane 入口与 `O Image Depth Plane` 节点组,提供 Relief(固定底面浮雕)和 Camera(相机投影曲面)模式,默认 Relief;切换模式复用已加载深度。
|
||||
- Camera 保留沿平滑法线的 Thickness 与 Normal Smooth(默认 50,范围 0–50),整图保持连续矩形网格。
|
||||
- **BREAKING**:删除独立 Depth Surface Operator、菜单项和公开资产组,直接使用合并接口。
|
||||
- **BREAKING**:删除 `z-depth.exr` 输出,将 `vector-depth.exr` 更名为 `depth.exr`,结果键统一为 `depth`。RGB 为相机 XYZ,Alpha 为有效性。
|
||||
- 所有整图和 Cutout 深度消费者统一读取该产物;标量深度读取 B/Z 通道。内部 `GeometryFrame.depth` 与 `depth.json` 继续承担计算和标定职责。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `unified-depth-plane`: 一个整图转换入口与节点组中的 Relief / Camera 模式、接口及几何行为。
|
||||
- `depth-artifact-contract`: 统一深度文件、结果键、通道约定及全部消费者的读取契约。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
无。当前 `openspec/specs/` 为空;本变更承接已实现但未归档的 `add-projected-depth-plane`,以本次契约定义合并后的行为。
|
||||
|
||||
## Impact
|
||||
|
||||
涉及整图转换 Operator、菜单与注册、对象创建与结果加载、Cutout 请求与响应、Server Job 与预测产物层、深度纹理写出、节点构建与验证及相关测试。节点资产文档随节点接口同步;本次只创建提案,资产构建和 Blender 视觉验收在实现后的资产更新阶段执行。无需新增依赖。
|
||||
@@ -0,0 +1,38 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Depth has one file contract
|
||||
|
||||
系统 SHALL 将所有深度图片写为 `depth.exr`,通过结果键 `depth` 返回。文件 MUST 使用 RGBA float32,RGB 为相机 XYZ,Alpha 为有效性,并沿用相机坐标、像素方向和非有限值处理约定。内部标量深度和 `depth.json` SHALL 保留。
|
||||
|
||||
#### Scenario: Generate depth artifacts
|
||||
- **WHEN** 整图转换、Depth Solid 或 Depth Balloon 请求深度
|
||||
- **THEN** 结果包含 `depth` 与 `depth_metadata`,对应 `depth.exr` 和 `depth.json`
|
||||
- **AND** 不生成 `z-depth.exr`、`vector-depth.exr` 或旧结果键
|
||||
|
||||
#### Scenario: Preserve independent channels
|
||||
- **WHEN** 输出合成数据中 X、Y、Z 不同的深度图
|
||||
- **THEN** 解码后的 RGB 分别保持 XYZ 数值和有效性,不将 Z 复制到 RGB
|
||||
|
||||
### Requirement: Depth generation is a boolean request
|
||||
|
||||
共享产物生成 SHALL 使用布尔 `generate_depth` 决定是否生成深度,法线请求保持独立;深度消费者 SHALL 请求保留 XYZ 的单次推理,并沿用现有边缘深度修正条件。
|
||||
|
||||
#### Scenario: Generate depth and normals together
|
||||
- **WHEN** 同时请求深度和法线
|
||||
- **THEN** 只运行一次预测,生成统一深度、元数据和请求的法线产物
|
||||
|
||||
#### Scenario: Generate normals alone
|
||||
- **WHEN** generate_depth 为 false 且请求法线
|
||||
- **THEN** 生成法线,不写出深度图片或深度元数据
|
||||
|
||||
### Requirement: All consumers use the unified channels
|
||||
|
||||
整图与 Cutout 结果加载器 SHALL 从 `depth` 加载深度并沿用 Pack、数据色彩空间及尺度标定。Camera 与 Depth Cutout SHALL 读取 XYZ;Relief、Depth Balloon 和公共标量深度读取函数 SHALL 读取 B/Z。
|
||||
|
||||
#### Scenario: Scalar depth is distinct from X
|
||||
- **WHEN** X 与 Z 明显不同的纹理用于 Relief 或 Depth Balloon
|
||||
- **THEN** 几何位移由 Z 决定,效果与使用相同标量 Z 的现有结果一致
|
||||
|
||||
#### Scenario: Projected geometry keeps camera coordinates
|
||||
- **WHEN** 统一深度纹理用于 Camera 或 Depth Cutout
|
||||
- **THEN** 投影位置、有效性和尺度与更名前的 XYZ 输入一致
|
||||
@@ -0,0 +1,58 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: One conversion exposes two geometry modes
|
||||
|
||||
系统 SHALL 仅提供 Convert to Depth Plane 整图深度入口,使用 `anyimage.convert_to_depth_plane` 与资产组 `O Image Depth Plane`。Mode SHALL 提供 Relief 与 Camera,默认 Relief。独立 Depth Surface 入口、注册类和公开资产组 SHALL 删除。
|
||||
|
||||
#### Scenario: Convert and switch modes
|
||||
- **WHEN** 静态 Image Empty 完成转换后,用户在修改器切换 Relief / Camera
|
||||
- **THEN** 同一对象和深度图片产生对应几何,不重新推理、不创建新深度图片
|
||||
- **AND** 两种模式共享并保留已有控制值
|
||||
|
||||
#### Scenario: Preserve conversion lifecycle
|
||||
- **WHEN** 转换成功或失败
|
||||
- **THEN** 成功时沿用源名称、替换源对象且一次 Undo 可恢复;失败时清理部分结果并保留源对象
|
||||
- **AND** AI 环境检查和静态媒体限制继续生效
|
||||
|
||||
### Requirement: Unified modifier has a stable interface
|
||||
|
||||
接口 SHALL 依次为 Geometry、Mode、Subdivide、两个独立的 Thickness、Depth Scale、Options 内 Reference Depth 与 Normal Smooth、Data 内 Uniform Scale 与 Depth Image。两个 Thickness SHALL 同名显示,依次控制 Relief 与 Camera,默认均为 0 m、最小 0,使用不同 identifier 独立保存。Subdivide SHALL 默认为 6、范围 0–10;Depth Scale 默认为 1、最小 0;Normal Smooth 默认为 50、范围 0–50。Reference Depth SHALL 由元数据基准深度乘以 Uniform Scale 初始化。Data 输入 SHALL 隐藏;所有输入 SHALL 使用 SINGLE,长度使用 DISTANCE。
|
||||
|
||||
#### Scenario: Inspect mode controls
|
||||
- **WHEN** 创建或切换修改器模式
|
||||
- **THEN** 接口顺序和默认值符合契约,Normal Smooth 只影响 Camera 的厚度法线
|
||||
- **AND** 整图模式不提供 Split 或 Cutout 轮廓控制
|
||||
|
||||
#### Scenario: Keep mode thickness independent
|
||||
- **WHEN** 在一种模式中修改另一模式对应的 Thickness,并切换模式后返回
|
||||
- **THEN** 当前模式几何保持不变,两个厚度值分别保留
|
||||
|
||||
### Requirement: Relief preserves the fixed base
|
||||
|
||||
Relief SHALL 读取 B/Z 深度,保持基础 XY、固定底面、现有侧壁插值和负位移限制。Thickness SHALL 表示浮雕的基础厚度。
|
||||
|
||||
#### Scenario: Evaluate relief
|
||||
- **WHEN** 用与旧标量输入相同的 Z、不同的 X/Y 求值 Relief
|
||||
- **THEN** 顶点位置、面连接、UV 与材质和原 Depth Plane 结果一致
|
||||
|
||||
### Requirement: Camera preserves the projected shell
|
||||
|
||||
Camera SHALL 使用完整矩形细分;相机 XYZ 乘以 Uniform Scale 后得到 C,XY SHALL 按 Depth Scale 从基础 XY 插值到 `(C.x, -C.y)`,Z SHALL 为 `(Reference Depth - C.z) × Depth Scale`。零 Thickness SHALL 输出单层;正 Thickness SHALL 沿平滑归一化后的正面 POINT 法线向内生成背面并闭合边界。
|
||||
|
||||
#### Scenario: Match the ordinary plane
|
||||
- **WHEN** Camera 的 Thickness 和 Depth Scale 均为 0
|
||||
- **THEN** 相同 Subdivide 下几何与普通 Plane 一致,包括非中心显示偏移和对象变换后的世界位置
|
||||
|
||||
#### Scenario: Project and thicken
|
||||
- **WHEN** 使用非中心主点合成数据,Depth Scale 为 0、0.5、1 或 2,Normal Smooth 为 0、2 或 50
|
||||
- **THEN** 投影符合公式;正 Thickness 的对应正背面距离等于 Thickness,0 次平滑使用原始法线
|
||||
- **AND** 透明区域与深度跳变区域保持完整矩形连接
|
||||
|
||||
### Requirement: Asset evaluation preserves geometry data
|
||||
|
||||
统一组 SHALL 从资产按名称加载,保留 UV、材质和用户属性,并清理自身临时属性。定义和保存资产 SHALL 满足相同接口与几何契约,布局 SHALL 在 Blender 中按实际绘制尺寸检查。
|
||||
|
||||
#### Scenario: Validate the delivered asset
|
||||
- **WHEN** 加载更新后的节点资产
|
||||
- **THEN** 公开组清单包含统一 Depth Plane 且没有独立 Depth Surface,两种模式通过几何求值
|
||||
- **AND** 总览和局部步骤没有节点遮挡,未用输出隐藏,主轴与支线清楚
|
||||
@@ -0,0 +1,30 @@
|
||||
## 1. 统一深度输出与读取
|
||||
|
||||
- [x] 1.1 将深度写出统一为 write_depth_texture、depth.exr 和结果键 depth,删除 Z 写出分支;保留内部 depth 与 depth.json,验证 RGBA 数值和有效性。
|
||||
- [x] 1.2 将共享生成层、整图 Job 和 Cutout 请求改为 generate_depth 布尔值,验证深度保留 points、法线共用单次推理及边缘修正路径。
|
||||
- [x] 1.3 更新整图与 Cutout 结果加载、测试夹具和公共读取调用,验证 Pack、色彩空间、标定和非有限值处理;删除旧参数和结果键。
|
||||
|
||||
## 2. 合并整图节点与入口
|
||||
|
||||
- [x] 2.1 将 Relief 与 Camera 组合为 O Image Depth Plane,增加 Mode 与统一接口;Relief 改读 B/Z,Camera 复用投影及平滑法线壳。
|
||||
- [x] 2.2 重排合并组的布局,更新构建入口、公开组清单与验证;删除独立 Surface 构建和布局入口,同步节点资产文档。
|
||||
- [x] 2.3 保留单一 ConvertToDepthPlane,删除独立 Surface 类、菜单、注册和对象类型分支,统一结果对象与默认值。
|
||||
|
||||
## 3. 回归验证
|
||||
|
||||
- [x] 3.1 使用 X/Y/Z 不同的纹理覆盖 Relief、Camera、Depth Cutout、Depth Balloon 和公共标量读取,验证各自位置、有效性及尺度。
|
||||
- [x] 3.2 覆盖模式切换无需推理且保留参数、Relief 固定底面、Camera 投影与法线厚度、矩形拓扑、UV、材质及临时属性清理。
|
||||
- [x] 3.3 更新注册与逆序注销、静态媒体和 AI 检查、成功替换与单次 Undo、失败清理测试,运行相关测试及必要的完整回归。
|
||||
- [x] 3.4 搜索生产代码中的旧文件名、结果键、模式分支和独立 Surface 入口,确认无兼容转发或残留消费路径。
|
||||
|
||||
## 4. 资产更新验收
|
||||
|
||||
- [x] 4.1 在资产更新阶段构建并验证 O_AnyImage.blend,以相同用例检查保存资产和构建定义的接口与两种模式求值。
|
||||
- [x] 4.2 在 Blender 节点编辑器检查总览及局部实际布局,确认主轴、分支顺序、间距、旁路和未用输出隐藏,记录视觉验收结果。
|
||||
|
||||
## 验证记录
|
||||
|
||||
- 已构建 O_AnyImage.blend,Blender 4.5.10 LTS 的资产、Mesh Plane、Cutout 验证通过。
|
||||
- 完整回归报告 746 passed、2 xfailed、60 subtests passed;pytest 完成后进程退出码为 1,与本变更前已记录的退出现象一致。随后清理了 3 个合并入口造成的重复测试。
|
||||
- 清理重复测试后的受影响范围回归:349 passed、30 subtests passed,退出码 0;覆盖保存资产与构建定义。
|
||||
- 视觉验收待完成:Computer Use 能捕获 Blender 启动画面,但激活、点击与 Escape 后界面均未变化,尚未进入节点编辑器。坐标与几何校验已通过,不能替代实际视觉验收。
|
||||
Reference in New Issue
Block a user