Moving GUI Image with 3D Model

Actually if you scroll away enough you can see the color behind the canvas element:

I am using the following code and it’s giving me the error shown in the screenshot.

 <script>
                var canvas = document.getElementById("renderCanvas");
                var engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });

                var loadingScreenDiv = window.document.getElementById("loadingScreen");

                function customLoadingScreen() {
                    console.log("customLoadingScreen creation")
                }
                customLoadingScreen.prototype.displayLoadingUI = function () {
                    console.log("customLoadingScreen loading")
                    loadingScreenDiv.innerHTML = "loading";
                };
                customLoadingScreen.prototype.hideLoadingUI = function () {
                    console.log("customLoadingScreen loaded")
                    loadingScreenDiv.style.display = "none";
                };
                var loadingScreen = new customLoadingScreen();
                engine.loadingScreen = loadingScreen;

                engine.displayLoadingUI();

                var createScene = function ()
                {
                    // Create scene
                    var scene = new BABYLON.Scene(engine);

                    scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);

                   var environment = scene.createDefaultEnvironment({ enableGroundShadow: true, groundYBias: 1 });

                    scene.createDefaultCameraOrLight(true, true, true);

                    var building = BABYLON.SceneLoader.Append("@Url.Content("~/3dmodel/")", "senkrechtcaster_schere_QLgame.glb", scene, function (meshes)
                    {
                        scene.getEngine().loadingScreen.hideLoadingUI();


                        scene.createDefaultCameraOrLight(true, true, true);

                        var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

                        var image = new BABYLON.GUI.Image("", "~/Images/on.png");

                        var manager = new BABYLON.GUI.GUI3DManager(scene);
                        var button = new BABYLON.GUI.Button3D("reset");
                        manager.addControl(button);
                        button.position.z = -230;
                        button.position.x = 700;
                        button.position.y = 900;
                        button.scaling = new BABYLON.Vector3(150, 150, 100);
                        button.content = image;

                    });

                    return scene;
                };

                var scene = createScene();
                engine.runRenderLoop(function () {
                    if (scene) {
                        scene.render();
                    }
                });

                // Resize
                window.addEventListener("resize", function () {
                    engine.resize();
                });

            </script>

looks like your canvas is not called renderCanvas ???

canvas id was the problem. thank you.
I am using custom loading screen using the code mentioned in above comments,I am able to display the custom loading div but a strange purple box is coming in the middle, please check the video attached with this comment and suggest. thank you again.

3dModel Issue.zip (76.2 KB)

I believe it is due to environment and I have edited my code and first the purple environment generates and then its color change to transparent and 3d model is rendered.

              var canvas = document.getElementById("renderCanvas");
                var engine = new BABYLON.Engine(canvas, true, /*{ preserveDrawingBuffer: true, stencil: true }*/);

                var loadingScreenDiv = window.document.getElementById("loadingScreen");

                function customLoadingScreen() {
                    console.log("customLoadingScreen creation")
                }
                customLoadingScreen.prototype.displayLoadingUI = function () {
                    console.log("customLoadingScreen loading")
                    loadingScreenDiv.innerHTML = "loading";
                };
                customLoadingScreen.prototype.hideLoadingUI = function () {
                    console.log("customLoadingScreen loaded")
                    loadingScreenDiv.style.display = "none";
                };
                var loadingScreen = new customLoadingScreen();
                engine.loadingScreen = loadingScreen;

                engine.displayLoadingUI();

                
                var delayCreateScene = function ()
                {
                    // Create scene
                    var scene = new BABYLON.Scene(engine);
                    scene.createDefaultCameraOrLight(true, true, true);

                    scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);

                    var environment = scene.createDefaultEnvironment({ enableGroundShadow: true, groundYBias: 1 });


                    //scene.getEngine().loadingScreen.displayLoadingUI();

                    var building = null;
                    BABYLON.SceneLoader.ImportMesh("", "@Url.Content("~/3dmodel/")", "senkrechtcaster_schere_QLgame.glb?", scene, function (meshes)
                    {

                        scene.createDefaultCameraOrLight(true, true, true);

                       // scene.getEngine().loadingScreen.hideLoadingUI();


                        engine.hideLoadingUI();


                        building = meshes[0];
                        meshes[0].rotationQuaternion = null;

                        var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

                        var image = new BABYLON.GUI.Image("but", "@Url.Content("~/Images/on.png")");

                        var manager = new BABYLON.GUI.GUI3DManager(scene);
                        var button = new BABYLON.GUI.Button3D("reset");
                        manager.addControl(button);
                        button.position.z = 300;
                        button.position.x = 400;
                        button.position.y = 600;
                        button.scaling = new BABYLON.Vector3(150, 150, 100);
                        button.content = image;

                    });

                    return scene;
                };

                
                //var scene = createScene();
                var scene = delayCreateScene();
                engine.runRenderLoop(function () {
                    if (scene) {
                        scene.render();
                    }
                });

                // Resize
                window.addEventListener("resize", function () {
                    engine.resize();
                });

yup it is because your clear has alpha 0 and you see through it so you see the html color of the background, you could change the clear color to prevent that to happen.

HI Sebavam, thank you for your help till now. I have got a quick question regarding dynamic change to 3D UI Button. I am creating 3D Button and putting a image in its content. I am trying to change the button image based on a value. For example if the value of a variable is less than 3 then button image will be something and if value of that variable is greater than 3 then the image of the button will be different. These values of variable are very dynamic and rapidly changing however I cant see the button’s image changing that rapid. Can babylon js cannot handle these kind of dynamic updates?

It should work all good by switching the content even rapidly, obviously not faster than a frame (but anyway your eyes would not notice). Could you share a playground with a repro of your issue ?

I am unable to share the playground as I have created a .NET Core web application in which I am using real time streaming data value to switching the content of button. The values changes rapidly however the content doesn’t change that fast. In-fact the content changes randomly not following the condition which I am passing.

just to give you an example, please refer the video attached with this comment to check how fast the data changes but the button content is not changing that rapid. note the button content is two images which are being displayed.3dVideo.zip (3.8 MB)

You do not need the real code in the playground, just one button, a setInterval and the switching image code. It should be enough to troubleshoot.

it is working with the help of delay function in JS.
Please refer the following playground to see it running.

https://www.babylonjs-playground.com/#HR6IDD#16

It probably highlights that something else is going in your code in this case :frowning:

got it. Could you please tell me one thing why can’t I use the same image content again and again. if you have seen my above playground, you will notice that I am creating multiple image content like following -
var on1 = new BABYLON.GUI.Image(“but”, "https://dl.dropbox.com/s/x754y0wj6twzljr/on.png?");
var on2 = new BABYLON.GUI.Image(“but”, "https://dl.dropbox.com/s/x754y0wj6twzljr/on.png?");

in-order to them render again once they have changed. Is there way to reuse it again?
I believe this is the same problem which I am facing in my .NET core application. I am reusing the image content again and again thats why they are not rendering once they have been used once. Is there any way to reuse the image content again?

I would advise to keep the images as a cache instead of trying to change the url in the same image. This way all the textures are already living in cache on the gpu :slight_smile:

Could you please elaborate on this?
If i just switch between
var on1 = new BABYLON.GUI.Image(“but”, "https://dl.dropbox.com/s/x754y0wj6twzljr/on.png?");
and
var off1 = new BABYLON.GUI.Image(“but”, "https://dl.dropbox.com/s/20eaqne7ydxuv7b/off.png?");

It doesn’t render again. The same thing happens in my localhost. Once the variable has been used, it doesn’t render again.

please check this babylonjs-playground.com/#HR6IDD#17
I am using similar stuff on my localhost.

Ohhh I see what you mean, it is a bug on our end I guess : https://www.babylonjs-playground.com/#HR6IDD#20

It looks like the content is always append to the rest instead of being replace, my workaround removes the cache to make it as wished, we will deploy a new version shortly.

sure sounds good!

I made it work by using new BABYLON.GUI.Image(“but”, "https://dl.dropbox.com/s/x754y0wj6twzljr/on.png?") directly instead of initializing it to a variable, however, the rendering of the 3D model with the dynamic button is making it work very slowly. Is there any way to speed up the rotation or zooming of the 3D Model.

Also I am getting the following error.
[.WebGL-0000025902E29C00]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1

Is there something wrong with my code? The only difference I did is reduced the size of the canvas in my application, will that affect?