Sceneform 1.16 GLTF change Texture

Viewed 742

I am currently working on an AR app that should be able to display GLTF/GLB models, play its animations and change its textures. Since I am new to rendering and working with 3D models, I need some help here.

Because animations are not supported in Sceneform 1.15 / Sceneform 1.17.1, I need to use Sceneform 1.16, because I have access to the filamentAsset here, which allows me to access the animations of an GLB object.

Now, the app should be able to change the look of an object if the user wants to, which means I need to change the texture of a materialInstance of the filamentAsset (submeshcount in Sceneform 1.16 is always 0, so texture change using the sceneform functionality does not work).

Here is what I got so far:

I start with saving the filamentAsset after creating the Sceneform renderable:

private void addModel(Anchor anchor, ModelRenderable modelRenderable) {
        // Creating a AnchorNode with a specific anchor
        AnchorNode anchorNode = new AnchorNode(anchor);

        // attaching the anchorNode with the ArFragment
        anchorNode.setParent(arCam.getArSceneView().getScene());

        // attaching the anchorNode with the TransformableNode
        TransformableNode model = new TransformableNode(arCam.getTransformationSystem());
        model.setParent(anchorNode);

        // attaching the 3d model with the TransformableNode
        // that is already attached with the node
        model.setRenderable(modelRenderable);
        model.select();

        // Saving the object as filament asset
        // -> Possibility to run animations and change textures
        filamentAsset = model.getRenderableInstance().getFilamentAsset();
    }

When the user clicks the button, following method is called:

public void changeMaterials() {
        textureBC = loadTexture(engine, R.drawable.avocado_basecolor);
        MaterialInstance[] materialInstances = filamentAsset.getMaterialInstances();

        TextureSampler textureSampler = new TextureSampler();
        textureSampler.setWrapModeR(TextureSampler.WrapMode.REPEAT);
        textureSampler.setWrapModeS(TextureSampler.WrapMode.REPEAT);
        textureSampler.setWrapModeT(TextureSampler.WrapMode.REPEAT);

        for (MaterialInstance materialInstance : materialInstances) {
            materialInstance.setParameter("baseColorMap", textureBC, textureSampler);
        }
    }

My loadTexture() method looks like this (Basically copied from filament github): The resourceId points to a PNG

private com.google.android.filament.Texture loadTexture(Engine engine, int resourceId) {
        Resources resources = getResources();

        Bitmap bitmap = BitmapFactory.decodeResource(resources, resourceId, null);
        
        com.google.android.filament.Texture texture = new com.google.android.filament.Texture.Builder()
                .width(bitmap.getWidth())
                .height(bitmap.getHeight())
                .sampler(Texture.Sampler.SAMPLER_2D)
                .format(Texture.InternalFormat.SRGB8_A8) // It is crucial to use an SRGB format.
                .levels(0xff) // tells Filament to figure out the number of mip levels
                .build(engine);

        TextureHelper.setBitmap(engine, texture, 0, bitmap);

        texture.generateMipmaps(engine);
        return texture;
    }

The problem is that the model is completely black after I call the changeMaterials() method. What am I doing wrong?

Before texture change: Model before texture change

After texture change: Model after texture change

As an example I used this avocado model. As an input for the loadTexture method I used this image of the avocado GLTF and changed some colors to check, whether the texture change is working.

0 Answers
Related