Using texture packs

I need help.
I have some assets from texture pack. It consists of

  1. Color
  2. Displacement
  3. Metalness
  4. Normal
  5. Roughness
    Tell me please, how to properly include all that texture maps in my material, in java code.
Material sphereMat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
        sphereMat.setTexture("DiffuseMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Color.jpg"));
        sphereMat.setTexture("NormalMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_NormalGL.jpg"));
        sphereMat.setTexture("SpecularMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Metalness.jpg"));
        sphereMat.setTexture("ParallaxMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Displacement.jpg"));
        sphereMat.setTexture("LightMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Roughness.jpg"));

Is it right?
And how to include
6. ambient occlusion map, if it exists in pack too.

1 Like

I think you want different material definitions. “Lighting.j3md” is for Phong shading. If you have all these textures, you probably want a Physically-Based Rendering material instead.

I suggest:

Material sphereMat = new Material(assetManager, "Common/MatDefs/Light/PBRLighting.j3md");

Ambient occlusion can be handled various ways. “PBRLighting.j3md” allows it to be packed into the light map if you set “LightMapAsAOMap” to true.

That’s about the limit of my knowledge. I hope someone who knows more will respond now.

1 Like

Thank you. I already have some progress. But I can’t find documentation on
PBRLighting.j3md. Problems are, that PBRLighting don’t have DiffuseMap parameter as well as Shiniess, Ambient and Diffuse colors. I guess I need to replace DiffuseMap with BaseColorMap, but I do not sure at all. Some code for reference

Sphere sphereMesh = new Sphere(32,32, 4f);
        Geometry sphereGeo = new Geometry("Shiny rock", sphereMesh);
        sphereMesh.setTextureMode(Sphere.TextureMode.Projected); // better quality on spheres
        TangentBinormalGenerator.generate(sphereMesh);           // for lighting effect
        Material sphereMat = new Material(assetManager, "Common/MatDefs/Light/PBRLighting.j3md");
        sphereMat.setTexture("BaseColorMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Color.jpg"));
        sphereMat.setTexture("NormalMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_NormalGL.jpg"));
        sphereMat.setTexture("MetallicMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Metalness.jpg"));
        sphereMat.setTexture("ParallaxMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Displacement.jpg"));
        sphereMat.setTexture("RoughnessMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Roughness.jpg"));
        sphereMat.setColor("Specular",ColorRGBA.White);
        sphereGeo.setMaterial(sphereMat);
        sphereGeo.setLocalTranslation(0,2,-2); // Move it a bit
        sphereGeo.rotate(1.6f, 0, 0);          // Rotate it a bit
        rootNode.attachChild(sphereGeo);
        
        /** Must add a light to make the lit object visible! */
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(1,0,-2).normalizeLocal());
        sun.setColor(ColorRGBA.White);
        rootNode.addLight(sun);
        
        // We add light so we see the scene
        AmbientLight al = new AmbientLight();
        al.setColor(ColorRGBA.White.mult(1.3f));
        rootNode.addLight(al);

There unfortunately is not any basic documentation on the PBRLighting.j3md shader (as far as I’m aware) but there is a 3 part article in the jme wiki that the developer of JME’s pbr shaders wrote while developing the shader. The first part of the article (Physically Based Rendering – Part one :: jMonkeyEngine Docs) does a pretty good job of introducing the PBR workflow and explaining how it differs from the usual diffuse-spec-ambient. The second and third part of the articles are a bit more technical and go beyond the scope of what you need to know so they might not have as much useful information as part 1, but could still be useful to check out.

You appear to be on the correct path so far, but here is a quick run-down on how you’d use each of these textures with the metallic/roughness workflow in PBRLighting.j3md:

In PBR you would define these as:

  1. BaseColorMap (often referred to as an albedoMap in other pbr implementations, but jme’s shader calls it the BaseColorMap)

  2. ParallaxMap (can also be packed in the alpha channel of the normal Map if you set the matParm “PackedNormalParallax” to true)

  3. MetallicMap (gets multiplied by the float matParam called “Metallic”)

  4. NormalMap

  5. RoughnessMap (gets multiplied by the float matParam called “Roughness”)

  6. A) LightMap (need to set matParam “LightMapAsAOMap” true to tell shader light map is being used as AO)
    B). MetallicRoughnessMap. You also have the option to pack the AmbientOcclusion, Roughness, and Metallic values into a single texture, and then set the matParam “AoPackedInMRMap” to true.

And there is also an EmissiveMap that can be used interchangebly with a GlowMap.

If you ever have trouble remembering the exact name of a material paramater, you can also reference the source code for PBRLighting.j3md to see a basic list of all valid MaterialParamaters that the shader uses https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md. If you take a look at the top of that j3md file then you should see all of the important PBR textures I mentioned defined as Texture2D variable types. Hopefully this helps :slightly_smiling_face:

Edit: also forgot to mention that if you’re using the SDK, you can open up a material file that’s using the pbr shader to see a list of all its MaterialParamater’s in a GUI based material editor.

