GLB Texture model flicker (Vue JS ?) Only on chrome

Hello there !

This is the first time that i use this forum to exchange about i issue that i face today … Hope that will be solved because you are the best :wink:

So, i’m using Vue js 2 and three in my current project where i have a glb that i load with an env map hdr,

So in my code to be quick, in the mounted i init the scene then i load first with RGBELoader that equirectangular text, then i use the GLTF loader to load the model, when i’m on the page where contain that canvas, all is good, but if i start the page from the home, then i come to that page, my model is starting to flicker and i realy dont know why … tried to remove all other stuff that i have (Controls etc …) but still the same…

Here is a preview of the issue : Enregistrement de l’écran 2020-12-04 à 17.40.06

Thanks for your help guys !

Ok, i tried a simple import and took exactly the GLTF loader in this example ( AND i think that come from the vue-router … (cc @Mugen87 maybe are you aware of this kind of issue ?), when i use this component on a view, and i just start from another route, when i change route to this, i got the model flickering, so weird like something happen during the life cycle…

  <div class="canvas-container" />

import * as THREE from 'three';

import { GLTFLoader } from '@/components/Global/Content3D/threeJS/loaders/GLTFLoader.js';
import { RGBELoader } from '@/components/Global/Content3D/threeJS/loaders/RGBELoader.js';
import { OrbitControls } from '@/components/Global/Content3D/threeJS/controls/OrbitControls.js';
import { RoughnessMipmapper } from '@/components/Global/Content3D/threeJS/utils/RoughnessMipmapper.js';

export default {
    name : 'Content3D',
    data : () => {
        return (
    destroyed : function (){
    mounted: function (){
    methods : {
        load (){

        init : function (){
            this.el_canvasContainer = document.querySelector('.canvas-container'); 
            this.containerW = this.el_canvasContainer.getBoundingClientRect().width;
            this.containerH = this.el_canvasContainer.getBoundingClientRect().height;

   = new THREE.PerspectiveCamera( 45, this.containerW/ this.containerH, 0.25, 20 );
   - 1.8, 0.6, 2.7 );

            this.scene = new THREE.Scene();

            new RGBELoader()
                .setDataType( THREE.UnsignedByteType )
                .setPath( '/assets/textures/equirectangular/' )
                .load( 'product_envmap.hdr', function ( texture ) {
                    this.envMap = this.pmremGenerator.fromEquirectangular( texture ).texture;
                    this.scene.background = this.envMap;
                    this.scene.environment = this.envMap;



                    // model

                    // use of RoughnessMipmapper is optional
                    this.roughnessMipmapper = new RoughnessMipmapper( this.renderer );

                    this.loader = new GLTFLoader().setPath( '/assets/model3d/' );
                    this.loader.load( 'GalaxyS10.glb', function ( gltf ) {

                        gltf.scene.traverse( function ( child ) {

                            if ( child.isMesh ) {

                                // TOFIX RoughnessMipmapper seems to be broken with WebGL 2.0
                                // roughnessMipmapper.generateMipmaps( child.material );


                        } );
                        this.scene.add( gltf.scene );



                    }.bind(this) );

                }.bind(this) );

            this.renderer = new THREE.WebGLRenderer( { antialias: true } );
            this.renderer.setPixelRatio( window.devicePixelRatio );
            this.renderer.setSize( this.containerW, this.containerH );
            this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
            this.renderer.toneMappingExposure = 1;
            this.renderer.outputEncoding = THREE.sRGBEncoding;
            this.el_canvasContainer.appendChild( this.renderer.domElement );

            this.pmremGenerator = new THREE.PMREMGenerator( this.renderer );

            this.controls = new OrbitControls(, this.renderer.domElement );
            this.controls.minDistance = 2;
            this.controls.maxDistance = 10;
   0, 0, - 0.2 );
        update : function (){
            this.rafId = requestAnimationFrame(this.update);
        resize : function (){
            this.containerW = this.el_canvasContainer.getBoundingClientRect().width;
            this.containerH = this.el_canvasContainer.getBoundingClientRect().height;

   = this.containerW/ this.containerH;

            this.renderer.setSize( this.containerW, this.containerH );

        render : function (){
        attach : function (){
            window.addEventListener('resize', this.resize);
        detach : function (){
            window.removeEventListener('resize', this.resize);

<style lang="scss" scoped>
        display: block;
        width: 100%;
        height: 100%;
        position: relative;
        background: red;

Nobody had this kind of issue ?

Sorry, I’m not familiar with Angular. If you can reproduce the issue in a pure three.js live example, I can have a look at it.

Thank you answering me, i’m using Vue JS, and i noticed that i got this issue only on chrome when i change pages, maybe something wrong on load between page changes ?

I probably can’t reproduce this into pure three js…

I suspect it will only be possible to fix this issue if you can isolate it with a small test case. You might also want to check if this glitch happens with other 3D engines (like BabylonJS), too.

The devs from the Angular or Chromium team will only investigate this issue if it’s clear that it is not an application related problem.

I see, can i make a repository that can be accessible to demonstrate the issue ?

Sounds good. I suggest you provide a npm start script so it’s possible to locally execute it via npm i && npm start.

Ok thank you ! Going to work on it now :slight_smile: