How to correctly construct a PBR Material?

The PhysicallyBasedMaterial class doesn’t have a constructor and if I create a normal Material and call Default() and then ToPhysicallyBased() it also doesn’t seem to do anything:

In Rhino it then looks like this:

Is there any way to enforce or construct a correct PhysicallyBasedMaterial instance in Rhino3dm via code?

Hi @tebjan,

I’m sure there is no way of creating these with rhino3dm. I’ve logged a wish for this.

https://mcneel.myjetbrains.com/youtrack/issue/RH3DM-150

– Dale

Thanks for the answer. But here is this Material.ToPhysicallyBased() but it seems to be broken. Maybe that just needs a bug fix?

This project is related to these two requests:

Would be nice if you could link these together… Thanks!

Remind me in which language you are using rhino3dm?
I recently wrapped toPhysicallyBased() for js and py. I don’t recall when it was added for dotnet. In js you would do something like:

const redMaterial = new rhino.Material()
redMaterial.toPhysicallyBased()
redMaterial.physicallyBased().baseColor = { r: 1, g: 0, b: 0, a: 0 }
redMaterial.physicallyBased().metallic = 0.7
redMaterial.physicallyBased().roughness = 0.5
doc.materials().add(redMaterial)

I have not released a beta with this yet for js and py. If you need it for js and py, you can get a ci version here (next 15 days): rhino3dm ci

I am using C#. I think it isn’t wrapped correctly or is just missing…

In c# I can do this:

Rhino.FileIO.File3dm file3dm = new Rhino.FileIO.File3dm();

var material = new Rhino.DocObjects.Material();
material.ToPhysicallyBased();
material.PhysicallyBased.BaseColor = new Rhino.Display.Color4f(1, 0, 0, 0);
material.PhysicallyBased.Metallic = 0.7;
material.PhysicallyBased.Roughness = 0.5;
file3dm.AllMaterials.Add(material);

var oa = new Rhino.DocObjects.ObjectAttributes
{
    MaterialIndex = 0,
    MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject
};

var sphere = new Rhino.Geometry.Sphere(Rhino.Geometry.Point3d.Origin, 10);
file3dm.Objects.AddSphere(sphere, oa);

file3dm.Write("fileWithMaterial.3dm", null);

How would you add a texture to that PBR? I see a few different methods in the forum and this looks like a simpler/newer method.

Just returning to answer my own question for anyone else wondering after tinkering all day, merging bits of this post with this (some bits of that post seem no longer relevant? or maybe just for python):

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

I got this working:

using Rhino;
using Rhino.Render;

RhinoDoc doc = RhinoDoc.ActiveDoc;

// Create new Rhino material and convert to PBR
var rMaterial = new Rhino.DocObjects.Material();
rMaterial.ToPhysicallyBased();

// Create simulated texture from image path
SimulatedTexture simtex = new SimulatedTexture(doc);
simtex.Filename = “C:\Users\tsrch\Documents\test.jpg”;

// Assign texture to base color
rMaterial.PhysicallyBased.SetTexture(simtex.Texture(), Rhino.DocObjects.TextureType.PBR_BaseColor);

// Convert to RenderMaterial and add to document, this allows the material to show in the material editor
// without being assigned to any objects
var pbr = RenderMaterial.FromMaterial(rMaterial, doc);
pbr.Name = “testo”;
doc.RenderMaterials.Add(pbr);