- Implemented the "O Image Relief Plane" Geometry Nodes group to create a fixed-base image relief using depth images and various parameters. - Created the "O Shadeless" shader node group to display color without scene lighting while preserving shadows and reflections. - Introduced a preview feature for node groups, allowing for interactive visualization of node arrangements in an HTML format. - Added a template HTML file for rendering node previews with customizable views and controls.
89 lines
4.3 KiB
Python
89 lines
4.3 KiB
Python
"""Build O Image Layer."""
|
|
import bpy
|
|
from anyimage.common.material import IMAGE_MATERIAL_NODE_GROUP_NAME
|
|
from ..common.materials import build_material_nodes, connect_material_outputs
|
|
|
|
|
|
def build_image_layer_group():
|
|
group_name = IMAGE_MATERIAL_NODE_GROUP_NAME
|
|
existing = bpy.data.node_groups.get(group_name)
|
|
if existing is not None:
|
|
return existing
|
|
group = bpy.data.node_groups.new(group_name, 'ShaderNodeTree')
|
|
interface = group.interface
|
|
input_sockets = [('Color', 'NodeSocketColor'), ('Alpha', 'NodeSocketFloat'), ('Bump Scale', 'NodeSocketFloat')]
|
|
input_sockets.insert(2, ('Normal', 'NodeSocketColor'))
|
|
input_sockets.insert(3, ('Normal Scale', 'NodeSocketFloat'))
|
|
input_sockets.insert(4, ('Object Space', 'NodeSocketBool'))
|
|
input_sockets.insert(2, ('Alpha Fix', 'NodeSocketFloat'))
|
|
options = interface.new_panel(name='Options', default_closed=True)
|
|
option_names = {'Alpha Fix', 'Normal Scale', 'Object Space'}
|
|
for name, socket_type in input_sockets:
|
|
socket = interface.new_socket(name=name, in_out='INPUT', socket_type=socket_type, parent=options if name in option_names else None)
|
|
if name in {'Alpha', 'Alpha Fix'}:
|
|
socket.default_value = 1.0 if name == 'Alpha' else 0.0
|
|
socket.min_value = 0.0
|
|
socket.max_value = 1.0
|
|
socket.subtype = 'FACTOR'
|
|
elif name == 'Bump Scale':
|
|
socket.default_value = 0.0
|
|
socket.min_value = -10000.0
|
|
socket.max_value = 10000.0
|
|
elif name == 'Normal':
|
|
socket.default_value = (0.5, 0.5, 1.0, 1.0)
|
|
elif name == 'Normal Scale':
|
|
socket.default_value = 1.0
|
|
socket.min_value = 0.0
|
|
socket.max_value = 10.0
|
|
elif name == 'Object Space':
|
|
socket.default_value = False
|
|
output_sockets = [('Color', 'NodeSocketColor'), ('Roughness', 'NodeSocketFloat'), ('Alpha', 'NodeSocketFloat'), ('Normal', 'NodeSocketVector')]
|
|
for name, socket_type in output_sockets:
|
|
interface.new_socket(name=name, in_out='OUTPUT', socket_type=socket_type)
|
|
nodes, links = group.nodes, group.links
|
|
group_input, group_output, roughness_curve, bump = build_material_nodes(group)
|
|
tangent_normal = nodes.new('ShaderNodeNormalMap')
|
|
tangent_normal.space = 'TANGENT'
|
|
tangent_normal.location = (-500.0, -100.0)
|
|
object_normal = nodes.new('ShaderNodeNormalMap')
|
|
object_normal.space = 'OBJECT'
|
|
object_normal.location = (-500.0, -350.0)
|
|
choose_normal = nodes.new('ShaderNodeMix')
|
|
choose_normal.data_type = 'VECTOR'
|
|
choose_normal.location = (-150.0, -150.0)
|
|
for normal_map in (tangent_normal, object_normal):
|
|
links.new(group_input.outputs['Normal'], normal_map.inputs['Color'])
|
|
links.new(group_input.outputs['Normal Scale'], normal_map.inputs['Strength'])
|
|
links.new(group_input.outputs['Object Space'], choose_normal.inputs[0])
|
|
links.new(tangent_normal.outputs['Normal'], choose_normal.inputs[4])
|
|
links.new(object_normal.outputs['Normal'], choose_normal.inputs[5])
|
|
links.new(choose_normal.outputs['Result'], bump.inputs['Normal'])
|
|
processed_alpha = group_input.outputs['Alpha']
|
|
alpha_curve = nodes.new('ShaderNodeFloatCurve')
|
|
alpha_curve.mapping.initialize()
|
|
alpha_curve.mapping.extend = 'HORIZONTAL'
|
|
alpha_curve.mapping.use_clip = True
|
|
alpha_points = alpha_curve.mapping.curves[0].points
|
|
alpha_points[0].location = (0.0, 0.0)
|
|
alpha_points[-1].location = (1.0, 1.0)
|
|
alpha_points.new(0.8, 0.0)
|
|
alpha_points.new(0.925, 0.925)
|
|
for point in alpha_points:
|
|
point.handle_type = 'AUTO_CLAMPED'
|
|
alpha_curve.mapping.update()
|
|
group_input.location = (-750.0, 150.0)
|
|
group_output.location = (350.0, 450.0)
|
|
alpha_curve.location = (-350.0, 1100.0)
|
|
roughness_curve.location = (-350.0, 650.0)
|
|
links.new(group_input.outputs['Alpha'], alpha_curve.inputs['Value'])
|
|
links.new(group_input.outputs['Alpha Fix'], alpha_curve.inputs['Factor'])
|
|
processed_alpha = alpha_curve.outputs['Value']
|
|
connect_material_outputs(group, group_input, group_output, roughness_curve, bump, processed_alpha, (-250.0, 150.0))
|
|
group.color_tag = 'SHADER'
|
|
group.description = f'Prepare {group_name} material outputs.'
|
|
group.use_fake_user = True
|
|
for node in nodes:
|
|
for socket in node.outputs:
|
|
socket.hide = not socket.is_linked
|
|
return group
|