feat(node_assets): add image plane geometry nodes and validation scripts

- Implemented `image_plane.py` to build the Image Plane Geometry Nodes group with customizable parameters for geometry, subdivide, and thickness.
- Created `image_plane_validation.py` to validate the functionality of the image plane, ensuring correct geometry generation and material assignment.
- Developed `material_layers.py` to construct shader node groups for image materials, including depth and normal handling.
- Authored `plane_layouts.py` to define node arrangements for image geometry assets.
- Introduced `shadeless.py` to create a shadeless shader node group that displays color without scene lighting while preserving shadows and reflections.
This commit is contained in:
2026-09-08 23:24:27 +08:00
parent 196b964efc
commit 4c902ed7db
155 changed files with 9700 additions and 10393 deletions

View File

@@ -71,12 +71,12 @@ def _write_float_exr(rgba, output_path):
return output_path
def write_vector_depth_texture(frame, output_path):
def write_depth_texture(frame, output_path):
"""Write a frame's camera-space XYZ and validity as float RGBA."""
import numpy as np
if frame.points is None:
raise ValueError("Vector depth requires a point field")
raise ValueError("Depth requires a point field")
points = np.asarray(frame.points, dtype=np.float32)
validity = np.asarray(frame.validity, dtype=np.float32)
if not np.isfinite(points).all():
@@ -87,20 +87,6 @@ def write_vector_depth_texture(frame, output_path):
return _write_float_exr(rgba, output_path)
def write_z_depth_texture(frame, output_path):
"""Write a frame's camera Z and validity as float RGBA."""
import numpy as np
depth = np.asarray(frame.depth, dtype=np.float32)
validity = np.asarray(frame.validity, dtype=np.float32)
if not np.isfinite(depth).all():
raise ValueError("Depth field contains non-finite values")
rgba = np.empty((*depth.shape, 4), dtype=np.float32)
rgba[..., :3] = depth[..., None]
rgba[..., 3] = validity
return _write_float_exr(rgba, output_path)
def write_depth_metadata(frame, reference_valid, output_path):
"""Write camera values needed to scale a model-space depth texture."""
import numpy as np

View File

@@ -65,5 +65,3 @@ def write_camera_normal_texture(
output_path = Path(output_path)
full.save(output_path)
return output_path

View File

@@ -4,8 +4,7 @@ from ..media import DEFAULT_MAX_AI_INPUT_SIZE, limit_image
from ..models import moge2
from .depth_texture import (
write_depth_metadata,
write_vector_depth_texture,
write_z_depth_texture,
write_depth_texture,
)
from .normal_texture import write_camera_normal_texture
from .edge_depth import extend_edge_depth
@@ -57,16 +56,13 @@ def generate_moge2_artifacts(
parameters,
input_path,
*,
depth_mode="NONE",
generate_depth=False,
normal_mode="NONE",
correct_edge_depth=False,
alpha_threshold=0.9,
):
"""Run MoGe-2 once and write only the requested file artifacts."""
depth_mode = str(depth_mode).upper()
normal_mode = str(normal_mode).upper()
if depth_mode not in {"NONE", "VECTOR", "Z"}:
raise ValueError(f"Unsupported depth mode: {depth_mode}")
if normal_mode not in {"NONE", "TANGENT", "OBJECT"}:
raise ValueError(f"Unsupported normal mode: {normal_mode}")
model_path = _limited_model_input(
@@ -79,32 +75,23 @@ def generate_moge2_artifacts(
context.resource("model_manager"),
parameters,
[model_path],
include_points=depth_mode == "VECTOR",
include_points=generate_depth,
cancel_check=context.check_cancelled,
)
if len(frames) != 1:
raise ValueError("Artifact generation requires one geometry frame")
frame = frames[0]
result = {}
if depth_mode != "NONE":
if generate_depth:
context.progress(0.45, "Generating depth texture")
alpha = _image_alpha(input_path, frame.depth.shape)
depth_frame = (
extend_edge_depth(frame, alpha, alpha_threshold)
if correct_edge_depth else frame
)
if depth_mode == "VECTOR":
depth_path = write_vector_depth_texture(
depth_frame,
context.directory / "vector-depth.exr",
)
result["vector_depth"] = depth_path
else:
depth_path = write_z_depth_texture(
depth_frame,
context.directory / "z-depth.exr",
)
result["z_depth"] = depth_path
result["depth"] = write_depth_texture(
depth_frame, context.directory / "depth.exr",
)
result["depth_metadata"] = write_depth_metadata(
depth_frame,
(alpha > 0.0) & (alpha >= alpha_threshold)