2 Likes

Thank you. I did this in code, but material appeared completely black, but must be gold.
Looks like BaseColorMap don’t do proper work. I watched documentation on PBRLighting, but did not find any boolean trigger or other suitable map. Do I need to do something else?

        Sphere sphereMesh = new Sphere(32,32, 4f);
        Geometry sphereGeo = new Geometry("Shiny rock", sphereMesh);
        sphereMesh.setTextureMode(Sphere.TextureMode.Projected); // better quality on spheres
        TangentBinormalGenerator.generate(sphereMesh); 
        Material sphereMat = new Material(assetManager, "Common/MatDefs/Light/PBRLighting.j3md");
        sphereMat.setTexture("BaseColorMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Color.jpg"));
        sphereMat.setTexture("NormalMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_NormalDX.jpg"));
        sphereMat.setTexture("MetallicMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Metalness.jpg"));
        sphereMat.setTexture("ParallaxMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Displacement.jpg"));
        sphereMat.setTexture("RoughnessMap", assetManager.loadTexture("Materials/metal/Metal042A_1K_Roughness.jpg"));
        sphereGeo.setMaterial(sphereMat);

1 Like

It looks like the scene still needs a light probe. The LightProbe is actually what determines the ambient lighting in the scene, and the AmbientLight is just used for scaling LightProbes.

I don’t think the wiki mentions much about light probes, the documentation still hasn’t been updated to include much about PBR. But there is this video that does a good job explaining light probes using the JME SDK.

And there are also 2 light probes included in jmonkey’s test-data library that you can use for testing until you generate your own light probes that match your scene.

3 Likes

Ok. I had some progress and again bumped in the new problem.
Right sphere must looks brown-ish but it looks silver-ish. When I turned off DirectionalLight and left only Light probe and AmbientLight, right sphere starts to look better, more as intended.

  1. How right sphere must look
  2. How it looks with DirectionalLight
  3. How it looks without DirectionalLight, only leaving AmbientLight

PBR uses both the directional light and light probe, but It looks like the one in the middle has its metallic and roughness value set differently than the one you’re trying to match on the left.

But it’s hard to tell without seeing the code you’re using to create the material, if you post that it should help figure out what’s going wrong.

1 Like

Right… It’s not very clear what I’m complaining about, looking on this pictures. But light reflection appears too bright, unrealistically strong and shiny, despite this material is very rough and dark. That light makes brown material looks as silver. And only with dim light material looks right.

The lighting can also vary drastically depending on the color and brightness of the LightMap’s cubeMap texture.

Are you using the light probe from jme-test-data called defaultProbe or the one called quarryProbe? Or did you generate your own?

1 Like

Thank you once again. I pretty sure that problem lies in lighting aspect. I’m not familiar with lighting setup and setting yet, and I was confused with appearance of material what I was not expected. I just want more soft, dispersed and scattered light. With that kind of light, I pretty sure textures start to look right.

I used that snipped from some post in this forum.

                        
        EnvironmentCamera envCam = new EnvironmentCamera(); //Make an env camera
        stateManager.attach(envCam);
        envCam.initialize(stateManager, this); //Manually initilaize so we can add a probe before the next update happens
        LightProbe probe = LightProbeFactory.makeProbe(envCam, rootNode);
        probe.getArea().setRadius(100); //Set the probe's radius in world units
        probe.setPosition(new Vector3f(1, 0, -2)); //Position it in 3d space
        rootNode.addLight(probe);

Generating a light probe from your own scene can be tricky.

I’ve found that I never get good results if I try to gnerate a light probe from a scene that isn’t decorated enough, in that case the lightProbe just ends up being primarily the color of the sky and causes the ambient lighting to be a dull grayish blue like what seems to have happened in your case. I also usually brighten my scenes drastically before generating a lightProbe to make sure the resulting probe isn’t way too dim for the scene.

But I would suggest using the lightProbe in jme-test-data named “defaultProbe.j3o” for testing things, since it is very bright and will always do a good job at bringing out a material’s color and shininess.

2 Likes

looking at screenshot. Roughness and Metalness seems to be working.

NormalMap idk, maybe work, hard to tell based on screenshot, but you use DX and im not sure if it refer to DirectX that might cause inverted values or something.

Parallax seems to be not working, so you probably need more parameters or something else, i dont remember. (sorry cant help here, using custom parallax pbr shader)

Summary:

  1. You need better test light probe - light probe is thing that affect metalness colors (if you want color less dependent on light probe, then lower metalness value)
  2. You need fix parallax
1 Like

Have you any code examples to load “defaultProbe.j3o”? because I don’t know how.

1 Like

Thank you. That defaultProbe.j3o looks awesome. It’s a pity that it is not my scenery :smile:

1 Like

If you look through the list of probes in my link, sometimes you can find one close enough or generic enough to match.

It’s boring but the “studio” one will at least have some nice highlights without putting really different reflections in your shiny metal stuff.

1 Like