Correct orthographic camera positioning for front, back, left, right and top side of an object in scene

I need to create images by using orthographic camera. I have predefined values for width and height for them. Since I only need images I’m not implementing viewer, so instead I’m creating imaginary canvas. Code for this is as follows:

class RenderSetup {
    public camera: OrthographicCamera;
    public scene: Scene;
    public composer: EffectComposer;

    public constructor(width: number, height: number, construction: Group) {
        const canvas = document.createElement("canvas");
        canvas.width = width;
        canvas.height = height;
        this.scene = new Scene().add(construction);
        this.scene.background = new Color(0xffffff);

        const light = new AmbientLight(0xf0f0f0, .8);
        const dirLight = new DirectionalLight(0xffffff, .4);
        this.scene.add(light);

        this.camera = this.createDefaultCamera(width / height);
        this.camera.add(dirLight);

        const renderer = new WebGLRenderer({canvas, antialias: true, logarithmicDepthBuffer: true});

        const drawingBufferSize = renderer.getDrawingBufferSize(new Vector2());
        const renderTarget = new WebGLRenderTarget(drawingBufferSize.width, drawingBufferSize.height, {samples: 4});
        const renderPass = new RenderPass(this.scene, this.camera);
        const copyPass = new ShaderPass(CopyShader);
        this.composer = new EffectComposer(renderer, renderTarget);
        this.composer.addPass(renderPass);
        this.composer.addPass(copyPass);
    }

    private createDefaultCamera(aspect: number): OrthographicCamera {
        const viewerFrustumSize = .25;
        const aspectFrustum = aspect * viewerFrustumSize;
        const camera = new OrthographicCamera(-aspectFrustum, aspectFrustum, viewerFrustumSize, -viewerFrustumSize, 0.001, 1000);
        camera.matrixAutoUpdate = false;
        camera.updateProjectionMatrix();
        camera.updateMatrix();
        return camera;
    }

    public getImage(): string {
        this.composer.render();
        return this.composer.renderer.domElement.toDataURL("image/png");
    }
}

Based on this I can create new object RenderSetup with canvas 1590x425, but also smaller ones like 775x425.

My problem is: how to set the camera properties in order to correctly visualize front, back, left, right and top side additionaly ensuring that the whole construction group is visible (it’s width, height and depth may vary) and camera is looking at the center of each side (so boundingBox is useful for this). I have created method that tries to accomplish front side view:

private getFrontSideView(construction: Group): string {
        const camera = this.mainSetup.camera;
        const box = new Box3().setFromObject(construction);
        const center = box.getCenter(new Vector3), size = box.getSize(new Vector3);
        camera.matrix.setPosition(center.x, center.y, 0);
        camera.up.set(0, 1, 0);
        camera.lookAt(0, 0, 1);
        camera.zoom = .1;
        camera.updateProjectionMatrix();
        return this.mainSetup.getImage();
    }

It’s not perfect however and doesn’t respect rule of whole side being visible at all times. I managed to get a look at back side of the object, but I don’t know how to do it for left, right and top side. So my question is:

  • what parameters would I need to pass to setPosition method to get proper position for each side I mentioned earlier?
  • same for lookAt method and up as well,
  • what would be the perfect formula for zoom that will make whole side visible?
  • is it good approach or should I change something that will help me accomplish correct camera positioning for all the sides?

r152

Generally, you might want to do this:

  • position the camera at some distance from the object center (in a direction dependent on which side you want to view)
  • set the zoom factor so that the object fills up the view (either horizontally or vertically)

Here is my attempt (snapshots: left → view all; middle → view from X+; right → view from Z-):

https://codepen.io/boytchev/full/LYgXgOX

image

1 Like

Thank you so much, this works like a charm. I do have one more question however: the top view works just fine, but I would like it to be rotated by 90 degrees. What changes to adjustCamera should be made so rotation like this could be possible?

If ‘top’ means ‘Y+’, then try one of these:

adjustCamera( 0.00001, 1, 0, size.x, size.z )
adjustCamera( -0.00001, 1, 0, size.x, size.z )
1 Like

Yeah, that’s it, thank you once again