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

@@ -1,5 +1,5 @@
"""Construct the planar and depth-based Cutout shape stages."""
from cutout_depth_surface import store_surface_camera, remove_surface_attributes, split_depth_surface, thicken_depth_surface
from depth_surface import project_depth_surface, store_surface_camera, remove_surface_attributes, split_depth_surface, thicken_depth_surface
from anyimage.operators.cutout_tool.shape import BALLOON_ATTRIBUTE_NAME
@@ -561,53 +561,11 @@ def _build_depth_surface(
geometry, camera_position = store_surface_camera(
group, geometry, original_camera, split
)
scaled = nodes.new("ShaderNodeVectorMath")
scaled.operation = "SCALE"
scaled.location = (3100.0, -100.0)
links.new(camera_position, scaled.inputs[0])
links.new(uniform_scale, scaled.inputs[3])
separate = nodes.new("ShaderNodeSeparateXYZ")
separate.location = (3300.0, -100.0)
links.new(scaled.outputs["Vector"], separate.inputs["Vector"])
relative_depth = _math(nodes, "SUBTRACT", (3500.0, -100.0))
links.new(reference_depth, relative_depth.inputs[0])
links.new(separate.outputs["Z"], relative_depth.inputs[1])
front = _math(nodes, "MULTIPLY", (3700.0, -100.0))
links.new(relative_depth.outputs[0], front.inputs[0])
links.new(depth_scale, front.inputs[1])
negative_y = _math(nodes, "MULTIPLY", (3500.0, -600.0))
negative_y.inputs[1].default_value = -1.0
links.new(separate.outputs["Y"], negative_y.inputs[0])
projected = nodes.new("ShaderNodeCombineXYZ")
projected.location = (3700.0, -450.0)
links.new(separate.outputs["X"], projected.inputs["X"])
links.new(negative_y.outputs[0], projected.inputs["Y"])
current_position = nodes.new("GeometryNodeInputPosition")
current_position.location = (3500.0, -850.0)
blend = nodes.new("ShaderNodeMix")
blend.data_type = "VECTOR"
blend.clamp_factor = False
blend.location = (3900.0, -450.0)
links.new(depth_scale, blend.inputs[0])
links.new(current_position.outputs["Position"], blend.inputs[4])
links.new(projected.outputs["Vector"], blend.inputs[5])
blended_axes = nodes.new("ShaderNodeSeparateXYZ")
blended_axes.location = (4100.0, -500.0)
links.new(blend.outputs["Result"], blended_axes.inputs["Vector"])
surface_position = nodes.new("ShaderNodeCombineXYZ")
surface_position.location = (4100.0, -200.0)
links.new(blended_axes.outputs["X"], surface_position.inputs["X"])
links.new(blended_axes.outputs["Y"], surface_position.inputs["Y"])
links.new(front.outputs[0], surface_position.inputs["Z"])
project_geometry = nodes.new("GeometryNodeSetPosition")
project_geometry.location = (4400.0, 400.0)
links.new(geometry, project_geometry.inputs["Geometry"])
links.new(surface_position.outputs["Vector"], project_geometry.inputs["Position"])
geometry = project_geometry.outputs["Geometry"]
geometry = project_depth_surface(
group, geometry, camera_position, uniform_scale, reference_depth, depth_scale
)
shaped = thicken_depth_surface(group, geometry, thickness)
geometry = _remove_zero_thickness(
group, project_geometry.outputs["Geometry"], shaped, thickness, (11800.0, 400.0)
group, geometry, shaped, thickness, (11800.0, 400.0)
)
return remove_surface_attributes(group, geometry)