THREE.WebGLRenderer: A WebGL context could not be created


  async init() {
    await this.addScene();
    await this.addRenderer();
    await this.addCamera();
    await this.addLight();
    await this.addGridHelper();
    await this.addControl();
    await this.addTransformControl();
    await this.addDragControl();
    this.renderCanvas();
  }

  addScene() {
      this.scene = new THREE.Scene();
  }

  addRenderer() {
    // Dispose existing renderer if it exists
    if (this.renderer) {
      this.renderer.dispose();
      this.renderer.forceContextLoss();
      this.renderer.context = null;
      this.renderer.domElement = null;
  }

  let context;
  let isWebGL2 = false; 

  // Try WebGL2 first
  try {
      context = this.canvas.getContext('webgl2', { antialias: true, alpha: true });
      if (context) {
          this.renderer = new THREE.WebGLRenderer({
              canvas: this.canvas,
              context: context
          });
          isWebGL2 = true;
          console.log('WebGL 2 context created successfully.');
      } else {
          throw new Error('WebGL 2 not supported.');
      }
  } catch (e) {
      console.warn('WebGL 2 not supported, falling back to WebGL 1.', e);
  }

  // Fallback to WebGL1 if WebGL2 is unavailable
  if (!this.renderer) {
      try {
          this.renderer = new THREE.WebGLRenderer({
              canvas: this.canvas,
              antialias: true,
              alpha: true
          });
          console.log('WebGL 1 context created successfully.');
      } catch (e) {
          console.error('WebGL not supported in this browser.', e);
          this.utils.showError('Your browser does not support WebGL, which is required for 3D rendering.', true, 5000);
          return;
      }
  }

    // Configure renderer
    this.renderer.setPixelRatio(window.devicePixelRatio);
    this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
  }

  addCamera() {
      const aspectRatio = this.getAspectRatio();
      this.camera = new THREE.PerspectiveCamera(45, aspectRatio, 0.1, 2000);
      this.camera.position.set(0, 4, 6);
      this.camera.lookAt(0, 0, 0);

  }

  addLight() {
    var light;
    this.scene.add(new THREE.AmbientLight(0x666666));
    
    var lightobjgeo = new THREE.SphereGeometry(0.3, 4, 2);
    var material = new THREE.MeshPhongMaterial({
        color: new THREE.Color().setHSL(Math.random(), 1, 0.75),
        flatShading: true,
        specular: 0x111111,
        shininess: 0
    });
    
    this.lightobj = new THREE.Mesh(lightobjgeo, material);
    this.lightobj.position.set(2, 8, 4);
    this.lightobj.name = 'light';

    light = new THREE.DirectionalLight(0xdfebff, Math.PI * 2);
    light.position.copy(this.lightobj.position);
    light.castShadow = true;
    light.shadow.mapSize.width = 1500;
    light.shadow.mapSize.height = 1500;
    light.shadow.camera.near = 0.5;
    light.shadow.camera.far = 500;

    this.lightobj.add(light);
    this.scene.add(this.lightobj);
    this.updateObjectList();
  }
  copyValue(tmp) {
    var dummy = document.createElement("input");
    document.body.appendChild(dummy);
    dummy.setAttribute("id", "dummy_id");
    document.getElementById("dummy_id").setAttribute('value', tmp);
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
    this.utils.showSuccess('Copied', false, 2000);
  }
  addGridHelper() {
      this.ground = new THREE.GridHelper(40, 40);
      this.ground.name = "ground";
      this.scene.add(this.ground);
  }

  addControl() {
      this.orbitcontrols = new OrbitControls(this.camera, this.renderer.domElement);
      this.orbitcontrols.rotateSpeed = 1;
      this.orbitcontrols.zoomSpeed = 2;
      this.orbitcontrols.panSpeed = 1;
      this.orbitcontrols.minDistance = 1;
      this.orbitcontrols.maxDistance = 100;
      this.orbitcontrols.enableKeys = false;
      this.orbitcontrols.update();

      this.orbitControlChangeRef = this.renderCanvas.bind(this);
      this.orbitcontrols.addEventListener('change', this.orbitControlChangeRef);
  }

  addTransformControl() {
    this.transformcontrols = new TransformControls(this.camera, this.renderer.domElement);
    this.transformcontrols.addEventListener('change', this.renderCanvas.bind(this));

    this.transformcontrols.addEventListener('mouseDown', () => {
        this.orbitcontrols.enabled = false;
    }); 
    this.transformcontrols.addEventListener('mouseUp', () => {
        this.orbitcontrols.enabled = true;
        this.getObjectPosition();
        this.getObjectRotation();
        this.getObjectScale();
    });

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

  addDragControl() {
    // Filter only Mesh objects from the scene
    const meshObjects = this.objects.filter(obj => obj instanceof THREE.Mesh);
  
    // Initialize DragControls with filtered mesh objects
    this.dragControls = new DragControls(meshObjects, this.camera, this.renderer.domElement);
  
    this.dragControls.deactivate();
    this.dragControls.activate();
  
    // Add event listeners for hover effects
    this.dragControls.addEventListener('hoveron', (e) => {
      // Only apply wireframe effect if the object has material and is a Mesh
      if (e.object instanceof THREE.Mesh && e.object.material) {
        this.onHoverObject(e); // Call your custom hover logic
      }
    });
  
    // Disable DragControls while TransformControls are active
    this.transformcontrols.addEventListener('dragstart', () => {
      this.dragControls.enabled = false;
    });
  
    this.transformcontrols.addEventListener('dragend', () => {
      this.dragControls.enabled = true;
    });
  }

  renderCanvas() {
      this.renderer.render(this.scene, this.camera);
  }

In above code its perfect working for the which browser support webgl2 but some browser only support webgl1in that browser throw below error

This does not create a WebGL1 context. Support for WebGL1 has been deprecate for quite some time. Currently WebGLRenderer only creates a WebGL2 context.

More info:

1 Like