jMonkeyEngine / jmonkeyengine

A complete 3-D game development suite written in Java.
http://jmonkeyengine.org
BSD 3-Clause "New" or "Revised" License
3.83k stars 1.12k forks source link

TextureAtlas class for PBR / custom materials #1263

Open oxplay2 opened 4 years ago

oxplay2 commented 4 years ago

recently @yaRnMcDonuts had issues to use TextureAtlas generator for his PBR models.

not sure if issue or feature.

but: Geometry geom = TextureAtlas.makeAtlasBatch(scene, assetManager, 2048);

within TextureAtlass class, it refer only for Lightning.j3md material.

i would suggest do one of below options:

imo last option sounds best. - reasons:

below is Lightning.j3md related code:

    public boolean addGeometry(Geometry geometry) {
        Texture diffuse = getMaterialTexture(geometry, "DiffuseMap");
        Texture normal = getMaterialTexture(geometry, "NormalMap");
        Texture specular = getMaterialTexture(geometry, "SpecularMap");
        if (diffuse == null) {
            diffuse = getMaterialTexture(geometry, "ColorMap");

        }
        if (diffuse != null && diffuse.getKey() != null) {
            String keyName = diffuse.getKey().toString();
            if (!addTexture(diffuse, "DiffuseMap")) {
                return false;
            } else {
                if (normal != null && normal.getKey() != null) {
                    addTexture(normal, "NormalMap", keyName);
                }
                if (specular != null && specular.getKey() != null) {
                    addTexture(specular, "SpecularMap", keyName);
                }
            }
            return true;
        }
        return true;
    }

and:

        Material mat = new Material(mgr, "Common/MatDefs/Light/Lighting.j3md");
        Texture diffuseMap = atlas.getAtlasTexture("DiffuseMap");
        Texture normalMap = atlas.getAtlasTexture("NormalMap");
        Texture specularMap = atlas.getAtlasTexture("SpecularMap");
        if (diffuseMap != null) {
            mat.setTexture("DiffuseMap", diffuseMap);
        }
        if (normalMap != null) {
            mat.setTexture("NormalMap", normalMap);
        }
        if (specularMap != null) {
            mat.setTexture("SpecularMap", specularMap);
        }
        mat.setFloat("Shininess", 16.0f);
yaRnMcDonuts commented 2 years ago

I'm thinking of working on this issue soon unless anyone else has started, and I'm in the early planning stages.

I agree that the last proposal of yours sounds like the best way to do it.

The only concern I have is with the way this utility currently works to create the batch at the same time as the atlas. I'm not sure if I would be better off making an entirely new utility and just use the old converter as a reference.

The way it currently works seems to be great if you only have one set of objects that need batched - but in a large scene where you might have several of the same models occurring in more than one batch, then you will end up with an entirely new Texture Atlas and new material for every new batch, even though those batches might have many of the same models/textures, so if you create a scene with 10 batched foilage squares (separated into squared areas for distance culling) then you would end up with 10 very similar texture atlases, although they may not be interchangeable, and that would be a lot of extra memory usage that could be saved if they all just shared a texture atlas

So unless I'm misunderstanding anything, then I think I will need to rewrite the whole utility so that it doesn't actually batch the models, but so it would instead just create the texture atlas and a new folder containing individual copies of the models (with adjusted texCoords to match the atlas of course) that use the same material with the new texture atlas, so then they could be batched together any way at anytime during the scene building process, while all using 1 single material and texture atlas. Essentially separating the batching process from the texture atlas creation process.

Any thoughts?

oxplay2 commented 2 years ago

well, it was long time ago, but as i remember it was just about PBR version of "makeAtlasBatch"