Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request:Add Water PBR material #17

Closed
Ali-RS opened this issue Jan 12, 2020 · 13 comments
Closed

Feature request:Add Water PBR material #17

Ali-RS opened this issue Jan 12, 2020 · 13 comments
Labels
enhancement New feature or request
Milestone

Comments

@Ali-RS
Copy link
Contributor

Ali-RS commented Jan 12, 2020

It will be nice to add a PBR version of the water material. :)

@Ali-RS Ali-RS changed the title Add Water PBR material Feature request:Add Water PBR material Jan 12, 2020
@rvandoosselaer rvandoosselaer added this to the v1.4.0 milestone Mar 5, 2020
@rvandoosselaer rvandoosselaer added the enhancement New feature or request label Mar 5, 2020
@rvandoosselaer
Copy link
Owner

rvandoosselaer commented Mar 6, 2020

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.

@Ali-RS
Copy link
Contributor Author

Ali-RS commented Mar 6, 2020

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?

@rvandoosselaer
Copy link
Owner

rvandoosselaer commented Mar 6, 2020

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.

@Ali-RS
Copy link
Contributor Author

Ali-RS commented Mar 6, 2020

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);

@Ali-RS
Copy link
Contributor Author

Ali-RS commented Mar 6, 2020

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.

@Ali-RS
Copy link
Contributor Author

Ali-RS commented Mar 6, 2020

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.

@rvandoosselaer
Copy link
Owner

Awesome explanation, thanks! I’ll try to create an example with this info.

I hope to get this update released soon.

@Ali-RS
Copy link
Contributor Author

Ali-RS commented Mar 6, 2020

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:

@Ali-RS
Copy link
Contributor Author

Ali-RS commented Mar 7, 2020

@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);

@rvandoosselaer
Copy link
Owner

rvandoosselaer commented Mar 8, 2020

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.

@Ali-RS
Copy link
Contributor Author

Ali-RS commented Mar 9, 2020

Thanks, going to try it soon :)

@Ali-RS
Copy link
Contributor Author

Ali-RS commented Mar 9, 2020

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.

@rvandoosselaer
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants