Cannot get "poster" image to show for VideoTexture (and UV rotate texture)


I can get everything else to work but for some reason the “poster” image never shows up. The mesh just shows as black while waiting for user input. This is on Microsoft Edge (Chrome?). I need the poster to show a “touch here” message. I removed anything that might interfere like an action manager and checked that the image file is accessible. Cheers.

document.addEventListener('DOMContentLoaded', (event) => {
    var canvas = document.getElementById("renderCanvas"); // Get the canvas element
    var engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

        /******* Add the create scene function ******/
    var createScene = function () {
    var scene = new BABYLON.Scene(engine);
    scene.clearColor = new BABYLON.Color4(0,0,0,0);

    //Adding a light
    //var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(20, 20, 100), scene);

    // Parameters: alpha, beta, radius, target position, scene
    var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);
    // Positions the camera overwriting alpha, beta, radius
    camera.setPosition(new BABYLON.Vector3(0, 0, 3.7));
    scene.activeCamera.panningSensibility = 0;  
    // Otherwise textures imported from gltf are flipped.
    scene.useRightHandedSystem = true;

    // This attaches the camera to the canvas, commenting this out prevents any input.
    // Second value afterr "canvas" must be "true" to allow page scroll.  
    camera.attachControl(canvas, true);
    // Prevent Zoom -
    camera.lowerRadiusLimit = camera.radius;
    camera.upperRadiusLimit = camera.radius;
    // Prevent up/down rotation (beta) -
    camera.lowerBetaLimit = camera.beta;
    camera.upperBetaLimit = camera.beta;
    // The first parameter can be used to specify which mesh to import. Here we import all meshes.
    var loader = BABYLON.SceneLoader.ImportMesh(["Face.001","Face.002","Face.003","Face.004"], "", "cube_map.glb", scene, function (meshes, particleSystems, skeletons) {
        scene.createDefaultLight(true, true, true);
        var nature = scene.getMeshByName("Face.001");
        var unspoken = scene.getMeshByName("Face.002");
        var waking = scene.getMeshByName("Face.003");
        var space = scene.getMeshByName("Face.004");
    // All variables must be included in contructor or options don't set -
	   var spaceMat = new BABYLON.StandardMaterial("m", scene);
	   var spaceVidTex = new BABYLON.VideoTexture("vidtex","./spacex.mp4", scene, false, false, BABYLON.VideoTexture.BILINEAR_SAMPLINGMODE, {
           poster: "./spacex-poster.jpg",
           muted: false,
           autoUpdateTexture: true,
           preload: true,
           autoPlay: true,
           loop: true,
	   spaceMat.diffuseTexture = spaceVidTex;
	   spaceMat.roughness = 1;
	   spaceMat.emissiveColor = new BABYLON.Color3.White();
	   space.material = spaceMat;
       spaceMat.backFaceCulling = false;
		if(evt.pickInfo.pickedMesh === space){
	    }, BABYLON.PointerEventTypes.POINTERPICK);
        //create a Center of Transformation
        var CoT = new BABYLON.TransformNode("root");
        nature.parent = CoT;
        unspoken.parent = CoT;
        waking.parent = CoT;
        space.parent = CoT;

	    scene.registerBeforeRender(function () {
            CoT.rotationQuaternion = null;
			CoT.rotation.y += 0.0027;
        // Add actionManagers on the models
        nature.actionManager = new BABYLON.ActionManager(scene);
        unspoken.actionManager = new BABYLON.ActionManager(scene);
        waking.actionManager = new BABYLON.ActionManager(scene);
        space.actionManager = new BABYLON.ActionManager(scene);

        // add links
            new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, 
                var pickedMesh = event.meshUnderPointer; 

            new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, 
                var pickedMesh = event.meshUnderPointer; 

            new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, 
                var pickedMesh = event.meshUnderPointer; 

        //    new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, 
        //    function(event){
        //       var pickedMesh = event.meshUnderPointer; 
        //    })

    return scene;
        /******* End of the create scene function ******/

        var scene = createScene(); //Call the createScene function

        // Register a render loop to repeatedly render the scene
        engine.runRenderLoop(function () {

        // Watch for browser/canvas resize events
        window.addEventListener("resize", function () {

Hello! Would you be able to provide us with a playground repro, so we can isolate the issue better from your local environment? :slight_smile:

OK, thanks. Will do.

Did some experimenting. If I set it to muted and autoplay to off THEN the poster image is shown. It seems if the browser requires user input (with muted and autoplay ON) then it won’t show the poster image.

1 Like

Here it is but I don’t know how to get playground to use assets like images and models If I upload them to my site I get a CORS error. Can I upload to playground ? Cheers.

Missing poster for videotexture | Babylon.js Playground (

You can use external assets on the playground: Using External Assets In the Playground | Babylon.js Documentation (

1 Like

Thanks ! OK now it’s at …

Missing “poster” for videotexture | Babylon.js Playground (

It now works in the playground. It now also works on my local test version of my website for some reason ( Will eventually go on ). Could it be because I used the assets from Github rather than locally ? Anyway what ever it was. Could have been a typo.

So while I’m here, as you see in the playground, the VideoTexture panel of the model does not honour the UV that is already on the mesh. The other static images do use the UV defined in the GLTF.

The docs say - VideoTexture | Babylon.js Documentation

“Define the UV channel to use starting from 0 and defaulting to 0.”.

So why is the VideoTexture not conforming to the UV defined in the GLTF ? Cheers.

I added to your PG
spaceVidTex.uScale = -1;
Example -

(you can also use
spaceVidTex.vScale = -1;
if it suits your need better)

As far as I know GLTF has no support for videotextures.

1 Like

Yes, thanks. I was just getting the hang of that. I opened a binary version of my GLTF in the Babylon Sandbox ( Babylon.js Sandbox - View glTF, glb, obj and babylon files ( ). Just copy and past the UV’s I reasoned ! …

However I don’t get the same results when setting values such as …

       //spaceVidTex.uOffset = -1.0;
       //spaceVidTex.vOffset = 1.0;
       //spaceVidTex.uScale = -1.0;
       //spaceVidTex.vScale = 1.0;
       spaceVidTex.wAng = -90;

The Angle one especially. 90 or 180 shows the textures 45 degrees ! Is it expecting quaternions ?

Cracked it ! The wAng figure needs to be in radians …

       spaceVidTex.uScale = -1.0;
       spaceVidTex.wAng = -1.5708;

Fixed playground - Missing “poster” for videotexture FIXED | Babylon.js Playground (

I wish it would say this in the docs …

VideoTexture | Babylon.js Documentation (

It says “wAng: number”. It should say “wAng: number (Radians)”. Might put in a bug report / suggestion.

EDIT: When a value required for a property needs to be in Radians docs should specify that · Issue #11700 · BabylonJS/Babylon.js (

1 Like

You were faster than me - Babylon.js Playground :slight_smile:

I agree that the API doc needs this improvement.

1 Like

Wow. Maybe I should become your Padawan apprentice ? :grin:

Radians is the thing that you just “should know” with 3D if you use it all the time (I don’t). The last time I think I used Radians was with the venerable VRML.

1 Like