Modify Rhino PBR Material With GH Python Component

Hello,

I’m using the new Rhino 8 Material nodes to create custom materials from within GH but the features missing are being able to control the Roughness, Opacity/Transparency of said materials.

I am attempting to create a python node that modifies a PBR material from within GH but stuck with the method to actually find the referenced material.

You can see below I’m taking a new model material, getting its ID, and giving that to python to then find that material and set Material Attributes from my python inputs (color, sliders, etc). (Or at least this is what I am trying to create.

Here’s a snip of the graph:

Here’s the baked result (Roughness always gets set to 100):

Here’s the intended result (Roughness gets set to user defined value from GH):

The “Create Material” component can influence the opacity from GH but cannot influence Roughness

Here is the code thus far:

import random
import Rhino
import scriptcontext as sc
import rhinoscriptsyntax as rs
import Rhino.Render as rr
import System.Drawing as sd

def set_material_parameters(material_name, diffuse, roughness, opacity):
    rhino_doc = sc.doc
    render_materials = rhino_doc.RenderMaterials
    
    material_index = None
    for i in range(render_materials.Count):
        material = render_materials[i]
        if material.Name == material_name:
            material_index = i
            break
    
    if material_index is not None:
        # Get the current material name
        current_name = rs.MaterialName(material_index)
        
        # Set the new material name
        previous_name = rs.MaterialName(material_index, "Your New Material Name")
        
        material = render_materials[material_index]
        
        material.BeginChange(rr.RenderContent.ChangeContexts.Program)
        
        # Set diffuse color
        material.SetParameter("diffuse", sd.Color.FromArgb(diffuse[0], diffuse[1], diffuse[2]))
        
        # Set roughness
        material.SetParameter("roughness", roughness)
        
        # Set opacity
        material.SetParameter("opacity", opacity)
        
        material.EndChange()
    else:
        print("Material not found!")

# Input parameters
material_name = "Your Material Name"  # Input material name as a string
diffuse = Diffuse
roughness = Roughness
opacity = Opacity

#print diffuse
#print roughness
#print opacity

set_material_parameters(material_name, diffuse, roughness, opacity)

Thank you for your help and any leads! Always appreciated!

1 Like

maybe some code in this will be helpful:

2 Likes

Thank you, this looks like it is probably what I am after. I look forward to taking a look. Are UVW properties exposed?

I thought I recall Human having a UVW mapping series of nodes but I don’t recall seeing UVW methods in the Python API, maybe I’m looking in the wrong places…

Thanks for your lead and help on this!

it depends what you mean by uvw properties – basically, if a render content uses its fields for data, the python in that will allow you to expose and connect them (you will notice it is the same python code in both of the example nodes, it does not care whether it is dealing with material, texture, or environment)

looking at the xml for a 2d checker texture, if I switch the mapping from mapping channel → wcs box style, I see that the value of rdk-texture-projection-mode has changed from 0 to 4, if this is what you are looking for

edit: forgot that field is already hooked up in the example, which is also a 2d checker

image

1 Like

This makes sense thanks for clarifying. Yes, that is the mapping option with the material properties itself.

I think I will dig into some other code to expose the Object Properties UVW mapping. This is the little checkerboard icon on one of the object properties tabs, it lets you set Box, Spherical, Unwrap, etc.

I don’t think this lives in the shader XML data to my knowledge

correct, for that you are looking at RhinoObject

image

1 Like

Very helpful thank you so much!

1 Like

sure thing, best of luck :+1:

2 Likes

I realize you didn’t create this with the intent of working inside of Rhino 8 WIP but I’m curious if you have any insights on the following content:

I am using the new Rhino 8 nodes to query the PBR material and bake it with the sphere objects to test. It seems to generally be working correctly since the baker is just grabbing the PBR material from the Rhino Doc.

Top spheres are baked objects, bottom are the custom preview referenced GH spheres from your original example.

You can see that the objects do in fact have the PBR mat applied but show white in “Rendered Mode”

Here is the same view in Raytraced mode (showing correctly):

What is odd is that it appears once I have baked an object with the PBR material, any edits I make with the python script after that get ignored until I change the viewport display mode (and then change it back).

Note the purple diffuse color, yet the spheres still show Blue, even on the custom preview node.

Here’s a video showing the difference in rendered mode and how switching the viewport display mode seems to “refresh” the visuals of the material (which is odd? to me)

Video Showing Display Mode Behavior

I’ll continue to dig into it and see what could be causing the issue.

Any insight is greatly appreciated, thank you!

try adding these lines

image

here, that gets things updated correctly in v7, in rendered or raytraced view, and also in the material editor

in v8 it seems to get everything working except for the baked objects, the material of which does not respond to changes, and just stays however it was when raytraced was enabled – this seems to be a render queue (the rhino sdk api used by renderers to implement realtime display modes) issue, as the behavior is identical in my renderer as well

That worked! I really appreciate your help @jdhill! I’m mostly utilizing rendered mode anyways and then using third party renderers for anything beyond that so this implementation is perfect! Thanks again!

1 Like