Physically Based Material in Headless doc

Hi everyone,

I am facing an issue when trying to export a GLTF file from C#, with a custom PBR (Physically Based) material.

When I create a PBR material outside from compute, it works fine. But as soon as I try it over compute, somehow the PBR settings are lost. Am I missing something ?

I attach the gh definition.

My end goal is to export a GLTF file with a custom PBR Render Material assigned to a given geometry.

@AndyPayne this is one of the topics I would need help on.

rendermat.gh (9.4 KB)

image

var doc = RhinoDoc.CreateHeadless(null);

//Setup material
var matId = doc.Materials.Add(new Rhino.DocObjects.Material());
var addedMat = doc.Materials[matId];

addedMat.DiffuseColor = System.Drawing.Color.Aqua;
addedMat.ToPhysicallyBased();
Rhino.DocObjects.PhysicallyBasedMaterial pbrMat = addedMat.PhysicallyBased;
pbrMat.Clearcoat = 1.0;
pbrMat.ClearcoatRoughness = 0.2;
pbrMat.Roughness = 0.2;

//Beginning of headache :)

//Option 1 : works but not via compute
Rhino.Render.RenderMaterial mat = addedMat.RenderMaterial; // a is null when executed on compute (NullReference)
ok = mat != null; //false when executed on compute

//Option 2 (render material is valid, but PBR parameters like roughness are lost in the process)
Rhino.Render.RenderMaterial mat2 = Rhino.Render.RenderMaterial.CreateBasicMaterial(
    pbrMat.Material,
    doc
);
ok2 = mat2 != null; //true on compute

//Option 3 (render material is valid, but PBR parameters like roughness are lost in the process)
Rhino.Render.RenderMaterial mat3 = Rhino.Render.RenderMaterial.CreateImportedMaterial(
    pbrMat.Material,
    doc,
    false
);
ok3 = mat3 != null; //true on compute

//Option 4a : works on active doc without compute, PBR settings are kept
/*
var guid = RhinoDoc.ActiveDoc.Objects.Add(G);
var index = RhinoDoc.ActiveDoc.Materials.Add(pbrMat.Material);
var matGUID = RhinoDoc.ActiveDoc.Materials.Find(pbrMat.Material, true);
var objRef = new Rhino.DocObjects.ObjRef(RhinoDoc.ActiveDoc, guid);
RhinoDoc.ActiveDoc.Materials.FindIndex(index).RenderMaterial.AssignTo(objRef);
*/

//Option 4b : try with headless doc : works outside compute, but PBR settings are lost
var guid = doc.Objects.Add(G);
var index = doc.Materials.Add(pbrMat.Material);
var matGUID = doc.Materials.Find(pbrMat.Material, true);
var objRef = new Rhino.DocObjects.ObjRef(doc, guid);
doc.Materials.FindIndex(index).RenderMaterial.AssignTo(objRef);

var options = new Rhino.FileIO.FileGltfWriteOptions();
options.MapZToY = true;
Rhino.FileIO.FileGltf.Write("path to your local system.gltf", doc, options);

EDIT : I attach also an example of both files, one exported outside of compute (GLTF has glossy surface) and one exported from inside compute (GLTF has matte surface).

compute_matte.gltf (708.5 KB)

outside_glossy.gltf (1.8 MB)

I would directly create a physically based material. You can do so using

System.Guid pbrGuid = new System.Guid("5a8d7b9b-cdc9-49de-8c16-2ef64fb097ab")
RenderMaterial pbr = Rhino.Render.RenderContentType.NewContentFromTypeId(pbrGuid, doc);

Assign it to an object with obj.RenderMaterial = pbr;

You can set the various parameters through SetParameter.

Here some tutorials on how to investigate, create and edit different RenderContent. It is written with Python in mind, but since it is using RhinoCommon the same approaches will work in C#

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

1 Like

Hi Nathan,

Thanks a lot for the super fast answer.

I’ve tried your approach but I am not sure why I get this error :

Any idea ?
Thanks again

EDIT :
More on this, it seems it’s not attached to a document. I will try adding it.

Rhino.DocObjects.ObjRefArgumentException: The material is not attached to a document.
    at Script_Instance.RunScript(GeometryBase G, Object& ok, Object& ok2, Object& ok3) in rhinocode:///grasshopper/1/b480c16d-1a37-48d2-9057-ee57a0c0b260/52a97ff4-9b16-4c1f-a267-20ba69326147:line 95

EDIT 2 :
@nathanletwory
Using this approach it seems I can get the PBR material exported in the headless version. However the SetParameter method call seems to have no effect (I still have a white material).

