Closed Ali-RS closed 4 years ago
Could you help me with creating a PBR water material @Ali-RS ? I made some changes to the TypeRegistry
(see #23) so it's possible to load custom materials for a block.
I would like to create a new example showcasing how you can use a PBR material as a type for a block. I guess a water block is an ideal example for this.
Could you help me with creating a PBR water material @Ali-RS ?
Do you mean you need help with the shader side?
tbh, I have not worked with shaders so I am not sure if I can be of any help. If I am understanding it right, you just copied Lighting material frag and vert shaders and modified it for your water material, can't the same thing be done for PBR too?
I meant more in general. I haven’t worked with PBR materials before and have not yet looked into it. I don’t know what settings or lights you need to supply to make it look good. You have lights, lightprobes, environment maps, ... It’s still a bit unclear for me.
The shader part to simulate waves, I can adapt later.
I meant more in general. I haven’t worked with PBR materials before and have not yet looked into it. I don’t know what settings or lights you need to supply to make it look good. You have lights, lightprobes, environment maps, ... It’s still a bit unclear for me.
Ah, yes, I can help with this stuff.
You can read about PBR workflow in JME wiki:
https://wiki.jmonkeyengine.org/jme3/advanced/pbr_part1.html# (it's in 3 parts)
In short, the light probe is the thing that contains environment map data. You can use a pre-generated light probe or generate your own light probe.
Then you can attach the light probe to the root node as you do for regular lights. (you can also add directional (if you want shadow or using have normal map on your models) and ambient light (for adjusting env map lighting i.e day/night lighting).
For generating a light probe you just need to attach a SkyBox into the scene and run this code:
Here is an example code of how to generate and export light probe into j3o:
public class LightProbExporter extends SimpleApplication {
private Timer makeProbeTimer;
@Override
public void simpleInitApp() {
initSky();
initLight();
}
@Override
public void simpleUpdate(float tpf) {
makeProbeTimer.update(tpf);
}
public static void main(String[] args) {
LightProbExporter app = new LightProbExporter();
app.start();
}
private void initLight() {
final EnvironmentCamera envCam = new EnvironmentCamera(256, Vector3f.ZERO);
stateManager.attach(envCam);
makeProbeTimer = new Timer();
makeProbeTimer.schedule(new TimerTask() {
@Override
public void run(long time) {
final LightProbe probe = LightProbeFactory.makeProbe(stateManager.getState(EnvironmentCamera.class), rootNode, EnvMapUtils.GenerationType.Fast, new JobProgressAdapter<LightProbe>() {
@Override
public void done(LightProbe result) {
System.out.println("Done rendering env maps");
//Saving
Node probeNode = new Node("lightprobe node");
probeNode.addLight(result);
BinaryExporter ex = new BinaryExporter();
try {
ex.save(probeNode, new File("path to file/probe.j3o"));
System.out.println("Done exporting env maps");
} catch (IOException e) {
e.printStackTrace();
}
//done saving
}
});
((SphereProbeArea) probe.getArea()).setRadius(500);
rootNode.addLight(probe);
makeProbeTimer.setEnable(false);
}
}, 5);
}
private void initSky() {
/*Texture west = assetManager.loadTexture("envmap/fantasy/Sunny_01A_left.tga");
Texture east = assetManager.loadTexture("envmap/fantasy/Sunny_01A_right.tga");
Texture north = assetManager.loadTexture("envmap/fantasy/Sunny_01A_back.tga");
Texture south = assetManager.loadTexture("envmap/fantasy/Sunny_01A_front.tga");
Texture up = assetManager.loadTexture("envmap/fantasy/Sunny_01A_up.tga");
Texture down = assetManager.loadTexture("envmap/fantasy/Sunny_01A_down.tga");*/
//Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down);
//Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", SkyFactory.EnvMapType.CubeMap);
Spatial sky = SkyFactory.createSky(assetManager, "Textures/sky/outside.hdr", SkyFactory.EnvMapType.EquirectMap);
rootNode.attachChild(sky);
}
}
and load it like below:
Node probeNode = (Node) assetManager.loadModel("Scenes/lightprobe/probe.j3o");
LightProbe probe = (LightProbe) probeNode.getLocalLightList().iterator().next();
probe.setPosition(new Vector3f(0, 0, 0));
probe.getArea().setRadius(500);
rootNode.addLight(probe);
Regarding the material parameters, you have BaseColorMap, it's the same DiffuseMap we have in Phong lighting.
You can adjust the metalness of the material using the "Metallic" parameter. It's a float value in [0,1]. You can adjust the roughness of the material using the "Roughness" parameter. It's a float value in [0,1].
You can optionally use Normal and Parallex textures (same as Phong lighting) and MetallicRoughness map.
Also, you can see some PBR examples here: https://github.com/jMonkeyEngine/jmonkeyengine/tree/master/jme3-examples/src/main/java/jme3test/light/pbr
And here are some pre-generated light probes: lightprobes.zip
Please feel free to ask if you have any questions.
Awesome explanation, thanks! I’ll try to create an example with this info.
I hope to get this update released soon.
You're welcome.
btw, in case you need, here you can download a free water texture: https://lowlypoly.com/collections/free/products/stylized-water-texture
Some useful tips:
For an emissive map to work in PBR you need to set up the bloom filter to GlowMode.Scene
bloom = new BloomFilter(BloomFilter.GlowMode.Scene);
@rvandoosselaer I forgot to mention that you also need to add this in simpleInitApp()
:
// Configure the scene for PBR
renderManager.setPreferredLightMode(TechniqueDef.LightMode.SinglePassAndImageBased);
renderManager.setSinglePassLightBatchSize(10);
I committed a PBR test case in the examples subproject. If you have remarks or improvements please let me know. Will test some more myself (still need to test with a ‘spritesheet’ texture) and begin preparing for a release.
I did notice that the parallax mapping doesn’t appear to be working.
Thanks, going to try it soon :)
Just tried it, looks very nice :)
I did notice that the parallax mapping doesn’t appear to be working.
It does work with original PBRLighting material. Maybe something has broken while adapting it for water.
It does work with original PBRLighting material. Maybe something has broken while adapting it for water.
You were correct, there was an issue in the fragment shader, it's fixed.
It will be nice to add a PBR version of the water material. :)