[SOLVED] COLOR_1 vertex buffer gltf emissive not implemented

So, I have several models I want to use in a scene, and they all have emissive lights in them. I noticed in jme, although the surface is visible in low light conditions, it is not emitting light. I also noticed that during the gltf import, there are errors about not supporting COLOR_1.

...
WARNING: could not assign data to any VertexBuffer type for buffer view 8766
Dec 13, 2020 9:19:10 AM com.jme3.scene.plugins.gltf.GltfUtils getVertexBufferType
WARNING: Unsupported Vertex Buffer type COLOR_1
...

is the COLOR_1 warning related to the the emissive surfaces not casting light? Or am I missing something? This is my fist attempt to do emissive surfaces in jme.

Any help is greatly apperciated.
~Trevor

1 Like

I’m still a novice with respect to shaders and PBR, but I do know that, at the present time, JME only supports a single color buffer per mesh.

It wouldn’t be difficult to add a second color buffer (in VertexBuffer.Type) but that will be the least of your difficulties, since none of the built-in materials handles a second color buffer…

PBR emission works. I’ve done it before. Even a long time ago.

See the glowing lights on the power cubes: Many bugs - 30 head-driller bugs running around - YouTube

What I don’t know is “anything about your scene”. Do you have an emission texture, did you just use vertex color or some other feature of Blender?

1 Like

The models are from kitbash.

Here is an example of one of their emissive materials:


It is just an emission map texture.

Example street light in scene for that material

GLTF material definition
"materials" : [
        {
            "doubleSided" : true,
            "name" : "KB3D_HTS_MetalGrey",
            "normalTexture" : {
                "index" : 0,
                "texCoord" : 0
            },
            "pbrMetallicRoughness" : {
                "baseColorTexture" : {
                    "index" : 1,
                    "texCoord" : 0
                },
                "metallicRoughnessTexture" : {
                    "index" : 2,
                    "texCoord" : 0
                }
            }
        },
        {
            "doubleSided" : true,
            "name" : "KB3D_HTS_MetalLight",
            "normalTexture" : {
                "index" : 3,
                "texCoord" : 0
            },
            "pbrMetallicRoughness" : {
                "baseColorTexture" : {
                    "index" : 4,
                    "texCoord" : 0
                },
                "metallicRoughnessTexture" : {
                    "index" : 5,
                    "texCoord" : 0
                }
            }
        },
        {
            "doubleSided" : true,
            "name" : "KB3D_HTS_MetalWhite",
            "normalTexture" : {
                "index" : 6,
                "texCoord" : 0
            },
            "pbrMetallicRoughness" : {
                "baseColorTexture" : {
                    "index" : 7,
                    "texCoord" : 0
                },
                "metallicRoughnessTexture" : {
                    "index" : 8,
                    "texCoord" : 0
                }
            }
        },
        {
            "doubleSided" : true,
            "name" : "KB3D_HTS_MetalYellow",
            "normalTexture" : {
                "index" : 9,
                "texCoord" : 0
            },
            "pbrMetallicRoughness" : {
                "baseColorTexture" : {
                    "index" : 10,
                    "texCoord" : 0
                },
                "metallicRoughnessTexture" : {
                    "index" : 11,
                    "texCoord" : 0
                }
            }
        },
        {
            "doubleSided" : true,
            "name" : "KB3D_HTS_PlasticWhite",
            "normalTexture" : {
                "index" : 12,
                "texCoord" : 0
            },
            "pbrMetallicRoughness" : {
                "baseColorTexture" : {
                    "index" : 13,
                    "texCoord" : 0
                },
                "metallicRoughnessTexture" : {
                    "index" : 14,
                    "texCoord" : 0
                }
            }
        },
        {
            "doubleSided" : true,
            "emissiveFactor" : [
                1,
                1,
                1
            ],
            "emissiveTexture" : {
                "index" : 15,
                "texCoord" : 0
            },
            "name" : "KB3D_HTS_LightBlue",
            "normalTexture" : {
                "index" : 16,
                "texCoord" : 0
            },
            "pbrMetallicRoughness" : {
                "baseColorTexture" : {
                    "index" : 17,
                    "texCoord" : 0
                },
                "metallicRoughnessTexture" : {
                    "index" : 18,
                    "texCoord" : 0
                }
            }
        }
    ]