//Option 5 : directly create a PBR material
System.Guid pbrGuid = new System.Guid(Rhino.Render.RenderMaterial.PaintMaterialGuid.ToByteArray());
Rhino.Render.RenderMaterial pbr = (Rhino.Render.RenderMaterial)Rhino.Render.RenderContentType.NewContentFromTypeId(pbrGuid, doc);
var guid = doc.Objects.Add(G);
var objRef = new Rhino.DocObjects.ObjRef(doc, guid);
pbr.AssignTo(objRef);
pbr.SetParameter(Rhino.Render.PhysicallyBasedMaterial.ParametersNames.BaseColor, System.Drawing.Color.Aqua);
Console.Write(objRef);
//objRef.Object().RenderMaterial = pbr;
var options =  new Rhino.FileIO.FileGltfWriteOptions();
options.MapZToY = true;
Rhino.FileIO.FileGltf.Write("somewhere/output.gltf", doc, options);

You need to bracket changes through SetParameter by the appropriate calls to BeginChange and EndChange as I write in almost all of the literate scripts (like https://jesterking.github.io/rhipy/create_specific_rendermaterial.html ).

pbr.BeginChange(Rhino.Render.RenderContent.ChangeContexts.Program)
pbr.SetParameter(...)
pbr.EndChange()

# and the assign to object
ob.RenderMaterial = pbr
ob.CommitChanges()
1 Like

Yup, I just figured this out as well.
Thanks again.

Can you just help again with the SetParameter method, it’s somehow unclear to me ?

This works, success is true.

pbr.BeginChange(Rhino.Render.RenderContent.ChangeContexts.Program);
pbr.Name = "C#Created";
var color = Rhino.Display.Color4f.Black;
bool success = pbr.SetParameter("color", color); //success if true
pbr.EndChange();

This does not work, success is false.

pbr.BeginChange(Rhino.Render.RenderContent.ChangeContexts.Program);
pbr.Name = "C#Created";
var color = Rhino.Display.Color4f.Black;
bool success = pbr.SetParameter(Rhino.Render.ParameterNames.PhysicallyBased.BaseColor, color); //success if false
pbr.EndChange();

When looking at the XML content (got the information from your website here about parameters), I see there are actually 2 separated sections, parameters-v8 and parameters which seems to be settable via SetParameter method, and the simulation section which actually contains the parameters I would like to modify. From the second snippet above, I am not able to modify them so far.
Is there a solution for that ?

<material auto-delete="false" reference="false" hidden="false" tags="" notes="" instance-name="C#Created" instance-id="7173C602-EEC0-45B0-96C0-91F083083423" type-id="492FAFA5-0E48-4C8E-89A0-08D3A19BFE89" plug-in-id="16592D58-4A2F-401D-BF5E-3B87741C1B1B" render-engine-id="99999999-9999-9999-9999-999999999999" type-name="rdk-paint-material"><parameters-v8>
	<parameter type="color" name="color">0,0,0,1</parameter>
	<parameter type="double" name="reflectivity">1</parameter>
</parameters-v8>
<parameters>
	<color type="color">0,0,0,1</color>
	<reflectivity type="double">1</reflectivity>
</parameters>
<simulation>
	<ambient type="color">0,0,0,1</ambient>
	<diffuse type="color">0,0,0,1</diffuse>
	<emission type="color">0,0,0,1</emission>
	<specular type="color">1,1,1,1</specular>
	<shine type="double">1</shine>
	<transparency type="double">0</transparency>
	<reflectivity type="double">1</reflectivity>
	<ior type="double">1</ior>
	<fresnel-enabled type="bool">true</fresnel-enabled>
	<polish-amount type="double">1</polish-amount>
	<clarity-amount type="double">1</clarity-amount>
	<reflection type="color">1,1,1,1</reflection>
	<transparent type="color">1,1,1,1</transparent>
	<is-physically-based type="bool">true</is-physically-based>
	<pbr-brdf type="string">ggx</pbr-brdf>
	<pbr-base-color type="color">0,0,0,1</pbr-base-color>
	<pbr-subsurface type="double">0</pbr-subsurface>
	<pbr-subsurface-scattering-color type="color">1,1,1,1</pbr-subsurface-scattering-color>
	<pbr-subsurface-scattering-radius type="double">0</pbr-subsurface-scattering-radius>
	<pbr-specular type="double">0.5</pbr-specular>
	<pbr-specular-tint type="double">0</pbr-specular-tint>
	<pbr-metallic type="double">0</pbr-metallic>
	<pbr-roughness type="double">0</pbr-roughness>
	<pbr-anisotropic type="double">0</pbr-anisotropic>
	<pbr-anisotropic-rotation type="double">0</pbr-anisotropic-rotation>
	<pbr-sheen type="double">0</pbr-sheen>
	<pbr-sheen-tint type="double">0</pbr-sheen-tint>
	<pbr-clearcoat type="double">0</pbr-clearcoat>
	<pbr-clearcoat-roughness type="double">0</pbr-clearcoat-roughness>
	<pbr-opacity type="double">1</pbr-opacity>
	<pbr-opacity-ior type="double">1</pbr-opacity-ior>
	<pbr-opacity-roughness type="double">0</pbr-opacity-roughness>
	<pbr-emission type="color">0,0,0,1</pbr-emission>
	<pbr-alpha type="double">1</pbr-alpha>
	<pbr-use-base-color-texture-alpha type="bool">false</pbr-use-base-color-texture-alpha>
</simulation>
</material>

You are creating a Paint material, see under EDIT 2 of your post Physically Based Material in Headless doc - #3 by Laoky where you do

System.Guid pbrGuid = new System.Guid(Rhino.Render.RenderMaterial.PaintMaterialGuid.ToByteArray());

Instead, use the GUID I provided to you 5a8d7b9b-cdc9-49de-8c16-2ef64fb097ab

In Rhino 8 create a PBR material, save that to a file and open up, you’ll see something like this:

<xml>
	<material type-name="5a8d7b9b-cdc9-49de-8c16-2ef64fb097ab" render-engine-id="99999999-9999-9999-9999-999999999999" plug-in-id="638A0098-0511-482B-95BF-8CF47FD32C17" type-id="5A8D7B9B-CDC9-49DE-8C16-2EF64FB097AB" notes="" tags="" hidden="false" reference="false" auto-delete="false">
		<parameters-v8>
			<parameter name="automatic-dynamic-field-meta-data" type="string">&lt;xml/&gt;</parameter>
			<parameter name="pbr-base-color" type="color">0.980000019073486,0.980000019073486,0.980000019073486,1</parameter>
			<parameter name="pbr-base-color-on" type="bool">false</parameter>
			<parameter name="pbr-base-color-double-amount" type="double">1</parameter>
			<parameter name="pbr-base-color-amount" type="int">100</parameter>
			<parameter name="pbr-subsurface" type="double">0</parameter>
			<parameter name="pbr-subsurface-on" type="bool">false</parameter>
			<parameter name="pbr-subsurface-double-amount" type="double">1</parameter>
			<parameter name="pbr-subsurface-amount" type="int">100</parameter>
			<parameter name="pbr-subsurface-scattering-radius" type="double">0</parameter>
			<parameter name="pbr-subsurface-scattering-radius-on" type="bool">false</parameter>
			<parameter name="pbr-subsurface-scattering-radius-double-amount" type="double">0.01</parameter>
			<parameter name="pbr-subsurface-scattering-radius-amount" type="int">1</parameter>
			<parameter name="pbr-metallic" type="double">0</parameter>
			<parameter name="pbr-metallic-on" type="bool">false</parameter>
			<parameter name="pbr-metallic-double-amount" type="double">1</parameter>
			<parameter name="pbr-metallic-amount" type="int">100</parameter>
			<parameter name="pbr-specular" type="double">0.5</parameter>
			<parameter name="pbr-specular-on" type="bool">false</parameter>
			<parameter name="pbr-specular-double-amount" type="double">1</parameter>
			<parameter name="pbr-specular-amount" type="int">100</parameter>
			<parameter name="pbr-specular-tint" type="double">0</parameter>
			<parameter name="pbr-specular-tint-on" type="bool">false</parameter>
			<parameter name="pbr-specular-tint-double-amount" type="double">1</parameter>
			<parameter name="pbr-specular-tint-amount" type="int">100</parameter>
			<parameter name="pbr-roughness" type="double">0.2</parameter>
			<parameter name="pbr-roughness-on" type="bool">false</parameter>
			<parameter name="pbr-roughness-double-amount" type="double">1</parameter>
			<parameter name="pbr-roughness-amount" type="int">100</parameter>
			<parameter name="pbr-anisotropic" type="double">0</parameter>
			<parameter name="pbr-anisotropic-on" type="bool">false</parameter>
			<parameter name="pbr-anisotropic-double-amount" type="double">1</parameter>
			<parameter name="pbr-anisotropic-amount" type="int">100</parameter>
			<parameter name="pbr-anisotropic-rotation" type="double">0</parameter>
			<parameter name="pbr-anisotropic-rotation-on" type="bool">false</parameter>
			<parameter name="pbr-anisotropic-rotation-double-amount" type="double">1</parameter>
			<parameter name="pbr-anisotropic-rotation-amount" type="int">100</parameter>
			<parameter name="pbr-sheen" type="double">0</parameter>
			<parameter name="pbr-sheen-on" type="bool">false</parameter>
			<parameter name="pbr-sheen-double-amount" type="double">1</parameter>
			<parameter name="pbr-sheen-amount" type="int">100</parameter>
			<parameter name="pbr-sheen-tint" type="double">0</parameter>
			<parameter name="pbr-sheen-tint-on" type="bool">false</parameter>
			<parameter name="pbr-sheen-tint-double-amount" type="double">1</parameter>
			<parameter name="pbr-sheen-tint-amount" type="int">100</parameter>
			<parameter name="pbr-clearcoat" type="double">0</parameter>
			<parameter name="pbr-clearcoat-on" type="bool">false</parameter>
			<parameter name="pbr-clearcoat-double-amount" type="double">1</parameter>
			<parameter name="pbr-clearcoat-amount" type="int">100</parameter>
			<parameter name="pbr-clearcoat-roughness" type="double">0</parameter>
			<parameter name="pbr-clearcoat-roughness-on" type="bool">false</parameter>
			<parameter name="pbr-clearcoat-roughness-double-amount" type="double">1</parameter>
			<parameter name="pbr-clearcoat-roughness-amount" type="int">100</parameter>
			<parameter name="pbr-opacity-ior" type="double">1.52</parameter>
			<parameter name="pbr-opacity-ior-on" type="bool">false</parameter>
			<parameter name="pbr-opacity-ior-double-amount" type="double">1</parameter>
			<parameter name="pbr-opacity-ior-amount" type="int">100</parameter>
			<parameter name="pbr-opacity" type="double">1</parameter>
			<parameter name="pbr-opacity-on" type="bool">false</parameter>
			<parameter name="pbr-opacity-double-amount" type="double">1</parameter>
			<parameter name="pbr-opacity-amount" type="int">100</parameter>
			<parameter name="pbr-opacity-roughness" type="double">0</parameter>
			<parameter name="pbr-opacity-roughness-on" type="bool">false</parameter>
			<parameter name="pbr-opacity-roughness-double-amount" type="double">1</parameter>
			<parameter name="pbr-opacity-roughness-amount" type="int">100</parameter>
			<parameter name="pbr-alpha" type="double">1</parameter>
			<parameter name="pbr-alpha-on" type="bool">false</parameter>
			<parameter name="pbr-alpha-double-amount" type="double">1</parameter>
			<parameter name="pbr-alpha-amount" type="int">100</parameter>
			<parameter name="pbr-subsurface-scattering-color" type="color">1,1,1,1</parameter>
			<parameter name="pbr-subsurface-scattering-color-on" type="bool">false</parameter>
			<parameter name="pbr-subsurface-scattering-color-double-amount" type="double">1</parameter>
			<parameter name="pbr-subsurface-scattering-color-amount" type="int">100</parameter>
			<parameter name="pbr-emission" type="color">0,0,0,1</parameter>
			<parameter name="pbr-emission-on" type="bool">false</parameter>
			<parameter name="pbr-emission-double-amount" type="double">1</parameter>
			<parameter name="pbr-emission-amount" type="int">100</parameter>
			<parameter name="emission-multiplier" type="double">1</parameter>
			<parameter name="emission-multiplier-on" type="bool">false</parameter>
			<parameter name="emission-multiplier-double-amount" type="double">1</parameter>
			<parameter name="emission-multiplier-amount" type="int">100</parameter>
			<parameter name="alpha-transparency" type="bool">true</parameter>
			<parameter name="pbr-ambient-occlusion" type="double">1</parameter>
			<parameter name="pbr-ambient-occlusion-on" type="bool">false</parameter>
			<parameter name="pbr-ambient-occlusion-double-amount" type="double">1</parameter>
			<parameter name="pbr-ambient-occlusion-amount" type="int">100</parameter>
			<parameter name="pbr-bump" type="color">0,0,0,1</parameter>
			<parameter name="pbr-bump-on" type="bool">false</parameter>
			<parameter name="pbr-bump-double-amount" type="double">0.3</parameter>
			<parameter name="pbr-bump-amount" type="int">30</parameter>
			<parameter name="pbr-displacement" type="double">0</parameter>
			<parameter name="pbr-displacement-on" type="bool">false</parameter>
			<parameter name="pbr-displacement-double-amount" type="double">0.001</parameter>
			<parameter name="pbr-displacement-amount" type="int">0</parameter>
			<parameter name="pbr-clearcoat-bump" type="color">0,0,0,1</parameter>
			<parameter name="pbr-clearcoat-bump-on" type="bool">false</parameter>
			<parameter name="pbr-clearcoat-bump-double-amount" type="double">1</parameter>
			<parameter name="pbr-clearcoat-bump-amount" type="int">100</parameter>
			<parameter name="pbr-show-ui-basic-metalrough" type="bool">false</parameter>
			<parameter name="pbr-show-ui-subsurface" type="bool">false</parameter>
			<parameter name="pbr-show-ui-specularity" type="bool">false</parameter>
			<parameter name="pbr-show-ui-anisotropy" type="bool">false</parameter>
			<parameter name="pbr-show-ui-sheen" type="bool">false</parameter>
			<parameter name="pbr-show-ui-clearcoat" type="bool">false</parameter>
			<parameter name="pbr-show-ui-opacity" type="bool">false</parameter>
			<parameter name="pbr-show-ui-emission" type="bool">false</parameter>
			<parameter name="pbr-show-ui-bump-displacement" type="bool">false</parameter>
			<parameter name="pbr-show-ui-ambient-occlusion" type="bool">false</parameter>
		</parameters-v8>
		<parameters>
			<automatic-dynamic-field-meta-data type="string">&lt;xml/&gt;</automatic-dynamic-field-meta-data>
			<pbr-base-color type="color">0.980000019073486,0.980000019073486,0.980000019073486,1</pbr-base-color>
			<pbr-base-color-on type="bool">false</pbr-base-color-on>
			<pbr-base-color-double-amount type="double">1</pbr-base-color-double-amount>
			<pbr-base-color-amount type="int">100</pbr-base-color-amount>
			<pbr-subsurface type="double">0</pbr-subsurface>
			<pbr-subsurface-on type="bool">false</pbr-subsurface-on>
			<pbr-subsurface-double-amount type="double">1</pbr-subsurface-double-amount>
			<pbr-subsurface-amount type="int">100</pbr-subsurface-amount>
			<pbr-subsurface-scattering-radius type="double">0</pbr-subsurface-scattering-radius>
			<pbr-subsurface-scattering-radius-on type="bool">false</pbr-subsurface-scattering-radius-on>
			<pbr-subsurface-scattering-radius-double-amount type="double">0.01</pbr-subsurface-scattering-radius-double-amount>
			<pbr-subsurface-scattering-radius-amount type="int">1</pbr-subsurface-scattering-radius-amount>
			<pbr-metallic type="double">0</pbr-metallic>
			<pbr-metallic-on type="bool">false</pbr-metallic-on>
			<pbr-metallic-double-amount type="double">1</pbr-metallic-double-amount>
			<pbr-metallic-amount type="int">100</pbr-metallic-amount>
			<pbr-specular type="double">0.5</pbr-specular>
			<pbr-specular-on type="bool">false</pbr-specular-on>
			<pbr-specular-double-amount type="double">1</pbr-specular-double-amount>
			<pbr-specular-amount type="int">100</pbr-specular-amount>
			<pbr-specular-tint type="double">0</pbr-specular-tint>
			<pbr-specular-tint-on type="bool">false</pbr-specular-tint-on>
			<pbr-specular-tint-double-amount type="double">1</pbr-specular-tint-double-amount>
			<pbr-specular-tint-amount type="int">100</pbr-specular-tint-amount>
			<pbr-roughness type="double">0.2</pbr-roughness>
			<pbr-roughness-on type="bool">false</pbr-roughness-on>
			<pbr-roughness-double-amount type="double">1</pbr-roughness-double-amount>
			<pbr-roughness-amount type="int">100</pbr-roughness-amount>
			<pbr-anisotropic type="double">0</pbr-anisotropic>
			<pbr-anisotropic-on type="bool">false</pbr-anisotropic-on>
			<pbr-anisotropic-double-amount type="double">1</pbr-anisotropic-double-amount>
			<pbr-anisotropic-amount type="int">100</pbr-anisotropic-amount>
			<pbr-anisotropic-rotation type="double">0</pbr-anisotropic-rotation>
			<pbr-anisotropic-rotation-on type="bool">false</pbr-anisotropic-rotation-on>
			<pbr-anisotropic-rotation-double-amount type="double">1</pbr-anisotropic-rotation-double-amount>
			<pbr-anisotropic-rotation-amount type="int">100</pbr-anisotropic-rotation-amount>
			<pbr-sheen type="double">0</pbr-sheen>
			<pbr-sheen-on type="bool">false</pbr-sheen-on>
			<pbr-sheen-double-amount type="double">1</pbr-sheen-double-amount>
			<pbr-sheen-amount type="int">100</pbr-sheen-amount>
			<pbr-sheen-tint type="double">0</pbr-sheen-tint>
			<pbr-sheen-tint-on type="bool">false</pbr-sheen-tint-on>
			<pbr-sheen-tint-double-amount type="double">1</pbr-sheen-tint-double-amount>
			<pbr-sheen-tint-amount type="int">100</pbr-sheen-tint-amount>
			<pbr-clearcoat type="double">0</pbr-clearcoat>
			<pbr-clearcoat-on type="bool">false</pbr-clearcoat-on>
			<pbr-clearcoat-double-amount type="double">1</pbr-clearcoat-double-amount>
			<pbr-clearcoat-amount type="int">100</pbr-clearcoat-amount>
			<pbr-clearcoat-roughness type="double">0</pbr-clearcoat-roughness>
			<pbr-clearcoat-roughness-on type="bool">false</pbr-clearcoat-roughness-on>
			<pbr-clearcoat-roughness-double-amount type="double">1</pbr-clearcoat-roughness-double-amount>
			<pbr-clearcoat-roughness-amount type="int">100</pbr-clearcoat-roughness-amount>
			<pbr-opacity-ior type="double">1.52</pbr-opacity-ior>
			<pbr-opacity-ior-on type="bool">false</pbr-opacity-ior-on>
			<pbr-opacity-ior-double-amount type="double">1</pbr-opacity-ior-double-amount>
			<pbr-opacity-ior-amount type="int">100</pbr-opacity-ior-amount>
			<pbr-opacity type="double">1</pbr-opacity>
			<pbr-opacity-on type="bool">false</pbr-opacity-on>
			<pbr-opacity-double-amount type="double">1</pbr-opacity-double-amount>
			<pbr-opacity-amount type="int">100</pbr-opacity-amount>
			<pbr-opacity-roughness type="double">0</pbr-opacity-roughness>
			<pbr-opacity-roughness-on type="bool">false</pbr-opacity-roughness-on>
			<pbr-opacity-roughness-double-amount type="double">1</pbr-opacity-roughness-double-amount>
			<pbr-opacity-roughness-amount type="int">100</pbr-opacity-roughness-amount>
			<pbr-alpha type="double">1</pbr-alpha>
			<pbr-alpha-on type="bool">false</pbr-alpha-on>
			<pbr-alpha-double-amount type="double">1</pbr-alpha-double-amount>
			<pbr-alpha-amount type="int">100</pbr-alpha-amount>
			<pbr-subsurface-scattering-color type="color">1,1,1,1</pbr-subsurface-scattering-color>
			<pbr-subsurface-scattering-color-on type="bool">false</pbr-subsurface-scattering-color-on>
			<pbr-subsurface-scattering-color-double-amount type="double">1</pbr-subsurface-scattering-color-double-amount>
			<pbr-subsurface-scattering-color-amount type="int">100</pbr-subsurface-scattering-color-amount>
			<pbr-emission type="color">0,0,0,1</pbr-emission>
			<pbr-emission-on type="bool">false</pbr-emission-on>
			<pbr-emission-double-amount type="double">1</pbr-emission-double-amount>
			<pbr-emission-amount type="int">100</pbr-emission-amount>
			<emission-multiplier type="double">1</emission-multiplier>
			<emission-multiplier-on type="bool">false</emission-multiplier-on>
			<emission-multiplier-double-amount type="double">1</emission-multiplier-double-amount>
			<emission-multiplier-amount type="int">100</emission-multiplier-amount>
			<alpha-transparency type="bool">true</alpha-transparency>
			<pbr-ambient-occlusion type="double">1</pbr-ambient-occlusion>
			<pbr-ambient-occlusion-on type="bool">false</pbr-ambient-occlusion-on>
			<pbr-ambient-occlusion-double-amount type="double">1</pbr-ambient-occlusion-double-amount>
			<pbr-ambient-occlusion-amount type="int">100</pbr-ambient-occlusion-amount>
			<pbr-bump type="color">0,0,0,1</pbr-bump>
			<pbr-bump-on type="bool">false</pbr-bump-on>
			<pbr-bump-double-amount type="double">0.3</pbr-bump-double-amount>
			<pbr-bump-amount type="int">30</pbr-bump-amount>
			<pbr-displacement type="double">0</pbr-displacement>
			<pbr-displacement-on type="bool">false</pbr-displacement-on>
			<pbr-displacement-double-amount type="double">0.001</pbr-displacement-double-amount>
			<pbr-displacement-amount type="int">0</pbr-displacement-amount>
			<pbr-clearcoat-bump type="color">0,0,0,1</pbr-clearcoat-bump>
			<pbr-clearcoat-bump-on type="bool">false</pbr-clearcoat-bump-on>
			<pbr-clearcoat-bump-double-amount type="double">1</pbr-clearcoat-bump-double-amount>
			<pbr-clearcoat-bump-amount type="int">100</pbr-clearcoat-bump-amount>
			<pbr-show-ui-basic-metalrough type="bool">false</pbr-show-ui-basic-metalrough>
			<pbr-show-ui-subsurface type="bool">false</pbr-show-ui-subsurface>
			<pbr-show-ui-specularity type="bool">false</pbr-show-ui-specularity>
			<pbr-show-ui-anisotropy type="bool">false</pbr-show-ui-anisotropy>
			<pbr-show-ui-sheen type="bool">false</pbr-show-ui-sheen>
			<pbr-show-ui-clearcoat type="bool">false</pbr-show-ui-clearcoat>
			<pbr-show-ui-opacity type="bool">false</pbr-show-ui-opacity>
			<pbr-show-ui-emission type="bool">false</pbr-show-ui-emission>
			<pbr-show-ui-bump-displacement type="bool">false</pbr-show-ui-bump-displacement>
			<pbr-show-ui-ambient-occlusion type="bool">false</pbr-show-ui-ambient-occlusion>
		</parameters>
		<simulation>
			<ambient type="color">0,0,0,1</ambient>
			<diffuse type="color">0.980392158031464,0.980392158031464,0.980392158031464,1</diffuse>
			<emission type="color">0,0,0,1</emission>
			<specular type="color">0.800000011920929,0.800000011920929,0.800000011920929,1</specular>
			<shine type="double">0.8</shine>
			<transparency type="double">0</transparency>
			<reflectivity type="double">0.8</reflectivity>
			<ior type="double">1.52</ior>
			<fresnel-enabled type="bool">true</fresnel-enabled>
			<polish-amount type="double">0.8</polish-amount>
			<clarity-amount type="double">1</clarity-amount>
			<reflection type="color">1,1,1,1</reflection>
			<transparent type="color">1,1,1,1</transparent>
			<is-physically-based type="bool">true</is-physically-based>
			<pbr-brdf type="string">ggx</pbr-brdf>
			<pbr-base-color type="color">0.980000019073486,0.980000019073486,0.980000019073486,1</pbr-base-color>
			<pbr-subsurface type="double">0</pbr-subsurface>
			<pbr-subsurface-scattering-color type="color">1,1,1,1</pbr-subsurface-scattering-color>
			<pbr-subsurface-scattering-radius type="double">0</pbr-subsurface-scattering-radius>
			<pbr-specular type="double">0.5</pbr-specular>
			<pbr-specular-tint type="double">0</pbr-specular-tint>
			<pbr-metallic type="double">0</pbr-metallic>
			<pbr-roughness type="double">0.2</pbr-roughness>
			<pbr-anisotropic type="double">0</pbr-anisotropic>
			<pbr-anisotropic-rotation type="double">0</pbr-anisotropic-rotation>
			<pbr-sheen type="double">0</pbr-sheen>
			<pbr-sheen-tint type="double">0</pbr-sheen-tint>
			<pbr-clearcoat type="double">0</pbr-clearcoat>
			<pbr-clearcoat-roughness type="double">0</pbr-clearcoat-roughness>
			<pbr-opacity type="double">1</pbr-opacity>
			<pbr-opacity-ior type="double">1.52</pbr-opacity-ior>
			<pbr-opacity-roughness type="double">0</pbr-opacity-roughness>
			<pbr-emission type="color">0,0,0,1</pbr-emission>
			<pbr-alpha type="double">1</pbr-alpha>
			<pbr-use-base-color-texture-alpha type="bool">true</pbr-use-base-color-texture-alpha>
		</simulation>
		<preview>
			<scene-scale type="double">1</scene-scale>
			<angle-x type="double">38.6746511713306</angle-x>
			<angle-y type="double">35.2369044005456</angle-y>
			<rotation-type type="string">camera</rotation-type>
			<geometry type="string">material-scene</geometry>
			<background type="string">material-scene</background>
			<lighting type="string">skylighting</lighting>
		</preview>
	</material>
	<meta-data>
		<renderer-name>Generic</renderer-name>
		<type-name>Physically Based</type-name>
	</meta-data>
</xml>

I left the thumbnail tag out.

Ok, it’s working great.
Thanks for the support !

I join complete code for someone to re-use if it can help

//Option 5 : directly create a PBR material
System.Guid pbrGuid = new System.Guid("5a8d7b9b-cdc9-49de-8c16-2ef64fb097ab");
Rhino.Render.RenderMaterial pbr = (Rhino.Render.RenderMaterial)Rhino.Render.RenderContentType.NewContentFromTypeId(pbrGuid, doc);

pbr.BeginChange(Rhino.Render.RenderContent.ChangeContexts.Program);
pbr.Name = "C#Created";
System.Drawing.Color c = System.Drawing.Color.Aqua;
var color = Rhino.Display.Color4f.FromArgb(
    c.A, c.R, c.G, c.B
);
bool success = pbr.SetParameter(Rhino.Render.ParameterNames.PhysicallyBased.BaseColor, color); //success if false
pbr.EndChange();

var guid = doc.Objects.Add(G);
var objRef = new Rhino.DocObjects.ObjRef(doc, guid);
pbr.AssignTo(objRef);
doc.RenderMaterials.Add(pbr);

@nathanletwory May I ask if this 5a8d7b9b-cdc9-49de-8c16-2ef64fb097ab UID is available from the library to avoid this hardcoded value in the code ?

1 Like

It is available through Rhino.Render.ContentUuids.PhysicallyBasedMaterialType. All RenderContent UUIDs that Rhino itself provides should be accessible through Rhino.Render.ContentUuids.

1 Like

Hi again, I re-open the issue as I remark that it’s still not working over compute, which was my initial problem.

image

The complete code :

private void RunScript(GeometryBase G, Color Dc)
{
    var doc = RhinoDoc.CreateHeadless(null);

    //https://discourse.mcneel.com/t/physically-based-material-in-headless-doc/182696/7
    System.Guid pbrGuid = new System.Guid(Rhino.Render.ContentUuids.PhysicallyBasedMaterialType.ToByteArray());
    Rhino.Render.RenderMaterial pbr = (Rhino.Render.RenderMaterial)Rhino.Render.RenderContentType.NewContentFromTypeId(pbrGuid, doc);

    //pbr is null at this stage, over compute ! (line 44)
    pbr.BeginChange(Rhino.Render.RenderContent.ChangeContexts.Program);
    pbr.Name = "C#Created";
    var color = new Rhino.Display.Color4f(Dc.ToArgb());
    bool success = pbr.SetParameter(Rhino.Render.ParameterNames.PhysicallyBased.BaseColor, color);
    success = pbr.SetParameter(Rhino.Render.ParameterNames.PhysicallyBased.Clearcoat, 1.0);
    success = pbr.SetParameter(Rhino.Render.ParameterNames.PhysicallyBased.ClearcoatRoughness, 0.1);
    Console.Write(success);
    pbr.EndChange();

    var guid = doc.Objects.Add(G);
    var objRef = new Rhino.DocObjects.ObjRef(doc, guid);
    pbr.AssignTo(objRef);
    doc.RenderMaterials.Add(pbr);

    var options =  new Rhino.FileIO.FileGltfWriteOptions();
    options.MapZToY = true;
    Rhino.FileIO.FileGltf.Write("somewhere/output.gltf", doc, options);
}

I’m not familiar enough with Rhino Compute and Hops to know how this is supposed to work. @AndyPayne is better suited for that part.

Can you attach your GH file that your passing into shops so I can take a look?

Sure, here it is :
rendermat.gh (13.5 KB)

@Laoky I have looked at your code and I believe there is an internal bug with how .glb and/or .gltf files are imported/exported via rhino.compute. This was reported recently and there is a YT issue for this. We are looking into this.

1 Like

Hello, I would like to know how to modify the parameters of simulation

I tried SetParameter but it didn’t work and got a false result. Please advise me

SetParameter and GetParameter do not access the simulation tag data. That is something that is there as a fallback for Rhino itself essentially.

Thank you very much for your reply and help me clarify my doubts. Actually, I wanted to modify the file name through c # or macros when the RenderContent Type is ResampleTextureType. However, since my Rhino version is 6.5, there is no file name set attribute. I want to set an image for the Example, which is very helpless. So, may I ask if there is a way to modify this parameter? Thank you again