feat(cutout): implement boundary padding for cutout textures
- Introduced a new `Boundary Padding` preference in the Cutout Tool with a default of 2 px and a configurable range of 1-4 px. - Updated the Cutout client to establish inward mapping from the final Mask, sampling in a fixed direction and processing independent material RGBA and Depth. - Enhanced the handling of RGBA and Depth during cutout operations, ensuring proper mapping and preservation of source data. - Added tests to validate the new boundary padding functionality and its integration with existing cutout processes. feat(geometry): remove overall mesh smoothing from geometry nodes - Removed the `Smooth` input from several geometry node groups to eliminate unnecessary overall mesh smoothing. - Retained `Smooth Weight` for depth nodes while removing it from Cutout and Relief Plane nodes. - Ensured that boundary, normal, and fill smoothing behaviors remain intact and consistent. - Updated tests and documentation to reflect the changes in node interfaces and behaviors. feat(normals): scale tangent normals with depth - Reused the existing `o_normal_reduction` attribute to adjust Tangent Normal strength based on the geometry's `Depth Scale`. - Ensured that Tangent Normal strength is consistent with the geometry depth, preserving full strength for materials that do not provide the attribute. - Updated tests to verify the correct behavior of normal strength adjustments in both Tangent and Object Space.
This commit is contained in:
@@ -8,6 +8,59 @@ from anyimage.common import material as material_data
|
||||
from tests.support.image_objects import _create_cutout_shape, _group_node
|
||||
|
||||
|
||||
def test_generated_materials_use_implicit_uv_and_readable_layout():
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
source = SimpleNamespace(name="Source")
|
||||
color = bpy.data.images.new("Color", width=4, height=2)
|
||||
normal = bpy.data.images.new("Normal", width=4, height=2)
|
||||
depth = bpy.data.images.new("Depth", width=4, height=2)
|
||||
|
||||
material = material_data.create_image_material(source, color, normal_image=normal)
|
||||
nodes = material.node_tree.nodes
|
||||
assert not any(node.bl_idname == "ShaderNodeUVMap" for node in nodes)
|
||||
assert all(not node.inputs["Vector"].is_linked for node in nodes if node.type == "TEX_IMAGE")
|
||||
texture_location = lambda image: tuple(next(
|
||||
node for node in nodes if node.type == "TEX_IMAGE" and node.image == image
|
||||
).location)
|
||||
assert texture_location(color) == (-700.0, 300.0)
|
||||
assert texture_location(normal) == (-700.0, 0.0)
|
||||
assert tuple(next(node for node in nodes if node.type == "GROUP").location) == (-300.0, 300.0)
|
||||
assert tuple(next(node for node in nodes if node.type == "BSDF_PRINCIPLED").location) == (100.0, 300.0)
|
||||
assert tuple(next(node for node in nodes if node.type == "OUTPUT_MATERIAL").location) == (500.0, 300.0)
|
||||
|
||||
depth_material = material_data.create_image_material(
|
||||
source,
|
||||
color,
|
||||
displacement_image=depth,
|
||||
displacement_midlevel=0.5,
|
||||
displacement_scale=2.0,
|
||||
)
|
||||
nodes = depth_material.node_tree.nodes
|
||||
assert not any(node.bl_idname == "ShaderNodeUVMap" for node in nodes)
|
||||
assert all(not node.inputs["Vector"].is_linked for node in nodes if node.type == "TEX_IMAGE")
|
||||
depth_texture = next(node for node in nodes if node.type == "TEX_IMAGE" and node.image == depth)
|
||||
assert tuple(depth_texture.location) == (-1200.0, -300.0)
|
||||
math_locations = {node.operation: tuple(node.location) for node in nodes if node.type == "MATH"}
|
||||
assert math_locations == {
|
||||
"SUBTRACT": (-950.0, -300.0),
|
||||
"MULTIPLY": (-700.0, -300.0),
|
||||
}
|
||||
|
||||
panorama = material_data.create_image_material(
|
||||
source, color, shadeless=True, texture_extension="REPEAT")
|
||||
nodes = panorama.node_tree.nodes
|
||||
assert not any(node.bl_idname in {
|
||||
"ShaderNodeUVMap", "ShaderNodeSeparateXYZ", "ShaderNodeClamp", "ShaderNodeCombineXYZ",
|
||||
} for node in nodes)
|
||||
texture = next(node for node in nodes if node.type == "TEX_IMAGE")
|
||||
shader = next(node for node in nodes if node.type == "GROUP")
|
||||
output = next(node for node in nodes if node.type == "OUTPUT_MATERIAL")
|
||||
assert not texture.inputs["Vector"].is_linked
|
||||
assert texture.extension == "REPEAT"
|
||||
assert (tuple(texture.location), tuple(shader.location), tuple(output.location)) == (
|
||||
(-700.0, 300.0), (-300.0, 300.0), (100.0, 300.0))
|
||||
|
||||
|
||||
def test_image_layer_switches_between_tangent_and_object_space_normal():
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user