- 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.
78 lines
3.1 KiB
Python
78 lines
3.1 KiB
Python
"""Build the Shadeless shader node group."""
|
|
|
|
import bpy
|
|
|
|
|
|
SHADELESS_GROUP_NAME = "O Shadeless"
|
|
|
|
|
|
def build_shadeless_group():
|
|
group = bpy.data.node_groups.new(SHADELESS_GROUP_NAME, "ShaderNodeTree")
|
|
group.interface.new_socket(
|
|
name="Shader", in_out="OUTPUT", socket_type="NodeSocketShader"
|
|
)
|
|
group.interface.new_socket(
|
|
name="Color", in_out="INPUT", socket_type="NodeSocketColor"
|
|
)
|
|
nodes = group.nodes
|
|
links = group.links
|
|
group_input = nodes.new("NodeGroupInput")
|
|
group_input.location = (-900.0, -350.0)
|
|
group_output = nodes.new("NodeGroupOutput")
|
|
group_output.location = (850.0, 100.0)
|
|
|
|
diffuse = nodes.new("ShaderNodeBsdfDiffuse")
|
|
diffuse.location = (250.0, -150.0)
|
|
emission = nodes.new("ShaderNodeEmission")
|
|
emission.location = (250.0, -400.0)
|
|
links.new(group_input.outputs["Color"], diffuse.inputs["Color"])
|
|
links.new(group_input.outputs["Color"], emission.inputs["Color"])
|
|
|
|
light_path = nodes.new("ShaderNodeLightPath")
|
|
light_path.location = (-900.0, 150.0)
|
|
bounce_count = nodes.new("ShaderNodeMath")
|
|
bounce_count.operation = "SUBTRACT"
|
|
bounce_count.location = (-500.0, -50.0)
|
|
links.new(light_path.outputs["Ray Depth"], bounce_count.inputs[0])
|
|
links.new(light_path.outputs["Transmission Depth"], bounce_count.inputs[1])
|
|
refracted = nodes.new("ShaderNodeMath")
|
|
refracted.operation = "SUBTRACT"
|
|
refracted.inputs[0].default_value = 1.0
|
|
refracted.location = (-250.0, -50.0)
|
|
links.new(bounce_count.outputs[0], refracted.inputs[1])
|
|
|
|
reflection_limit = nodes.new("ShaderNodeMath")
|
|
reflection_limit.operation = "SUBTRACT"
|
|
reflection_limit.inputs[0].default_value = 2.0
|
|
reflection_limit.location = (-650.0, 450.0)
|
|
links.new(light_path.outputs["Ray Depth"], reflection_limit.inputs[1])
|
|
camera_reflected = nodes.new("ShaderNodeMath")
|
|
camera_reflected.operation = "MULTIPLY"
|
|
camera_reflected.location = (-400.0, 400.0)
|
|
links.new(reflection_limit.outputs[0], camera_reflected.inputs[0])
|
|
links.new(light_path.outputs["Is Glossy Ray"], camera_reflected.inputs[1])
|
|
shadow_or_reflect = nodes.new("ShaderNodeMath")
|
|
shadow_or_reflect.operation = "MAXIMUM"
|
|
shadow_or_reflect.location = (-100.0, 350.0)
|
|
links.new(camera_reflected.outputs[0], shadow_or_reflect.inputs[0])
|
|
links.new(light_path.outputs["Is Shadow Ray"], shadow_or_reflect.inputs[1])
|
|
shader_factor = nodes.new("ShaderNodeMath")
|
|
shader_factor.operation = "MAXIMUM"
|
|
shader_factor.location = (150.0, 300.0)
|
|
links.new(shadow_or_reflect.outputs[0], shader_factor.inputs[0])
|
|
links.new(refracted.outputs[0], shader_factor.inputs[1])
|
|
|
|
mix = nodes.new("ShaderNodeMixShader")
|
|
mix.location = (550.0, 100.0)
|
|
links.new(shader_factor.outputs[0], mix.inputs["Fac"])
|
|
links.new(diffuse.outputs["BSDF"], mix.inputs[1])
|
|
links.new(emission.outputs["Emission"], mix.inputs[2])
|
|
links.new(mix.outputs["Shader"], group_output.inputs["Shader"])
|
|
group.color_tag = "SHADER"
|
|
group.description = (
|
|
"Display color without scene lighting while preserving shadows "
|
|
"and reflections."
|
|
)
|
|
group.use_fake_user = True
|
|
return group
|