Closed harsha-main closed 4 years ago
Backface culling should be turned on by default. Could you show your .mat here please?
@romainguy I have given the sample .mat file given in the documentation: https://developers.google.com/ar/develop/java/sceneform/custom-material#culling It also says here that culling defaults to 'back', I need it both sides so I just added 'frontAndBack' to the sample.
material { name : "Textured material", parameters : [ { type : sampler2d, name : texture }, { type : float, name : metallic }, { type : float, name : roughness } ], requires : [ uv0 ], shadingModel : lit, culling : frontAndBack, blending : opaque }
fragment { void material(inout MaterialInputs material) { prepareMaterial(material); material.baseColor = texture(materialParams_texture, getUV0()); material.metallic = materialParams.metallic; material.roughness = materialParams.roughness; } }
frontAndBack means you want to cull front and back faces. This means no triangles will be ever visible. What you want is to set culling to none instead.
@romainguy I have tried to set culling to null (I had recreated the sfb just in case), the model now loses the texture set to it, and just displays a yellowish cream colored object instead of the image texture. What can I do here?
Not null, none.
@romainguy
Yes, I've given it none. I mis-typed here.
Here is the entire file, can someone help me figure out if this is the ideal file for the feature I'm looking for? Does Material have it's own texture that overrides
material {
name : "Textured material",
parameters : [
{
type : sampler2d,
name : texture
},
{
type : float,
name : metallic
},
{
type : float,
name : roughness
}
],
requires : [
uv0
],
shadingModel : lit,
culling : none,
blending : opaque
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, getUV0());
material.metallic = materialParams.metallic;
material.roughness = materialParams.roughness;
}
}
and this is my java code
ModelRenderable.builder().setSource(this, Uri.parse("andy.sfb")).build().thenAccept(dummy -> {
custom_material = dummy.getMaterial();
});
Texture.builder().setSource(BitmapFactory.decodeResource(getResources(), R.drawable.image_texture, opts))
.build()
.thenAccept(
texture -> {
MaterialFactory.makeOpaqueWithTexture(this, texture)
.thenAccept(
material -> {
custom_material.setTexture(MaterialFactory.MATERIAL_TEXTURE,texture);
andyRenderable = ShapeFactory.makeSphere(0.5f, new Vector3(0.0f, 0.15f, 0.0f), custom_material);
method();
});
});
I'm also not sure the string to pass into the name parameter of the setTexture method. Is it from the sfa? Should the parameters in .sfa and .mat be linked? I'm hoping I could load texture images from the internet. Thanks:)
I was able to do it now, it turns out the parameter with name "baseColorMap" (it could be any string, but has to be consistent in .sfa, .mat and java files) is to be given in the .mat file, and in the .sfa file, I needed to reference the same in it's parameters section (and also add it the sampler). I also had to give the same String "baseColorMap" as the first argument in the setTexture method of the Material. This line also needed to be in the .mat file in the fragment's material method. material.baseColor = texture(materialParams_baseColorMap, getUV0());
Maybe coders who are already experienced with 3D frameworks might find this easy.
update: It seems like you need at least a second time before you change the texture of the material to something else. Say if I'm loading my textures online, I can't change it again quickly(maybe a fast connection), and when I run a separate thread, wait for at least a second, and run the texture builder on ui thread with the bitmap, it works. Can someone help me understand this?
@romainguy Here is a very weird issue I have noticed while working on it: If I add a parameter in the .sfa file with a valid path in sampler, the content is visible on the app only alternatively (I need to press back to exit the app, and start the app again for it to work, and this pattern repeats). If I give it some random name as in parameters: [ { identifier : 'sdsds', }, ], ("sdsds" doesn't exist as a sampler), it works as expected every time.
I was able to do it now, it turns out the parameter with name "baseColorMap" (it could be any string, but has to be consistent in .sfa, .mat and java files) is to be given in the .mat file, and in the .sfa file, I needed to reference the same in it's parameters section (and also add it the sampler). I also had to give the same String "baseColorMap" as the first argument in the setTexture method of the Material. This line also needed to be in the .mat file in the fragment's material method. material.baseColor = texture(materialParams_baseColorMap, getUV0());
Maybe coders who are already experienced with 3D frameworks might find this easy.
update: It seems like you need at least a second time before you change the texture of the material to something else. Say if I'm loading my textures online, I can't change it again quickly(maybe a fast connection), and when I run a separate thread, wait for at least a second, and run the texture builder on ui thread with the bitmap, it works. Can someone help me understand this?
@harsha-main can you please paste the entire code of mentioning the changes. Even i am facing the same problem and only this is the solution I have found and i am new to 3d graphics
Hi, @sarat2GitHub Sorry I cannot paste the entire code as it's proprietary to my company. But please read a little further about rendering things using ARcore and you'll figure it out. Even I was a newbie when I posted this.
@harsha-main Okay understood. Anyway figured it out. Hope this solution can be used by others as well.
The thing is no need to change anything in the .mat file of the example in the this link https://developers.google.com/ar/develop/java/sceneform/custom-material#culling.
Just add
culling : none,
at the bottom of the material block.
and in the java code while setting the texture to the object, do this
node.getRenderable().getMaterial().setTexture("texture",material_texture); // where material_texture is the texture you have built or to that be applied to the Renderable
The important thing here is the string which is being passed in the java code i.e, "texture" should be same as that the parameter name which is being used for baseColor in the fragment block of the .mat file.
material.baseColor = texture(materialParams_texture, getUV0());
Even if it is missing in .sfa file, it is fine.
I have been trying to display a 3D Sphere with an image texture in air and was able to create one using MaterialFactory class, and was able to give it's anchor node a position using a Vector3 object.
The problem with this is that I wasn't able to set backface culling to true to this object programmatically. So when I tried to follow the documentation and create a .mat file to a dummy object, extract Material from it and set it to my Sphere, the Sphere wasn't even displayed (I think the issue may also be with the JSON that I created for the .mat, but it compiled fine). Can someone help me figure out how to enable backface culling to a Sphere so the image texture would be visible even when the camera enters the sphere? Another issue is that the object is not stable at it's place, it sometimes even flies away from it's place. Thanks in advance.