const model = await SceneLoader.ImportMeshAsync('', './assets/model.glb', '', this.scene);
It works great. But some users reported that on some mobile devices, the model appears white. Like emission is set to white. I’m not allowed to provide any models or the project and cannot create a demo until I cannot reproduce with my devices. But it’s a simple glb in a simple scene with a simple texture exported from Blender. Nothing special. Any hint will help.
The scene has just a TargetCamera, a HemiphericLight and a HDRCubeTexture(*.hdr). Pretty basic. On most mobile devices it works. But on some devices (Android 8) the model appears white.
Any idea why? Is this a known issue? Have you ever experienced such a case? I appreciate any help.
This is rendered in Blender. Just for demo reasons. This is like Babylon behaves on some Android devices. Left expected, right actual. Is there a solution for this?
I’m new to babylon, so ignore if not relevant: I’ve noticed that emmisive color can “override” diffuse to white if moved to upper left in the color picker (at least on Android). There is a property named “linkEmissiveWithDiffuse” that changes how diffuse and emmissive are related. Not sure if it’s retroactive or is linked only with subsequently-assigned values.
Playground for changing the four StandardMaterial colors:
All properties of StandardMaterial grouped into categories (linkEmissiveWithDiffuse is in row “Emissive”, column “Source”): Grouping the StandardMaterial parameters
Thanks, I’ll try it out. I’m new as well. More or less. Anyway… The material has no emission set. But I guess that there is an emission issue on import. But why only on some (older) android devices? The babylon.js version is the same. So the glb importer must be the same. It’s a cordova app. So it depends on the WebView. Maybe it has to do with the Chrome version. Or it’s an hardware problem. Maybe missing feature? The problem is, that I cannot debug since I cannot reproduce with my devices. I have to update and get feedback…
I’ll try to override the material or iterate through it and check/set the emission to zero. Not yet sure how, but I’ll find it out. Any other hint is welcome. For example: Can I disable emissive globally? For quick testing.
I found out another possible reason. If you set the material of all meshes to null, the mesh appers also as white. I would expect black btw. So maybe the material is not set in this case. Perhabs of unsupported hardware? I doubt. I will try the following. First test, if material exist and check the emissive. If this is the problem, I’ll try to set emissive back to zero/black or set a fallback material if not set. I’ll post a playground when ready… Since this seems only to appear of imported glb files, I wonder how to import a glb file in playground? Btw. is there a emissive strength (factor/multiplier)?
The last link I posted has all parameters of StandardMaterial (as of the time posted). Strength is under the column “Level.” I don’t see a strength-type parameter for emissive.
The playground I linked is a repro. Click the emissive ColorPicker in the square’s upper right. The sphere will change to white. Then click the diffuse ColorPicker anywhere (square or ring). The sphere will remain white regardless of the color chosen for diffuse.
Edit: perhaps you were asking for a repro from OP?
Yes, I think the question was for me. ^^ But thanks anyway. … Yes I’m working on it.
Btw. it’s PBRMaterial (from tfGL/glb) and e.g. emissiveColor and emissiveIntensity in this case. But I need to test this first. It’s not yet sure if emissive causes this problem or if material is null. Because I tried to remove the material on runtime with null. The model appears white like emissive in this case. I would expect black. … I’ll create a playground/repo after my tests. And hopfully with the solution/workaround if found. I’m on the trail…
I have overridden the material with StandardMaterial with a diffuse color green. It appears black. And the PBRMaterial from GLB appears white like emissive. But the emissive color is black and intensity is set to 0. Is it possible to test with WebGL1? It seems no materials works in this case. No errors on console btw. Babylon.js v5.57.1 - WebGL1 (Android 8, Chrome 124 WebView)
const B = BABYLON;
async function main() {
const canvas = document.querySelector('canvas');
const engine = new B.Engine(canvas);
const scene = new B.Scene(engine);
const camera = new B.TargetCamera('camera', new B.Vector3(10, 3, 0), scene);
camera.setTarget(B.Vector3.Zero());
camera.fov = (45 * Math.PI) / 180;
const light = new B.HemisphericLight('light', new B.Vector3(10, 10, 0), scene);
light.intensity = 2;
new ResizeObserver(() => engine?.resize()).observe(canvas);
engine.runRenderLoop(() => scene?.render());
const model = await B.SceneLoader.ImportMeshAsync('', './cube.glb', '', scene);
}
main();
Nothing special. The glb is a simple model exported from Blender (4.1). Not sure if it’s the WebGL v1 or the hardware/drivers on the Android device. I could download an old browser version of e.g. Chromium with WebGL v1 or is it possible to switch the version? I want to reproduce it. But wait, the device has the latest Chrome version. Means, the browser supports the older WebGL version. I wonder, if I could simulate this on desktop.
Are there some cheats to optimize Babylon for mobile? Settings? Tweaks, etc.
If it works on some devices and doesn’t on others (in the same OS), it is probably hardware or OS/Browser version dependent. This is why we usually want a reproduction - to see if we can set some flag in the repository for specific devices/user agents to have certain features disabled. But we need to first understand what the problem is
Neither the PBRMaterial (glb) nor the StandardMaterial (babylon) work. In case of PBRMaterial from glb, it appers white like emissive white. But the emissive color is black and also tried to set intencity to 0. And if the StandardMaterial is set, it appears black. No material works. That’s weird. The 3D view works. I can rotate the object etc. All fine, no errors. The console shows: Babylon.js v5.57.1 - WebGL1
Please let me know if you need more information. I wonder is there a tool/app to find out the graphics features? Or can babylon gather this information? But why should everything work, but the (basic) materials. It’s maybe just a bug and the device is garbage. Btw. I attached a test glb. But it seems it does not matter, since the StandardMaterial does also not work. I could try three.js, if there is the same problem to exclude an bug of babylon.js. Any idea to debug a device which I don’t have access? I would list graphics features. If babylon.js has such a feature, I could implement this in app and send the log to me.
Android 8.1 is 6 years old, and probably doesn’t get any updates anymore. I am not sure any of the team has a device that runs this OS (but it is legit to ask).
Also - have you tried a later version of Babylon?
Personally, I would stop supporting such old Android versions. But I can’t. Anyway… I tested it on an older device (Huawei MediaPad M3 Lite 10; Snapdragon 435) with Android 7.0 and it works great. I cannot use the latest Babylon version due to dependency incompatibilities.
It’s ok. You don’t need to test anything. I just thought I’d ask. Maybe the issue is already known. It was a try. It makes no sense, why the (simplest) material does not work.
Is this Snapdragon 425 (Qualcomm Adreno 308) vs 435 (Qualcomm Adreno 505)? Web search shows OpenGL ES 3.0 vs 3.2. Maybe this is the problem? I don’t know.
Or it’s maybe a driver question or other modifications of the manufacturer. I would say: Bad luck, buy a better tablet. But I want to know what the problem is, argh. ^^ Not sure if I try three.js. Maybe this can help to find out if this is a babylon issue.
Ok, I was able to update babylon to 7.7.0. But got the following error because of dependencies version like typescript, which I cannot update at this moment.
Cannot find name …
VideoFrame
ImageEncodeOptions
OffscreenRenderingContextId
OffscreenRenderingContext
But I found a workaround. I defined these types global with any.
// global.d.ts
type VideoFrame = any;
type ImageEncodeOptions = any;
type OffscreenRenderingContextId = any;
type OffscreenRenderingContext = any;
Now the build works. I tested on desktop and looks good. But I will test this build on the problem Android device tomorrow.
What do you mean with “disabling uniform buffer”? How? Can you please post a code line? I’ll implement this as soon as possible to include this in my tests tomorrow. Thanks.
you can force engine.disableUniformBuffers = false as soon as you instantiate an engine to test disabling it, also you can try disabling webgl2 in the engine construction option as another test to figure the culprit
Test result: No changes. Still white appearance. Latest babylon.js 7.7.0 with disableUniformBuffers (what is this?) and disableWebGL2Support. And typescript 4.7 btw which can’t be updated due to other deps. I also tested on an Android 7 and Android 9 which works well. This problem tablet is just garbage. Maybe bad graphics chip (Qualcomm Adreno 308). It makes no sense why only the material does not work. The 3D scene works well. But I give up. Thanks anway. Btw. I tried to view the examples on the three.js website on the Android device browser. But nothing works here. The babylon.js playground works but with the known black material issue (for standard material). I could develop a 2d fake 3d canvas solution. Babylon does not have a 2d canvas fallback (like pixi.js), right? It’s always webgl. But it’s ok. I won’t spend any more time on it. I hope this works on the most other devices.
Has babylon a method to get the graphic card info like name? Otherwise I would do this: