google-ar / sceneform-android-sdk

Sceneform SDK for Android
https://developers.google.com/sceneform/develop/
Apache License 2.0
1.23k stars 604 forks source link

how to set opacity for makeTransparentWithTexture material #196

Closed michaelvogt closed 6 years ago

michaelvogt commented 6 years ago

Hello.

When I create a material with makeTransparentWithColor, I can set the opacity with the alpha parameter of the color. Is there a way to set the opacity of a material created with makeTransparentWithTexture during runtime? The renderable is a ShapeFactory Cube.

Thanks, Michael

claywilkinson commented 6 years ago

Unfortunately, there is no way to affect the opacity of that material. The materialFactory generated materials are intended more for simple materials or placeholders during development.

You can create a custom material for your model that you could set a base texture and then pass in a parameter to affect the final color.

I don't have a sample of that handy, but let me know if you have questions.

michaelvogt commented 6 years ago

Only to make sure I understand correctly: it is not possible to accomplish transparency / translucency with a material from MaterialFactory.makeTransparentWithTexture call? Will this stay like this or are there plans to provide this functionality?

You can create a custom material for your model that you could set a base texture and then pass in a parameter to affect the final color.

As I'm using a ShapeFactory object: Is there a way to create a custom material during runtime?

Or are you suggesting that I should create a simple sfb for example of a plane, create a custom material for it and reuse it throughout the application, instead of using the ShapeFactory?

What I want to accomplish is, that the user can set the translucency of objects with a slider - for example.

dsternfeld7 commented 6 years ago

To clarify, when using makeTransparentWithTexture, the transparency of the material comes from the alpha channel of the texture. My understanding is that what you want is to control the transparency uniformly for the object with a float from 0-1 for use with a slider instead. To do this, you can write a custom material that has a scale factor multiplied against the alpha from the texture.

When writing a custom material, you can add a float parameter called alphaFactor and do this in the fragment block of the material:

material.baseColor = texture(materialParams_texture, getUV0());
material.baseColor.a *= materialParams.alphaFactor;

In regards to creating a custom material at runtime, there is currently no way to load a material outside of an .sfb. However, changing this is on our radar. That leaves two options, you can create a .sfb and use that instead of the ShapeFactory, OR you can create a dummy .sfb, load that as a Renderable, and then do renderable.getMaterial() to get the material and pass it into the ShapeFactory.

Once you have the custom material, you could change the parameter you created at runtime by doing material.setFloat("alphaFactor", alpha);

michaelvogt commented 6 years ago

Thank you for clarification.

Glad to hear (read) that loading a material outside of an .sfb is on your radar. Can we keep this ticket open as a feature request?

dsternfeld7 commented 6 years ago

No problem! We currently are tracking this feature request through issue https://github.com/google-ar/sceneform-android-sdk/issues/157. We prefer not to keep duplicate issues open, and to have separate issues open for things instead of having one large issue that encapsulates multiple things.

romainguy commented 6 years ago

The alpha value of baseColor only applies to diffuse lighting. Specular highlights are by definition reflected light and are therefore unaffected by the transparency of the surface. It is however useful to be able to affect both diffuse and specular lighting together for fade effects. This will require a new feature in custom materials.

dsternfeld7 commented 6 years ago

To add to that, in the meantime you can fade an object out entirely by using the unlit shading model in the custom material.

michaelvogt commented 6 years ago

@dsternfeld7 Yes, agreed. I didn't realize that a feature request already exists.

@romainguy Is this new feature for custom materials already in consideration?

romainguy commented 6 years ago

@michaelvogt Yes, I will add this feature

michaelvogt commented 6 years ago

👍

romainguy commented 6 years ago

I implemented the new feature internally. It's a new blending mode called "fade".

michaelvogt commented 6 years ago

@dsternfeld7 I finally had time to try out your suggestion, but failed. Somehow I don't get alpha working at all. I guess I'm missing something simple here.

.sfa { bound_relative_root: { x: 0.5, y: 0, z: 0.5, }, materials: [ { name: "unlit_material", parameters: [ { texture: "andy", }, { alphaFactor: 0.5, }, { backColor: [ 0.5, 0.5, 0, 1, ], }, ], source: "sampledata/models/andy.mat", }, ], model: { attributes: [ "Position", "TexCoord", "Orientation", ], collision: {}, file: "sampledata/models/andy.obj", name: "andy", recenter: "root", }, samplers: [ { file: "sampledata/models\\andy.png", name: "andy", pipeline_name: "andy.png", }, ], version: "0.52:1", }

.mat `material { name: "Custom material", parameters: [ { type: "sampler2d", name: "texture" }, { type: "float", name: "alphaFactor" }, { type: "float4", name: "backColor" } ], requires: [ "position", "uv0" ], shadingModel: "unlit", }

fragment { void material(inout MaterialInputs material) { prepareMaterial(material);

    // material.baseColor = materialParams.backColor;
    material.baseColor = texture(materialParams_texture, getUV0());
    material.baseColor.a *= materialParams.alphaFactor;
}

}`

creating the shape: ModelRenderable.builder() .setSource(this, R.raw.andy) .build() .thenAccept(temp -> { Material material = temp.getMaterial(); material.setFloat("materialParams.alphaFactor", 0.5f); ModelRenderable renderable = ShapeFactory.makeCube(Vector3.one(), Vector3.zero(), material); });

dsternfeld7 commented 6 years ago

In the material block, try adding "blending" : "transparent". There is more information about the different blend modes on this page.

michaelvogt commented 6 years ago

Yes, works - of course. Sorry for not finding this myself...