Asset-Frameworker/ProjectNotes/BLENDER_MATERIAL_MERGE_ADDON_PLAN.md
2025-04-29 18:26:13 +02:00

6.4 KiB

Blender Addon Plan: Material Merger

Version: 1.1 (Includes Extensibility Consideration)

1. Goal: Create a standalone Blender addon that allows users to select two existing materials (generated by the Asset Processor Tool, or previously merged by this addon) and merge them into a new material. The merge should preserve their individual node structures (including custom tweaks) and combine their final outputs using a dedicated MaterialMerge node group.

2. Core Functionality (Approach 2 - Node Copying):

  • Trigger: User selects two materials in Blender and invokes an operator (e.g., via a button in the Shader Editor's UI panel).
  • New Material Creation: The addon creates a new Blender material, named appropriately (e.g., MAT_Merged_<NameA>_<NameB>).
  • Node Copying:
    • For each selected source material:
      • Iterate through its node tree.
      • Copy all nodes except the Material Output node into the new material's node tree, attempting to preserve relative layout and offsetting subsequent copies.
      • Identify Final Outputs: Determine the node providing the final BSDF shader output and the node providing the final Displacement output before the original Material Output node.
        • In a base material (from Asset Processor), these are expected to be the PBR_BSDF node group (BSDF output) and the PBR_Handler node group (Displacement output).
        • In an already-merged material, these will be the outputs of its top-level MaterialMerge node group.
      • Store references to these final output nodes and their relevant sockets.
  • MaterialMerge Node:
    • Link/Append the MaterialMerge node group into the new material's node tree.
    • Assumption: This node group exists in blender_files/utility_nodegroups.blend relative to the addon's location.
    • Assumption: Socket names are Shader A, Shader B, Displacement A, Displacement B (inputs) and BSDF, Displacement (outputs).
  • Connections:
    • Connect the identified final BSDF output of the first source material's copied structure to the MaterialMerge node's Shader A input.
    • Connect the identified final Displacement output of the first source material's copied structure to the MaterialMerge node's Displacement A input.
    • Connect the identified final BSDF output of the second source material's copied structure to the MaterialMerge node's Shader B input.
    • Connect the identified final Displacement output of the second source material's copied structure to the MaterialMerge node's Displacement B input.
    • Connect the MaterialMerge node's BSDF output to the new material's Material Output node's Surface input.
    • Connect the MaterialMerge node's Displacement output to the new material's Material Output node's Displacement input.
  • Layout: Optionally, attempt a basic auto-layout (node_tree.nodes.update()) or arrange the key nodes logically.

3. User Interface (UI):

  • A simple panel in the Blender Shader Editor (Properties region - 'N' panel).
  • Two dropdowns or search fields allowing the user to select existing materials from the current .blend file.
  • A button labeled "Merge Selected Materials".
  • Status messages/feedback (e.g., "Merged material created: [Name]", "Error: Could not find required nodes in [Material Name]").

4. Addon Structure (Python):

  • __init__.py: Registers the addon, panel, and operator classes.
  • operator.py: Contains the OT_MergeMaterials operator class implementing the core logic.
  • panel.py: Contains the PT_MaterialMergePanel class defining the UI layout.
  • (Optional) utils.py: Helper functions for node finding, copying, linking, identifying final outputs, etc.

5. Error Handling:

  • Check if two valid materials are selected.
  • Verify that the selected materials have node trees.
  • Handle cases where the expected final BSDF/Displacement output nodes cannot be reliably identified in one or both source materials.
  • Handle potential errors during node copying.
  • Handle errors if the utility_nodegroups.blend file or the MaterialMerge node group within it cannot be found/linked.

6. Assumptions to Verify (Based on User Feedback):

  • Node Identification:
    • Base Material Handler: Node named PBR_Handler.
    • Base Material BSDF: Node named PBR_BSDF.
    • Merged Material Outputs: The BSDF and Displacement outputs of the top-level MaterialMerge node.
  • MaterialMerge Node:
    • Location: blender_files/utility_nodegroups.blend (relative path).
    • Input Sockets: Shader A, Shader B, Displacement A, Displacement B.
    • Output Sockets: BSDF, Displacement.

7. Future Extensibility - Recursive Merging:

  • The core merging logic (copying nodes, identifying final outputs, connecting to a new MaterialMerge node) is designed to inherently support selecting an already-merged material as an input without requiring separate code paths initially. The identification of final BSDF/Displacement outputs needs to correctly handle both base materials and merged materials (checking for PBR_BSDF/PBR_Handler or the outputs of an existing MaterialMerge node).

8. Mermaid Diagram of Node Flow:

graph TD
    subgraph New Merged Material
        subgraph Copied from Source A (Mat_A or Merge_A)
            %% Nodes representing the structure of Source A
            Structure_A[...]
            Final_BSDF_A[Final BSDF Output A]
            Final_Disp_A[Final Displacement Output A]
            Structure_A --> Final_BSDF_A
            Structure_A --> Final_Disp_A
        end

        subgraph Copied from Source B (Mat_B or Merge_B)
            %% Nodes representing the structure of Source B
            Structure_B[...]
            Final_BSDF_B[Final BSDF Output B]
            Final_Disp_B[Final Displacement Output B]
            Structure_B --> Final_BSDF_B
            Structure_B --> Final_Disp_B
        end

        Merge[MaterialMerge]
        Output[Material Output]

        Final_BSDF_A -- BSDF --> Merge -- Shader A --> Merge
        Final_Disp_A -- Displacement --> Merge -- Displacement A --> Merge
        Final_BSDF_B -- BSDF --> Merge -- Shader B --> Merge
        Final_Disp_B -- Displacement --> Merge -- Displacement B --> Merge

        Merge -- BSDF --> Output -- Surface --> Output
        Merge -- Displacement --> Output -- Displacement --> Output
    end