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?
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.