JME Material Definition: (The last one is the emissive one)

Material for KB3D_HTS_Lamp_A_Main_0
Material[name=KB3D_HTS_MetalGrey, def=PBR Lighting, tech=null]
	Float EmissivePower : 3.0
	Boolean BackfaceShadows : false
	Float Roughness : 1.0
	Float EmissiveIntensity : 2.0
	Float Glossiness : 1.0
	Vector4 BaseColor : 1.0 1.0 1.0 1.0
	Float ParallaxHeight : 0.05
	Float Metallic : 1.0
	Float NormalType : 1.0
	Vector4 Emissive : 0.0 0.0 0.0 1.0
	Texture2D NormalMap : Texture2D[name=image0.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D BaseColorMap : Texture2D[name=image1.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D MetallicRoughnessMap : Texture2D[name=image2.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Vector4 Specular : 1.0 1.0 1.0 1.0
Material for KB3D_HTS_Lamp_A_Main_1
Material[name=KB3D_HTS_MetalLight, def=PBR Lighting, tech=null]
	Float EmissivePower : 3.0
	Boolean BackfaceShadows : false
	Float Roughness : 1.0
	Float EmissiveIntensity : 2.0
	Float Glossiness : 1.0
	Vector4 BaseColor : 1.0 1.0 1.0 1.0
	Float ParallaxHeight : 0.05
	Float Metallic : 1.0
	Float NormalType : 1.0
	Vector4 Emissive : 0.0 0.0 0.0 1.0
	Texture2D NormalMap : Texture2D[name=image3.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D BaseColorMap : Texture2D[name=image4.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D MetallicRoughnessMap : Texture2D[name=image5.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Vector4 Specular : 1.0 1.0 1.0 1.0
Material for KB3D_HTS_Lamp_A_Main_2
Material[name=KB3D_HTS_MetalWhite, def=PBR Lighting, tech=null]
	Float EmissivePower : 3.0
	Boolean BackfaceShadows : false
	Float Roughness : 1.0
	Float EmissiveIntensity : 2.0
	Float Glossiness : 1.0
	Vector4 BaseColor : 1.0 1.0 1.0 1.0
	Float ParallaxHeight : 0.05
	Float Metallic : 1.0
	Float NormalType : 1.0
	Vector4 Emissive : 0.0 0.0 0.0 1.0
	Texture2D NormalMap : Texture2D[name=image6.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D BaseColorMap : Texture2D[name=image7.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D MetallicRoughnessMap : Texture2D[name=image8.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Vector4 Specular : 1.0 1.0 1.0 1.0
Material for KB3D_HTS_Lamp_A_Main_3
Material[name=KB3D_HTS_MetalYellow, def=PBR Lighting, tech=null]
	Float EmissivePower : 3.0
	Boolean BackfaceShadows : false
	Float Roughness : 1.0
	Float EmissiveIntensity : 2.0
	Float Glossiness : 1.0
	Vector4 BaseColor : 1.0 1.0 1.0 1.0
	Float ParallaxHeight : 0.05
	Float Metallic : 1.0
	Float NormalType : 1.0
	Vector4 Emissive : 0.0 0.0 0.0 1.0
	Texture2D NormalMap : Texture2D[name=image9.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D BaseColorMap : Texture2D[name=image10.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D MetallicRoughnessMap : Texture2D[name=image11.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Vector4 Specular : 1.0 1.0 1.0 1.0
Material for KB3D_HTS_Lamp_A_Main_4
Material[name=KB3D_HTS_PlasticWhite, def=PBR Lighting, tech=null]
	Float EmissivePower : 3.0
	Boolean BackfaceShadows : false
	Float Roughness : 1.0
	Float EmissiveIntensity : 2.0
	Float Glossiness : 1.0
	Vector4 BaseColor : 1.0 1.0 1.0 1.0
	Float ParallaxHeight : 0.05
	Float Metallic : 1.0
	Float NormalType : 1.0
	Vector4 Emissive : 0.0 0.0 0.0 1.0
	Texture2D NormalMap : Texture2D[name=image12.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D BaseColorMap : Texture2D[name=image13.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D MetallicRoughnessMap : Texture2D[name=image14.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Vector4 Specular : 1.0 1.0 1.0 1.0
Material for KB3D_HTS_Lamp_A_Main_5
Material[name=KB3D_HTS_LightBlue, def=PBR Lighting, tech=null]
	Float EmissivePower : 3.0
	Boolean BackfaceShadows : false
	Float Roughness : 1.0
	Float EmissiveIntensity : 2.0
	Texture2D EmissiveMap : Texture2D[name=image15.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Float Glossiness : 1.0
	Vector4 BaseColor : 1.0 1.0 1.0 1.0
	Float ParallaxHeight : 0.05
	Float Metallic : 1.0
	Float NormalType : 1.0
	Vector4 Emissive : 1.0 1.0 1.0 1.0
	Texture2D NormalMap : Texture2D[name=image16.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D BaseColorMap : Texture2D[name=image17.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Texture2D MetallicRoughnessMap : Texture2D[name=image18.png, image=Image[size=4096x4096, format=BGR8]]:returned null key
	Vector4 Specular : 1.0 1.0 1.0 1.0

Test code used:
EmissionTest.java

package io.tlf.jme.test;

import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.MatParam;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;

public class EmissionTest extends SimpleApplication {

    private boolean cursor = false;

    @Override
    public void simpleInitApp() {
        //Import char
        Spatial lamp = assetManager.loadModel("Models/kitbash3d/KB3D_HiTechStreets-Native_lamp.gltf");

        Node world = new Node("world");
        //Load lighting
        JmeLightingStateNight lightingState = new JmeLightingStateNight();
        stateManager.attach(lightingState);

        printMaterial(lamp);

        //Add to world
        world.attachChild(lamp);

        rootNode.attachChild(world);

        cam.setLocation(new Vector3f(0, 10f, 50f));
        cam.setFrustumFar(5000f);
        flyCam.setMoveSpeed(20f);


        ActionListener tab = new ActionListener() {
            @Override
            public void onAction(String name, boolean isPressed, float tpf) {
                if (!isPressed) {
                    cursor = !cursor;
                    flyCam.setEnabled(cursor);
                }
            }
        };
        inputManager.addMapping("tab", new KeyTrigger(KeyInput.KEY_TAB));
        inputManager.addListener(tab, "tab");

    }

    public void printMaterial(Spatial s) {
        if (s instanceof Node) {
            for (Spatial c : ((Node) s).getChildren()) {
                printMaterial(c);
            }
        } else if (s instanceof Geometry) {
            Material mat  = ((Geometry) s).getMaterial();
            System.out.println("Material for " + s.getName());
            System.out.println(mat.toString());
            for (MatParam param : mat.getParams()) {
                System.out.println("\t" + param.toString());
            }
        }
    }

    public static void main(String[] args) {
        EmissionTest main = new EmissionTest();
        main.start();
    }
}

JmeLightingStateNight.java

package io.tlf.jme.test;

import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.BaseAppState;
import com.jme3.environment.EnvironmentCamera;
import com.jme3.environment.LightProbeFactory;
import com.jme3.environment.generation.JobProgressAdapter;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.light.LightProbe;
import com.jme3.light.SphereProbeArea;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.FXAAFilter;
import com.jme3.post.filters.ToneMapFilter;
import com.jme3.post.ssao.SSAOFilter;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.shadow.DirectionalLightShadowFilter;
import com.jme3.shadow.DirectionalLightShadowRenderer;
import com.jme3.shadow.EdgeFilteringMode;
import com.jme3.util.SkyFactory;

/**
 * @author Trevor Flynn trevorflynn@liquidcrystalstudios.com
 */
public class JmeLightingStateNight extends BaseAppState {

    private DirectionalLight dl;
    private SimpleApplication app;
    private FilterPostProcessor fpp;
    private EnvironmentCamera envCam;
    private LightProbe probe;
    private Node lightingNode;

    private short renderSteps = 0;
    private int probeRadius = 5000;
    private boolean probing = true;

    @Override
    protected void initialize(Application a) {
        app = (SimpleApplication) a;
        app.getViewPort().setBackgroundColor(ColorRGBA.Black);
        lightingNode = (Node) app.getRootNode().getChild("world"); //For iso-test
        lightingNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);

        //AmbientLight al = new AmbientLight();
        //al.setColor(ColorRGBA.DarkGray.mult(0.3f));
        //lightingNode.addLight(al);

        dl = new DirectionalLight();
        dl.setDirection(new Vector3f(-1, -1, -1));
        lightingNode.addLight(dl);
        dl.setColor(ColorRGBA.DarkGray);

        final int SHADOWMAP_SIZE = 2048;
        DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(app.getAssetManager(), SHADOWMAP_SIZE, 4);
        dlsr.setLight(dl);
        dlsr.setLambda(0.55f);
        dlsr.setShadowIntensity(0.8f);
        dlsr.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
        //dlsr.displayDebug();
        app.getViewPort().addProcessor(dlsr);

        DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(app.getAssetManager(), SHADOWMAP_SIZE, 4);
        dlsf.setLight(dl);
        dlsf.setLambda(0.55f);
        dlsf.setShadowIntensity(0.8f);
        dlsf.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
        dlsf.setEnabled(true);
        //Filter
        fpp = new FilterPostProcessor(app.getAssetManager());
        fpp.addFilter(new FXAAFilter());
        fpp.addFilter(new ToneMapFilter(Vector3f.UNIT_XYZ.mult(4.0f)));
        fpp.addFilter(dlsf);
        fpp.addFilter(new SSAOFilter(0.5f, 3, 0.2f, 0.2f));
        app.getViewPort().addProcessor(fpp);


        //Spatial sky = SkyFactory.createSky(app.getAssetManager(), "Textures/Path.hdr", SkyFactory.EnvMapType.EquirectMap);
        //app.getRootNode().attachChild(sky);

        //Env Cam
        envCam = new EnvironmentCamera(256, new Vector3f(0, 3f, 0));
        app.getStateManager().attach(envCam);

        //LightsDebugState debugState = new LightsDebugState();
        //app.getStateManager().attach(debugState);

        //MaterialDebugAppState debug = new MaterialDebugAppState();
        //debug.registerBinding("Common/MatDefs/Light/PBRLighting.frag", app.getRootNode());
        //debug.registerBinding("Common/ShaderLib/PBR.glsllib", app.getRootNode());
        //getStateManager().attach(debug);

    }

    @Override
    protected void cleanup(Application a) {
        app.getRootNode().removeLight(dl);
        app.getViewPort().removeProcessor(fpp);
        app.getStateManager().detach(envCam);
    }

    @Override
    public void update(float tpf) {
        if (probing) {
            renderSteps++;
            if (renderSteps == 2) { //Give the scene a frame to update
                System.out.println("Starting PBR Probe");

                lightingNode.removeFromParent();
                probe = LightProbeFactory.makeProbe(app.getStateManager().getState(EnvironmentCamera.class), app.getRootNode(), new JobProgressAdapter<LightProbe>() {

                    @Override
                    public void done(LightProbe result) {
                        System.out.println("PBR Probe results in");
                    }
                });
                probe.getArea().setRadius(probeRadius);
                app.getRootNode().addLight(probe);
            } else if (renderSteps > 10) {
                app.getRootNode().attachChild(lightingNode);
                probing = false;
                renderSteps = 0;
                System.out.println("PBR Probe Done");
            }
        }
    }

    public void reprobe() {
        probing = true;
    }

    public int getProbeRadius() {
        return probeRadius;
    }

    public void setProbeRadius(int probeRadius) {
        this.probeRadius = probeRadius;
    }

    @Override
    protected void onEnable() {
        dl.setEnabled(true);
        envCam.setEnabled(true);
        reprobe();
        app.getViewPort().addProcessor(fpp);
    }

    @Override
    protected void onDisable() {
        dl.setEnabled(false);
        envCam.setEnabled(false);
        app.getViewPort().removeProcessor(fpp);
        if (probe != null) {
            app.getRootNode().removeLight(probe);
        }
    }

}

Do I perhaps have something in my PBR setup incorrect?

As a test, I just took a solid red metallic cube and used my black marble texture as the emission map:

But now rereading your post, I think maybe you expect too much from emission. It’s never going to “emit light” in the sense that it will light up other things. That’s not what it does.

…though if you have bloom it will ‘glow’ if the intensity is high enough.

2 Likes

Ah OK. I guess I was thinking I could use emission as a light source. So then there is no way to create a custom light source from a mesh? For example light a neon light?

No. And you’ll find that even blender’s PBR material won’t really emit light either. At least not in Evee.

2 Likes

OK, Thank you for the info.

1 Like

even in blender emission is not light source.

Bloom can create some fake of light based on emission.