The server has more than 3000 models and each of them has several colors of material. I need to load separately models and textures and set textures depending on the user's choice. How to change baseColorMap, normalMap, metallicMap, roughnessMap in runtime?
after modelRenderable.getMaterial().setTexture("normalMap", normalMap.get()); nothing happens I'm doing something wrong. There is no information in documentation for that.
Hi @alexeyfaradise, thank you for submitting this issue.
setTexture() appears to not work: Unfortunately this part of our API is still a little rough; it works but is very easy to get wrong. We're working on a sample to illustrate how to modify material parameters (including textures) at runtime and will improve our error reporting in the next release..sfb. We'll be releasing a blog post soon on how to do this..sfa will get the ability to contain loose textures and materials not explicitly associated with geometry, and .sfa's will be able to declare data dependencies on other .sfa's. This will mean that you can author (and deliver) .sfb's that contain textures/materials (but no geometry) and .sfb's that contain geometry (but no textures/materials), and if they're both available at instantiation time it will just work.Hey @alexeyfaradise, can you please post the contents of the .sfa file for the model you are testing with?
You can change the texture of the sample "andy" model at runtime using the following code in HelloSceneformActivity.java:
CompletableFuture<Texture> brickFuture = Texture.builder().setSource(this, R.drawable.bricks).build();
// When you build a Renderable, Sceneform loads its resources in the background while returning
// a CompletableFuture. Call thenAccept(), handle(), or check isDone() before calling get().
ModelRenderable.builder()
.setSource(this, R.raw.andy)
.build()
.thenAcceptBoth(brickFuture, (renderable, texture) -> {
andyRenderable = renderable;
andyRenderable.getMaterial().setTexture("baseColor", texture);
})
.exceptionally(
throwable -> {
Toast toast =
Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return null;
});
If your source assets are more complicated, the names of the material parameters could be different. However, those names should match what is in the .sfa file.
Hello @dsternfeld7 ,
I would like to change textures on a simple box.obj at runtime. But, I cannot get it working. My cube is red as specified in the sfa file, but the texture is not applied at runtime. Could you give me a hint, please? This would be nice.
I tried the following code:
Sceneform SDK 1.3.0
CompletableFuture<Texture> futureTexture = Texture.builder()
.setSource(this, R.drawable.ic_launcher)
.build();
ModelRenderable.builder()
.setSource(this, R.raw.box)
.build()
.thenAcceptBoth(futureTexture, (renderable, texture) -> {
boxRenderable = renderable;
boxRenderable.getMaterial().setTexture("baseColor", texture);
})
.exceptionally(
throwable -> {
Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG).show();
return null;
});
The box.sfa file looks like:
{
materials: [
{
name: "unlit_material",
parameters: [
{
baseColor: "box",
},
{
baseColorTint: [
1,
0,
0,
1,
],
},
{
metallic: 1,
},
{
roughness: 1,
},
{
opacity: null,
},
],
source: "build/sceneform_sdk/default_materials/obj_material.sfm",
},
],
model: {
attributes: [
"Position",
"TexCoord",
"Orientation",
],
file: "sampledata/box.obj",
name: "box",
suggested_collision: {
center: {
x: 0,
y: 0,
z: 0,
},
size: {
x: 1,
y: 1,
z: 1,
},
type: "Box",
},
},
version: "0.51:1",
}
@dsternfeld7
Should your code above also work with a ModelRenderable created with the ShapeFactory?
@michaelvogt I tried a texture change on a primitive cube instantiated with ShapeFactory. It is working.
Check the last line of my code snippet here
https://github.com/google-ar/sceneform-android-sdk/issues/197
(Sorry for pasting the link. I am new to GitHub and have not yet found the button to reference a different thread here.)
@Berenice2018
Excellent, thank you.
@Berenice2018 @AdrianAtGoogle can you please take a look at #448. It seems similar, but I can't understand how the ones discussed here can be applied to there. I'm just beginning to use Sceneform.
Thanks in advance.
@alexeyfaradise what solution did you used for this problem?
This feature works ?
To me it looks like setTexture() btw. setMaterial() only work on the renderables created via ShapeFactory
Most helpful comment
Hi @alexeyfaradise, thank you for submitting this issue.
setTexture()appears to not work: Unfortunately this part of our API is still a little rough; it works but is very easy to get wrong. We're working on a sample to illustrate how to modify material parameters (including textures) at runtime and will improve our error reporting in the next release..sfb. We'll be releasing a blog post soon on how to do this..sfawill get the ability to contain loose textures and materials not explicitly associated with geometry, and.sfa's will be able to declare data dependencies on other.sfa's. This will mean that you can author (and deliver).sfb's that contain textures/materials (but no geometry) and.sfb's that contain geometry (but no textures/materials), and if they're both available at instantiation time it will just work.