How to create new Material inside the script for Jmec?

In other word how to reference assetManager for creating Material?
I would like to convert materials when I convert models to j3o

It is provided via a binding and is available in all scripts:

1 Like

Give me an example with my code here, by the way this code works, but I need to how to excute the binding here

import com.jme3.asset.DesktopAssetManager
import com.jme3.material.Material
import com.jme3.material.MaterialDef
import com.jme3.material.RenderState
import com.jme3.renderer.queue.RenderQueue
import com.jme3.scene.Geometry
import com.jme3.scene.Node
import com.jme3.scene.Spatial
import com.jme3.texture.Texture
import com.simsilica.jmec.ModelInfo
import com.jme3.math.ColorRGBA

def convertToPhong(Spatial spatial) {
if (spatial instanceof Geometry) {
def mat = spatial.material
if (mat.getMaterialDef().getName() == “PBR Lighting”) {
def phongMat = new Material(mat.getMaterialDef().getAssetManager(), “Common/MatDefs/Light/Lighting.j3md”)
phongMat.setBoolean(“UseMaterialColors”, true)
phongMat.setColor(“Diffuse”, (ColorRGBA)mat.getParam(“BaseColor”).getValue())
phongMat.setColor(“Specular”, (ColorRGBA)mat.getParam(“Specular”).getValue())
// phongMat.setFloat(“Shininess”, (float)mat.getParam(“Gloss”).getValue())
def tex = mat.getTextureParam(“BaseColorMap”)
if (tex != null) {
phongMat.setTexture(“DiffuseMap”, tex.getTextureValue())
spatial.material = phongMat
if (spatial instanceof Node) {
for (child in (spatial as Node).children) {

model.findAll(Geometry.class).each { geom → model.generateMaterial(geom.material, “materials/” +}

In case this is helpful, here is an example of a script I use to convert PBR materials to regular lighting.j3md.

import com.jme3.material.*;
import com.jme3.scene.*;
import com.jme3.util.TangentBinormalGenerator;


boolean usePbr = false;

model.findAll( Geometry.class ).each { geom ->
    def mat = geom.getMaterial();"mat:" + mat.getMaterialDef().getName());
    boolean isPbr = "PBR Lighting" == mat?.materialDef?.name;
    if( !isPbr ) {
        // Not the droids we're looking for
//    if( !mat.getParamsMap().containsKey("BaseColorMap") ) {
//        // Not the droids we're looking for
//        return;
//    }

    // Temporarily convert the clothing layers to the test images    
    def base = mat.getParamValue("BaseColorMap");
    println "Texture:" + base; 
    if( "Grid-x.png" == ) {
        // Swap out the generic textures for the test textures
        mat.setTexture("BaseColorMap", assets.loadTexture("test-base.png", false));                 
        mat.setTexture("NormalMap", assets.loadTexture("test-normal.png", false));            
        mat.setTexture("MetallicRoughnessMap", assets.loadTexture("test-mr.png", false));
        mat.setFloat("Metallic", 1);
        mat.setFloat("Roughness", 1);
    if( !usePbr ) {
        // Replace it with regular lighting
        def newMat = new Material(assets.assetManager, "MatDefs/LocalLighting.j3md");
        if( mat.getParamsMap().containsKey("BaseColorMap") ) {
            newMat.setTexture("DiffuseMap", mat.getTextureParam("BaseColorMap").getTextureValue());
        if( mat.getParamsMap().containsKey("NormalMap") ) {
            newMat.setTexture("NormalMap", mat.getTextureParam("NormalMap").getTextureValue());
            newMat.setBoolean("PackedNormalParallax", true);
        if( mat.getParamsMap().containsKey("MetallicRoughnessMap") ) {
            // not really
            newMat.setTexture("SpecularMap", mat.getTextureParam("MetallicRoughnessMap").getTextureValue());
        if( mat.getParamsMap().containsKey("BaseColor") ) {
            def color = mat.getParamValue("BaseColor");
            newMat.setColor("Diffuse", color);
            newMat.setColor("Ambient", color);
            newMat.setBoolean("UseMaterialColors", true);

Edit: I mean, it does a couple of other things, too. It’s my current post-proc script for character models in Mythruna.


@Ali_RS @pspeed
Thank you

1 Like

The flag -probe A gives the descriptions of the model before the applying any changes, any way we can see them after the modifications

It’s kind of a weird request but probably something like this at the end of your script or in a separate script you add to the command line:


It works but it gives this following error

Exception in thread “main” java.lang.RuntimeException: Error running script:C:\Users\User 1\Documents\script.groovy against:boxprinciplebsdf.glb
at com.simsilica.jmec.ModelScript.apply(
at com.simsilica.jmec.Convert.runProcessors(
at com.simsilica.jmec.Convert.convert(
at com.simsilica.jmec.Convert.main(
Caused by: javax.script.ScriptException: java.lang.NullPointerException
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(
at org.codehaus.groovy.jsr223.GroovyCompiledScript.eval(
at java.scripting/javax.script.CompiledScript.eval(
at com.simsilica.jmec.ModelScript.apply(
… 3 more
Caused by: java.lang.NullPointerException
at com.simsilica.jmec.ModelInfo$Dependency.compareTo(
at com.simsilica.jmec.ModelInfo$Dependency.compareTo(
at java.base/
at java.base/java.util.TreeMap.put(
at java.base/java.util.TreeSet.add(
at java.base/java.util.AbstractCollection.addAll(
at java.base/java.util.TreeSet.addAll(
at java.base/java.util.TreeSet.(
at com.simsilica.jmec.Probe.listDependencies(
at com.simsilica.jmec.Probe.apply(
at com.simsilica.jmec.ModelProcessor$ Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(
… 6 more


I do not have enough information to help further. Try changing the foobidoo to a wizbading.