How do I create a renderer viewport that is smaller then the renderer canvas (DOM element)

I am trying to create a webgl canvas with a renderer viewport restricted to a portion of it. The idea is to have some hidden canvas real estate I can use for hidden rendering that I then present in a div/canvas.

So, for creating thumbnails with different rendering styles for example.

Anyway, I am getting distorted rendering and I cannot figure out what is wrong with my setup.


// scratch space for hidden rendering
const scratchSpaceYOffset = 512;

let main = (container) => {

	const [ w, h ] = [ container.offsetWidth, container.offsetHeight ];

	// setup renderer with viewport restricted to NOT include
	// scratch space for hidden rendering 
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(w, scratchSpaceYOffset + h);
    renderer.setViewport(0, scratchSpaceYOffset, w, h);

    // insert canvas in DOM hierarchy

    // camera and orbitalControl setup
    const [ fov, near, far ] = [ 40, 1e-1, 7e2 ];
    camera = new THREE.PerspectiveCamera(fov, w / h, near, far);
    orbitControl = new OrbitControls(camera, renderer.domElement);

The variable scratchSpaceYOffset sets the size of the hidden canvas which extends beyond to bottom of the parent div that host the webgl canvas.

When scratchSpaceYOffset is zero the rendering is correct, as expect:

When scratchSpaceYOffset is non-zero (512) the rendering is stretched vertically:

Notice the screen filling calibration quad shows only the upper half (0 - 0.5).

Not sure what I missed.

Is that what you are trying to achieve:

Scroll a bit to see the extra canvas space beneath the full-screen viewport.

That is exactly the same code I have with the exception that you are using an orthographic camera.

Please share your code as a fiddle, too. Otherwise all further feedback is just guesswork.

Live app:


The relevant code is here:

1 Like

Um, there might be an issue with your container element. Please try to add the renderer’s canvas element directly to the document’s body and work with window.innerWidth and window.innerHeight instead of container.offsetWidth and container.offsetHeight.

There is also an issue with your resizing logic. It does work when I reduce the window size but not the other way around. The dimension of the canvas stays the same in this case.

Ahh. yah. It is actually working. I’ll make the changes. Cheers.