Help: Construct a material with a gradient diffuse texture

Hi guys, I am trying to bend my head around Rhino and it’s materials.
And even though I am able to add and remove materials I feel that I am missing something.

1- what is the difference between a sc.doc.Materials and and a sc.doc.RenderMaterials ?
2- what is the best and simplest way for me to add a material for Rhino 7 / 8?

What I need is a material with a gradient texture.

@nathanletwory I know I have asked you before, but I could not find nor navigate the answers. So sorry for being a bit thick, but it is a difficult thing to master :slight_smile:

sc.doc.Materials = oldskool, confusing, don’t use
sc.doc.RenderMaterials = modern, relatively sensible use

https://jesterking.github.io/rhipy/

Just put in the base color channel for PBR a gradient texture. Manual stuff: Creating a tinted gradient on a glass material in Rhino

1 Like

Thanks! That helps me in making a PBR (and I see we still have to convert that to a sc.doc.RenderMaterials.Add()

And I think I have made a gradient, but I don’t understand how I can put it somewhere, as pbr.BaseColor doesn’t accept it…

### MAKE PBR MATERIAL
### PBR generation by @nathanletwory

import Rhino as rh
import Rhino.Render as rr
import Rhino.DocObjects as rd
import scriptcontext as sc


def makeGradient():
    
    import Rhino
    import rhinoscriptsyntax as rs
    
    g = Rhino.Display.ColorGradient()
    
    colors = []
    colors.append(rs.coercecolor((255,0,0)))
    colors.append(rs.coercecolor((0,255,0)))
    colors.append(rs.coercecolor((0,0,255)))
    
    colorStops=[]
    
    for i in range(len(colors)):
        colorStops.append(Rhino.Display.ColorStop(colors[i], i / (colors.Count - 1.0)))
        g.SetColorStops(colorStops)
        #g.StartPoint = rs.coerce3dpoint((0,0,0))
        #g.EndPoint = rs.coerce3dpoint((100,0,0))
        g.GradientType = Rhino.Display.GradientType.Linear
    
    print g
    return g

### <<used guids>>
bitmap_texture_type_guid = rr.ContentUuids.BitmapTextureType
pbr_material_type_guid = rr.ContentUuids.PhysicallyBasedMaterialType

### <<create bitmap texture>>
bmtex = rr.RenderContentType.NewContentFromTypeId(bitmap_texture_type_guid)
bmtex.Filename = "C:\\Users\\Nathan\\Pictures\\uvtester.png"

simtex = bmtex.SimulatedTexture(rr.RenderTexture.TextureGeneration.Allow)


### <<create pbr material and jump through hoops>>
# first create an empty PBR material
pbr_rm = rr.RenderContentType.NewContentFromTypeId(pbr_material_type_guid)

# to get to a Rhino.DocObjects.PhysicallyBasedMaterial we need to simulate the
# render material first.
sim = pbr_rm.SimulatedMaterial(rr.RenderTexture.TextureGeneration.Allow)

# from the simulated material we can get the Rhino.DocObjects.PhysicallyBasedMaterial
pbr = sim.PhysicallyBased

### <<set PBR properties and texture>>
# now we have an instance of a type that has all the API you need to set the PBR
# properties. For simple glass we set color to white, opacity to 0 and opacity
# IOR to 1.52
pbr.Opacity = 0.0
pbr.OpacityIOR = 1.52
pbr.BaseColor = rh.Display.Color4f.White

### ----------------
### ADD GRADIENT BUT WHERE AND HOW TO PLACE IT?
gradient = makeGradient()
### ----------------


pbr.SetTexture(simtex.Texture(), rd.TextureType.PBR_BaseColor)

### <<convert into render material>>
# convert it back to RenderMaterial
new_pbr = rr.RenderMaterial.FromMaterial(pbr.Material, sc.doc)
# Set a good name
new_pbr.Name = "My Own PBR Glass"

# Add it to the document
sc.doc.RenderMaterials.Add(new_pbr)



OK, So I managed to swap out your bitmap texture with a gradient, but it ends up as a temporary bitmap texture instead of a Gradient texture.

Can I find a way so Gradient Texture is used instead, so that I can set the two colors?

Here is where I am at now:`
You can see my altered code under “HOLO”.
(PS! def makeGradient(): is not in use now)

### MAKE PBR MATERIAL
### PBR generation by @nathanletwory

import Rhino as rh
import Rhino.Render as rr
import Rhino.DocObjects as rd
import scriptcontext as sc

import Rhino

def makeGradient():
    
    import Rhino
    import rhinoscriptsyntax as rs
    
    g = Rhino.Display.ColorGradient()
    g.GradientType = Rhino.Display.GradientType.Linear
    
    colors = []
    colors.append(rs.coercecolor((255,0,0)))
    colors.append(rs.coercecolor((0,255,0)))
    colors.append(rs.coercecolor((0,0,255)))
    colorStops=[]
    
    for i in range(len(colors)):
        percent = i / (colors.Count - 1.0)
        colorStops.append(Rhino.Display.ColorStop(colors[i], percent))
    g.SetColorStops(colorStops)
    #g.StartPoint = rs.coerce3dpoint((0,0,0))
    #g.EndPoint = rs.coerce3dpoint((100,0,0))
    
    print dir(g)
    return g

### <<used guids>>
bitmap_texture_type_guid = rr.ContentUuids.BitmapTextureType
pbr_material_type_guid = rr.ContentUuids.PhysicallyBasedMaterialType

### <<create pbr material and jump through hoops>>
# first create an empty PBR material
pbr_rm = rr.RenderContentType.NewContentFromTypeId(pbr_material_type_guid)

# to get to a Rhino.DocObjects.PhysicallyBasedMaterial we need to simulate the
# render material first.
sim = pbr_rm.SimulatedMaterial(rr.RenderTexture.TextureGeneration.Allow)

# from the simulated material we can get the Rhino.DocObjects.PhysicallyBasedMaterial
pbr = sim.PhysicallyBased

### <<set PBR properties and texture>>
# now we have an instance of a type that has all the API you need to set the PBR
# properties. For simple glass we set color to white, opacity to 0 and opacity
# IOR to 1.52
pbr.Opacity = 1
pbr.OpacityIOR = 1.52
pbr.BaseColor = rh.Display.Color4f.White


### ----------------
### NATHAN
### <<create bitmap texture>>
#bmtex = rr.RenderContentType.NewContentFromTypeId(bitmap_texture_type_guid)
#bmtex.Filename = "C:\\Users\\Nathan\\Pictures\\uvtester.png"
#simtex = bmtex.SimulatedTexture(rr.RenderTexture.TextureGeneration.Allow)
#pbr.SetTexture(simtex.Texture(), rd.TextureType.PBR_BaseColor)

### HOLO
gradient_texture_type_guid = rr.ContentUuids.GradientTextureType
gradienttex = rr.RenderContentType.NewContentFromTypeId(gradient_texture_type_guid)
print dir(gradienttex)
simgrad = gradienttex.SimulatedTexture(rr.RenderTexture.TextureGeneration.Allow)
### ADD GRADIENT TO PBR
pbr.SetTexture(simgrad.Texture(), rd.TextureType.PBR_BaseColor)
### IT WORKS BUT TURNS OUT BLACK TO WHITE AND IS A BITMAP TEXTURE
### How can I 
### HOW CAN I CHANGE THOSE COLORS?
### ----------------


### <<convert into render material>>
# convert it back to RenderMaterial
new_pbr = rr.RenderMaterial.FromMaterial(pbr.Material, sc.doc)
# Set a good name
new_pbr.Name = "DTM_material"

# Add it to the document
sc.doc.RenderMaterials.Add(new_pbr)

``

You need to create a GradientTexture instead of a BitmapTexture. In my code I am using

rr.ContentUuids.BitmapTextureType

So instead of BitmapTextureType you need to look for GradientTextureType (ContentUuids.GradientTextureType Property).

Further you can use the SetParameter method on rendercontent to set values for parameters. To find out the names of the two color inputs you want to either save out a render texture to disk and open in a text editor, or use something like https://jesterking.github.io/rhipy/inspect_rendermaterial_parameters.html adapted for RenderTextures instead of RenderMaterials.

Thanks, but isn’t that what I do here?

### HOLO
gradient_texture_type_guid = rr.ContentUuids.GradientTextureType
gradienttex = rr.RenderContentType.NewContentFromTypeId(gradient_texture_type_guid)

Ah, I looked only at the top of the script :slight_smile: Better leave the unnecessary bits out so you and I don’t get confused.

But instead of doing the display color stops just set the parameters for the gradient texture gradienttex.SetParameter(....

1 Like

Thanks, I’ll try that.
Right now I am working on a UTM to NTM converter, but RhinoCode is biting me all the time, it’s buggy and struggles with rhinoscriptsyntax etc. Trying to be an early adopter isn’t easy, but it can be rewarding as heck!