question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Issue with orthographic camera

See original GitHub issue

Hi

I have realized that in versions previous to R108 orthograpich camera behaved properly. When you set camera.near to a positive value (0.001), you could orbit to an specific object without being ocluded by objects previous from camera position to object geometry.

But since this version camera.near is behaving as it was set to -Infinity, I mean when you orbit to an specific object you are ocluded by objects that are previous from the camera position to object geometry.

This is very annoying because you cannot orbit to objects that are incide of other objects.

Could you please check this behavior?

Many thanks in advanced.

Here the piece of code to demonstrate the issue:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - orbit controls</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <link type="text/css" rel="stylesheet" href="main.css">
        <style>
            body {
                background-color: #ccc;
                color: #000;
            }

            a {
                color: #f00;
            }
        </style>
    </head>

    <body>
        <div id="info">
            <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - orbit controls
        </div>

        <script type="module">

            import * as THREE from '../build/three.module.js';

            import { OrbitControls } from './jsm/controls/OrbitControls.js';

            var camera, controls, scene, renderer;

            init();
            //render(); // remove when using next line for animation loop (requestAnimationFrame)
            animate();

            function init() {

                scene = new THREE.Scene();
                scene.background = new THREE.Color( 0xcccccc );
                scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 );

                renderer = new THREE.WebGLRenderer( { antialias: true } );
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                document.body.appendChild( renderer.domElement );

                camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
                camera.position.set( 400, 200, 0 );

                // controls

                controls = new OrbitControls( camera, renderer.domElement );

                //controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop)

                controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
                controls.dampingFactor = 0.05;

                controls.screenSpacePanning = false;

                controls.minDistance = 100;
                controls.maxDistance = 500;

                controls.maxPolarAngle = Math.PI / 2;

                // world

                var geometry = new THREE.CylinderBufferGeometry( 0, 10, 30, 4, 1 );
                var material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } );

                for ( var i = 0; i < 500; i ++ ) {

                    var mesh = new THREE.Mesh( geometry, material );
                    mesh.position.x = Math.random() * 1600 - 800;
                    mesh.position.y = 0;
                    mesh.position.z = Math.random() * 1600 - 800;
                    mesh.updateMatrix();
                    mesh.matrixAutoUpdate = false;
                    scene.add( mesh );

                }

                // lights

                var light = new THREE.DirectionalLight( 0xffffff );
                light.position.set( 1, 1, 1 );
                scene.add( light );

                var light = new THREE.DirectionalLight( 0x002288 );
                light.position.set( - 1, - 1, - 1 );
                scene.add( light );

                var light = new THREE.AmbientLight( 0x222222 );
                scene.add( light );

                //

                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

            }

            function animate() {

                requestAnimationFrame( animate );

                controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true

                render();

            }

            function render() {

                renderer.render( scene, camera );

            }

        </script>

    </body>
</html>

You can test it against the version 108 and to the current one.

The feeling of the user is that he cannot go through an specific object if there is any object in the path from object to camara position extending to Infinity.

Here some attachments:

image image

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
mrdoobcommented, Sep 10, 2020

@ua4192 You can achieve that by using PerspectiveCamera with a fov of 5 or so.

0reactions
ua4192commented, Oct 15, 2020

Hi.

Finally I decided to try to implement the same behaviour than for perspective camera, I mean that zoom in and zoom out will update camera position when orthographic camera is used:

Here my changes in OrbitControls.js library , it seems to work quite well:

function dollyIn( dollyScale ) { 
		if ( scope.object.isPerspectiveCamera ) {
			scale /= dollyScale;
		} else if ( scope.object.isOrthographicCamera ) {
			scale /= dollyScale;
			var distance = scope.target.distanceTo(scope.object.position);
			var normalizedVector = scope.object.position.clone().sub(scope.target).normalize();
			var deltaVector = normalizedVector.clone().multiplyScalar(distance * scale);
			var newPosition = scope.target.clone().add(deltaVector);
			scope.object.position.copy(newPosition)
			scope.object.position.set(newPosition.x, newPosition.y, newPosition.z);	
			var v3_camera = newPosition;
			var line_of_sight = new THREE.Vector3();
			scope.object.getWorldDirection( line_of_sight );
			var v3_distance = scope.target.clone().sub( v3_camera );
			var depth = v3_distance.dot( line_of_sight );
			var height_ortho = depth * 2 * Math.atan( 30 *(Math.PI/180) / 2 )
			var width_ortho  = height_ortho * pCamera.aspect;
			scope.object.left = width_ortho  / -2;
			scope.object.right = -width_ortho  / -2;
			scope.object.top = height_ortho /  2
			scope.object.bottom = height_ortho  / -2;
			scope.object.updateProjectionMatrix()
		} else {
			console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
			scope.enableZoom = false;
		}
	}
function dollyOut( dollyScale ) {
		if ( scope.object.isPerspectiveCamera ) {
			scale *= dollyScale;
		} else if ( scope.object.isOrthographicCamera ) {
			scale *= dollyScale;
			var distance = scope.target.distanceTo(scope.object.position);
			var normalizedVector = scope.object.position.clone().sub(scope.target).normalize();
			var deltaVector = normalizedVector.clone().multiplyScalar(distance * scale);
			var newPosition = scope.target.clone().add(deltaVector);
			scope.object.position.copy(newPosition)
			scope.object.position.set(newPosition.x, newPosition.y, newPosition.z);	
			var v3_camera = newPosition;
			var line_of_sight = new THREE.Vector3();
			scope.object.getWorldDirection( line_of_sight );
			var v3_distance = scope.target.clone().sub( v3_camera );
			var depth = v3_distance.dot( line_of_sight );
			var height_ortho = depth * 2 * Math.atan( 30 *(Math.PI/180) / 2 )
			var width_ortho  = height_ortho * pCamera.aspect;
			scope.object.left = width_ortho  / -2;
			scope.object.right = -width_ortho  / -2;
			scope.object.top = height_ortho /  2
			scope.object.bottom = height_ortho  / -2;
			scope.object.updateProjectionMatrix()
		} else {
			console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
			scope.enableZoom = false;
		}
	}

Best regards

Read more comments on GitHub >

github_iconTop Results From Across the Web

Orthographic Camera Issue - Unity Forum
Orthographic camera setup in my game. Camera settings ... I think issue occurs while Clipping Planes - Near is set to negative number....
Read more >
Orthographic view problems - camera position - Rhino
Hi I have to render some elevations, but everytime I load the view is always in a different position. I set the camera...
Read more >
Issue with Orthographic Camera after Defold v.1.2.143 - Bugs
collection and adding it back with necessary settings and that did not work either. I had also recently been having issues with the...
Read more >
problem with orthographic camera - LuxCoreRender Forums
problem with orthographic camera ... Hi, I've a simple scene: a box with open top, roughly a quarter of the top covered by...
Read more >
Orthographic Camera - Not Working Correctly. : r/unrealengine
Doesn't look like an Orthographic Camera problem to me, it looks like a lighting problem. If the scene is insufficiently lit you will...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found