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.
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:
BaseColorMap (often referred to as an albedoMap in other pbr implementations, but jme’s shader calls it the BaseColorMap)
ParallaxMap (can also be packed in the alpha channel of the normal Map if you set the matParm “PackedNormalParallax” to true)
MetallicMap (gets multiplied by the float matParam called “Metallic”)
NormalMap
RoughnessMap (gets multiplied by the float matParam called “Roughness”)
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
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.
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);
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.
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.
How right sphere must look
How it looks with DirectionalLight
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.
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.
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.
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.
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:
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)