Ar.js with Three.js Resizing problem

Hey,
I’m currently working on an Ar project using Marker Based Ar.js (Ar.js) together with Three.js. To set up the project I followed this example.

It does work, however there’s a problem with the resize function. When the application loads for the first time the dimensions of the canvas are incorrect. After then resizing the window for the first time, the dimensions are correct.

This is how I create my canvas and the renderer:

const renderer = new THREE.WebGLRenderer({
      antialias: true,
        alpha: true,
    });

    renderer.setSize(sizes.width, sizes.height);
    renderer.domElement.style.position = "absolute";
    renderer.domElement.style.top = "0px";
    renderer.domElement.style.left = "0px";
    renderer.domElement.style.width = sizes.width+"px";
    renderer.domElement.style.height = sizes.height+"px";
    document.getElementById("canvas").appendChild(renderer.domElement);

I then use the following resize function:

const onResize = () => {
        arToolkitSource.onResizeElement();
        arToolkitSource.copyElementSizeTo(renderer.domElement);
        if (arToolkitContext.arController !== null) {
          arToolkitSource.copyElementSizeTo(arToolkitContext.arController.canvas);
        }
      };
  
      arToolkitSource.init(function onReady() {
        onResize();
      });
  
      window.addEventListener("resize", () => {
        onResize();
      });

I tried to look for a documentation of Ar.js to find out what exactly arToolkitSource.onResizeElement() does, but couldn’t find anything.

Have any of you already had a similar problem and know how to solve it?

If it helps, here’s my full code:

    // Variables
    let arToolkitSource, arToolkitContext;
    
    // ------------------------------------------------------------------------
    // Scene
    // ------------------------------------------------------------------------
    const scene = new THREE.Scene();

    // ------------------------------------------------------------------------
    // Sizes
    // ------------------------------------------------------------------------
    const sizes = {
      width: window.innerWidth,
      height: window.innerHeight,
    };

    // ------------------------------------------------------------------------
    // Camera
    // ------------------------------------------------------------------------

    let camera = new THREE.Camera()
    scene.add(camera);

    // ------------------------------------------------------------------------
    // Renderer
    // ------------------------------------------------------------------------

    const renderer = new THREE.WebGLRenderer({
      antialias: true,
        alpha: true,
    });

    renderer.setSize(sizes.width, sizes.height);
    renderer.domElement.style.position = "absolute";
    renderer.domElement.style.top = "0px";
    renderer.domElement.style.left = "0px";
    renderer.domElement.style.width = sizes.width+"px";
    renderer.domElement.style.height = sizes.height+"px";
    document.getElementById("canvas").appendChild(renderer.domElement);

    // ------------------------------------------------------------------------
    // AR Toolkit Source
    // ------------------------------------------------------------------------

    arToolkitSource = new THREEx.ArToolkitSource({
        sourceType: "webcam",
        sourceWidth: window.innerWidth,
        sourceHeight: window.innerHeight,
    });

    // ------------------------------------------------------------------------
    // Function on Resize and Resizing
    // ------------------------------------------------------------------------
    
    const onResize = () => {
        arToolkitSource.onResizeElement();
        arToolkitSource.copyElementSizeTo(renderer.domElement);
        if (arToolkitContext.arController !== null) {
          arToolkitSource.copyElementSizeTo(arToolkitContext.arController.canvas);
        }
      };
  
      arToolkitSource.init(function onReady() {
        onResize();
      });
  
      window.addEventListener("resize", () => {
        onResize();
      });


    // ------------------------------------------------------------------------
    // Initialize arToolkitContext
    // ------------------------------------------------------------------------
    arToolkitContext = new THREEx.ArToolkitContext({
        cameraParametersUrl: "data/camera_para.dat",
        detectionMode: "mono",
      });
  
      arToolkitContext.init(function onCompleted() {
        camera.projectionMatrix.copy(arToolkitContext.getProjectionMatrix());
      });

    // ------------------------------------------------------------------------
    // Build Marker Controls
    // ------------------------------------------------------------------------
    let marker = new THREE.Group();
    scene.add(marker);

    let markerControls = new THREEx.ArMarkerControls(arToolkitContext, marker, {
      type: "pattern",
      patternUrl: "data/hiro.patt",
    });


    // ------------------------------------------------------------------------
    // Geometry
    // ------------------------------------------------------------------------
    
    const geometry = new THREE.BoxGeometry(1, 1, 1);
    const material = new THREE.MeshBasicMaterial({
        color: "red",
        side: THREE.DoubleSide,
    });

    const mesh = new THREE.Mesh(geometry, material);
    marker.add(mesh)

    // ------------------------------------------------------------------------
    // Lights
    // ------------------------------------------------------------------------
    const ambientLight = new THREE.AmbientLight(0xcccccc, 0.5)
    scene.add(ambientLight)

     // ------------------------------------------------------------------------
    // Update arToolkitSource.ready
    // ------------------------------------------------------------------------

    const update = ()=> {
        // update artoolkit on every frame
        if (arToolkitSource.ready !== false)
          arToolkitContext.update(arToolkitSource.domElement);
    }


    // ------------------------------------------------------------------------
    // Render Scene & Animation loop
    // ------------------------------------------------------------------------
    const animate = () => {
     window.requestAnimationFrame(animate)
     update()
     renderer.render(scene,camera)
    };
    animate()
    onResize()

If you have simillar problem, the solution could be to define both the displayWidth and displayHeight to window.innerWidth respectively window.innerHeight when initializing arToolkitSource. I unfortuanetly overlooked this.

arToolkitSource = new THREEx.ArToolkitSource({
        sourceType: "webcam",
        sourceWidth: window.innerWidth,
        sourceHeight: window.innerHeight,
        displayWidth: window.innerWidth,
        displayHeight: window.innerHeight,
    });
1 Like