I’ve written (with help from Claude.ai) a python script (Rhino 7 IronPython 2.7) that tweaks some V-Ray materials (that have already been convert from Rhino materials, with the name leaf or flower in it).
The diffuse tex is set up in a TexBitmap with the the filename XYZ_albedo.jpg
I want to create 2 new TexBitmaps, following the naming scheme: XYZ_translucency.jpg and XYZ_glossiness.jpg (with the same file location as the diffuse map), and map them to brdf.translucency_color_tex and brdf.reflect_glossiness_tex
Can someone explain how to do this?
import rhinoscriptsyntax as rs
import Rhino
import System
import rhVRay as vray
with vray.Scene.Transaction() as f:
# Get all V-Ray materials of type MtlSingleBRDF from the scene
vray_materials = vray.Scene.PluginsByType("MtlSingleBRDF", True)
# Loop through each V-Ray material
for material in vray_materials:
material_name = material.Name
with vray.Scene.Transaction() as t:
for material in vray.Scene.Materials:
brdf = vray.Scene[material.brdf]
if brdf.Type != "BRDFVRayMtl":
continue
# Check if name contains "leaf" OR "flower"
name_lower = brdf.Name.lower()
if "leaf" not in name_lower and "flower" not in name_lower:
continue
print("Processing: \"{0}\" ...".format(brdf.Name))
brdf.translucency = 6
brdf.translucency_amount = 0.3
brdf.refract_ior = 1.6
brdf.fresnel_ior = 1.3
brdf.refract_glossiness = 1
brdf.refract_thin_walled = 1
brdf.reflect_color = [1, 1, 1, 1.0]
brdf.bump_amount_float = 1
brdf.translucency_color_tex = # ..._translucency.jpg
brdf.reflect_glossiness_tex = #..._glossiness.jpg
print("Done!")
Hi,
This API is pretty basic and is not meant to be used for other than querying basic information and tweaking simple parameters.
That being said creation and deletion of plugins is not exposed.
What you need, though, is not impossible, you just need a small helper file that will create the necessary plugins upon import.
I made a simple .vrmat file that contains the 3 plugins needed for the bitmap:
<vrmat>
<Asset url="/Bitmap">
<plugin>
<vrayplugin name="TexBitmap" version="23" />
</plugin>
</Asset>
<Asset url="/BitmapBuffer">
<plugin>
<vrayplugin name="BitmapBuffer" version="23" />
</plugin>
</Asset>
<Asset url="/BitmapUVW">
<plugin>
<vrayplugin name="UVWGenChannel" version="23" />
</plugin>
</Asset>
</vrmat>
and added a new function to import and properly rename them.
import rhinoscriptsyntax as rs
import Rhino
import System
import rhVRay as vray
def make_bitmap(scene, parent, prefix, file):
# import the TexBitmap
scene.LoadSettings(r"<path_to>\TexBitmap.vrmat")
# get /Bitmap, /BitmapBuffer and /BitmapUVW
texBitmap = scene["/Bitmap"]
bitmapBuffer = scene["/BitmapBuffer"]
bitmapUVW = scene["/BitmapUVW"]
# rename to handle the hierarchy
texBitmap._plugin_interface.Name = "%s/%s"%(parent.Name, prefix)
bitmapBuffer._plugin_interface.Name = "%s/Bitmap"%texBitmap.Name
bitmapUVW._plugin_interface.Name = "%s/UVW"%texBitmap.Name
# set properties
texBitmap.bitmap = bitmapBuffer.Name
texBitmap.uvwgen = bitmapUVW.Name
bitmapBuffer.file = file
return texBitmap
scene = vray.Scene
with scene.Transaction() as t:
for material in scene.Materials:
brdf = scene[material.brdf]
if brdf and brdf.Type != "BRDFVRayMtl":
continue
brdfName = brdf.Name
# Check if name contains "leaf" OR "flower"
name_lower = brdfName.lower()
if "leaf" not in name_lower and "flower" not in name_lower:
continue
print("Processing: \"{0}\" ...".format(brdfName))
brdf.translucency = 6
brdf.translucency_amount = 0.3
brdf.refract_ior = 1.6
brdf.fresnel_ior = 1.3
brdf.refract_glossiness = 1
brdf.refract_thin_walled = 1
brdf.reflect_color = [1, 1, 1, 1.0]
brdf.bump_amount_float = 1
brdf.translucency_color_tex = make_bitmap(scene, brdf, "Translucency", r"<path_to>\translucency.jpg").Name
brdf.reflect_glossiness_tex = make_bitmap(scene, brdf, "ReflectGlossiness", r"<path_to>\reflect_glossiness.jpg").Name
print "Done!"
and here is the result:
Also the Claude.ai put a lot of redundant code in that script, that you can safely remove
all files attached flower_leaf.zip
flower_leaf.zip (24.2 KB)
Hi Nikolay,
Thanks for the this help, really appreciate it.
I have two related questions:
1 - I’d like to do something similar with all materials with the name ‘bark’. After looking through the available parameters for a V-Ray mtl (bdrf) I notice that displacement isn’t part of them, so I assume we need to use a vrmat to import another plugin - can you guide me on how to do this? I want to add a _displacement.exr bitmap (the material already has a diffuse and bump bitmap upon import).
2 - When converting Rhino materials to V-Ray materials, I notice that all materials with ‘leaf’ in the name come in a 2-sided v-ray materials when running Rhino.Render.Utilities.ChangeContentType(m, vrayMtlId, True) - is this intended or am I mistaken?
Hi,
1. The displacement works just like the other two properties, but mind that we are talking about material displacement here. The scene hierarchy for that is very different compared to the renderer .vrscene. Basically in the .vrscene file that material displacement is converted to a geometry displacement.
the parameter name is called “displacement” and is pointing to a GeomDisplacedMesh plugin
If you give me more details, I can enhance the script for you
2. The reason you get a Mtl2Sided for the “Leaf” material, is because the enscape compatibility option is turned on. Enscape has this behavior that if you name your material in a certain way, that material is considered to be specific material type. Like “water”, “leaf”, “metal”, “copper”, etc..
If you want the default behavior you must turn the enscape compatibility option off:
Hi Nikolay,
Thanks again for your help on this.
The steps to take take regarding displacement is pretty similar to the leaf material you heped with…
- Check materials with ‘trunk’ in its name (sorry, not bark as previously mentioned)
- Add a displacement map. The file is matched to the material name… so Material_name_trunk_01 will have a displacement file name Material_name_trunk_01_displacement.exr (note - not all materials named trunk have a _displacement.exr file - if this is the case then we can skip adding a displacement map )
- See below for displacement settings:
- Add a _glossiness.jpg map to reflection glossiness with the same naming scheme mentioned before
- Set brdf.reflect_color = [1, 1, 1, 1.0]
Thanks for explaining about about the Enscape settings too!
Hi
I believe it is pretty straightforward, just added another dummy file with GeomDisplacedMesh and that is being loaded into the material.displacement slot (not the brdf!!)
the rest is just repetition:
#! python 2
import rhinoscriptsyntax as rs
import Rhino
import System
import rhVRay as vray
def make_bitmap(scene, parent, prefix, file):
# import the TexBitmap
scene.LoadSettings(r"<path_to>\TexBitmap.vrmat")
# get /Bitmap, /BitmapBuffer and /BitmapUVW
texBitmap = scene["/Bitmap"]
bitmapBuffer = scene["/BitmapBuffer"]
bitmapUVW = scene["/BitmapUVW"]
# rename to handle the hierarchy
texBitmap.Name = "%s/%s"%(parent.Name, prefix)
bitmapBuffer.Name = "%s/Bitmap"%texBitmap.Name
bitmapUVW.Name = "%s/UVW"%texBitmap.Name
# set properties
texBitmap.bitmap = bitmapBuffer.Name
texBitmap.uvwgen = bitmapUVW.Name
bitmapBuffer.file = file
return texBitmap
def make_displacement(scene, parent, prefix, file):
# import the GeomDisplacement
scene.LoadSettings(r"<path_to>\GeomDisplacement.vrmat")
# get /Displacement
geomDisplacedMesh = scene["/Displacement"]
# rename to handle the hierarchy
geomDisplacedMesh.Name = "%s/%s"%(parent.Name, prefix)
# set properties
geomDisplacedMesh.edge_length = 100
geomDisplacedMesh.displacement_tex_color = make_bitmap(scene, geomDisplacedMesh, "Bitmap", file).Name
return geomDisplacedMesh
def process_leafs(sceene, brdf):
brdf.translucency = 6
brdf.translucency_amount = 0.3
brdf.refract_ior = 1.6
brdf.fresnel_ior = 1.3
brdf.refract_glossiness = 1
brdf.refract_thin_walled = 1
brdf.reflect_color = [1, 1, 1, 1.0]
brdf.bump_amount_float = 1
brdf.translucency_color_tex = make_bitmap(scene, brdf, "Translucency", r"<path_to>\translucency.jpg").Name
brdf.reflect_glossiness_tex = make_bitmap(scene, brdf, "ReflectGlossiness", r"<path_to>\reflect_glossiness.jpg").Name
def process_barks(scene, material):
material.displacement = make_displacement(scene, material, "Displacement", r"<path_to>\displacement.jpg").Name
scene = vray.Scene
with scene.Transaction() as t:
for material in scene.Materials:
if not material or material.Type != "MtlSingleBRDF":
continue
#process barks (set parameters on the material)
if any(name_lower in material.Name.lower() for name_lower in ["bark"]):
process_barks(scene, material)
brdf = scene[material.brdf]
if not brdf or brdf.Type != "BRDFVRayMtl":
continue
# process leafs and flowers (set parameters on the BRDF)
if any(name_lower in brdf.Name.lower() for name_lower in ["leaf", "flower"]):
process_leafs(scene, brdf)
print "Done!"
code and example attached flower_leaf_bark.zip
Note:
Mind that currently the Displacement rollout will not appear in the AssetEditor when added by a script, unless you restart it - either save and re-open your file, or release and reacquire the V-Ray license. Both will force NeUI to reset its state and the displacement rollout will be displayed for the “Bark” material
flower_leaf_bark.zip (24.4 KB)