The orthographic camera in Three.js offers a unique perspective for rendering

Currently, I am working on a project involving an application that showcases various 3D models. The process involves loading the models, creating meshes, and adding them to the scene as part of the standard procedure. Upon completing the addition of the last mesh, we compute the bounding box to adjust the camera position in order to encompass the entire scene. This calculation takes into account both the total geometry size and the viewport dimensions.

    if (bounds.bx / bounds.by < camera.aspect) {
        /* Vertical maximum */
        r = bounds.by / (2 * Math.tan(Math.PI / 8));
    } else {
        /* Horizontal maximum */
        hFOV = 2 * Math.atan(Math.tan(Math.PI / 8) * camera.aspect);
        r = bounds.bx / (2 * Math.tan((hFOV / 2)));
    }

The object bounds stores the width and height of the bounding box. Following this computation, we adjust the camera position with a small additional ratio for aesthetic purposes, providing some space between the geometry and the screen border before rendering.

    camera.position.z = r * 1.05;

Although this implementation works smoothly with the PerspectiveCamera, our team is looking to transition to using the OrthographicCamera. However, this shift has proven challenging. The models appear too small, the mousewheel zoom functionality from the TrackBall Controls is lost, and the camera relocation algorithm no longer functions as expected. Additionally, there is confusion regarding the constructor parameters for the camera - are the width and height specified intended for the geometry or the viewport?

Answer №1

In three.js, the method for creating an orthographic camera involves the following steps:

var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, near, far );

The values for width and height represent the dimensions of the camera's frustum in units of the world space.

The parameters near and far indicate the distance to the near and far planes of the frustum respectively, also measured in world-space units. Both values must be greater than zero.

To maintain proper proportions and avoid distortion, it is advisable to set the aspect ratio of the orthographic camera (width / height) to match that of the canvas where the scene will be rendered. (refer to *Note below)

It should be noted that some examples in three.js use window.innerWidth and window.innerHeight as arguments in this constructor. This approach is only suitable if the orthographic camera is intended for rendering textures, or if the world units are defined in pixels.


*Note: In reality, the aspect ratio of the camera should correspond to the aspect ratio of the viewport within the renderer. The viewport can be a subsection of the canvas. If the renderer's viewport is not set explicitly using renderer.setViewport(), it will default to the size of the canvas, maintaining the same aspect ratio as the canvas itself.

Based on three.js version r.73

Answer №2

Just a heads up for the future: Check out the updated video here

var width = container.clientWidth;
var height = container.clientHeight;
var viewSize = height;
var aspectRatio = width / height;

_viewport = {
    viewSize: viewSize,
    aspectRatio: aspectRatio,
    left: (-aspectRatio * viewSize) / 2,
    right: (aspectRatio * viewSize) / 2,
    top: viewSize / 2,
    bottom: -viewSize / 2,
    near: -100,
    far: 100
}

_camera = new THREE.OrthographicCamera ( 
    _viewport.left, 
    _viewport.right, 
    _viewport.top, 
    _viewport.bottom, 
    _viewport.near, 
    _viewport.far 
);

In my case, I am working with world units in pixels. Therefore, I am using container.clientWidth and container.clientHeight as the width and height. Keep in mind that this may not be suitable for your scenario.

Answer №3

            Adjusting the camera dimensions by reducing them to 95% of their original values:
            camera.top = (.95*camera.top);
            camera.bottom = (.95*camera.bottom);
            camera.left = (.95*camera.left);
            camera.right = (.95*camera.right);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Store the link in a variable and retrieve its content into another variable

Is there a way to extract the content of a link stored in a variable and store it in another variable using jQuery or javascript while working on an XML page? I know this is possible with php, but since I am developing a Chrome extension, I am wondering ...

Angular- Product Details

I'm currently expanding my knowledge of angular (utilizing the ionic framework with phone gap included) and I'm working on developing a single application that displays a list of data. When a user clicks on an item in the list, I want to show the ...

Extracting data from a webpage's dynamic table using Python with Selenium and

I am planning to extract the data from the JavaScript tables found in the following link: import codecs import lxml.html as lh from lxml import etree import requests from selenium import webdriver import urllib2 from bs4 import BeautifulSoup URL = &apo ...

What is the best method for executing an HTTP request to retrieve the complete source page if certain aspects are loaded through JavaScript?

I am trying to retrieve the HTML webpage from . However, a portion of the HTML file is loaded through JavaScript. When using HTTP.jl to fetch the webpage with HTTP.request(), I only receive the part of the HTML file that was loaded before the execution of ...

How can I design a tooltip window using HTML, jQuery, or other elements to create a box-like effect?

As someone who is new to front end development, I am facing a challenge with my web app. The requirement is that when a user hovers over an image, I need a 'box' to open nearby and display a pie chart. Although I have managed to get the hover fu ...

Generate a new passport session for a user who is currently logged in

I am currently utilizing passport js for handling the login registration process. After a new user logs in, a custom cookie is generated on the browser containing a unique key from the database. Here's how the program operates: When a new user logs ...

What techniques can be used to maintain the value of 'this' when utilizing async.apply?

Employing async.parallel to simultaneously run 2 functions, initiated from a static function within a mongoose model. In this code snippet (where the model contains a static function named verifyParent), I utilize this to access the model and its functions ...

Leveraging JSON data in a client-side JavaScript script

Recently, I started exploring node.js and express. One issue that I am currently facing is how to correctly retrieve json data in a client-side javascript file. I keep receiving a 404 error indicating that the .json file cannot be found. In my project&apo ...

React: Implementing localStorage token addition in loginHandler function using State hook is not functioning as expected

I've implemented an AuthContextProvider in my React application to handle user authentication and logout functionality: import React, { useState } from "react"; import axios from "axios"; import { api } from "../api"; co ...

Is it possible to prevent users from clicking on a jQuery UI Datepicker?

Is it possible to disable the functionality of a jQuery UI Datepicker so that clicking on it does nothing but display the date? I attempted: $("#calendar").datepicker({ disabled: true, altField: '#note_date', maxDate: 0 }); Unfortu ...

Load texture using ImageUtils with callback in Canvas Renderer

Currently, I am utilizing three.js revision 53. While attempting to load a texture in Canvas Renderer (specifically on Win7) and incorporating a callback for the onLoad event, the texture fails to display. Surprisingly enough, removing the callback functi ...

Use JavaScript to switch the h1 title when selecting an option from the dropdown menu

As a beginner in coding, I am struggling to find a solution using an if statement for this particular problem. Although I can achieve the desired result with HTML code and options, this time I need to use arrays and an if function. My goal is to create a ...

Accordion elements that are active will move all other content on the page

I am currently working on creating an accordion using the following code: https://codepen.io/rafaelmollad/pen/JjRZbeW. However, I have encountered a problem where when clicking on one of the accordion items, the content expands and pushes the title upward. ...

Error: The Stripe webhook payload must be submitted as either a string or a Buffer

I'm currently working on setting up a subscription system using Stripe. I have mostly followed the code from their documentation, but I keep encountering the following error: Webhook signature verification failed. Webhook payload must be provided as a ...

Retrieve the file path of the local system's home directory from the server

The server is up and running, I am looking to retrieve the file path of the local system in which the AWS server is operating using Node.js. ...

Confirming the structure of a URL using JavaScript/jQuery

I have a text field where users input URLs. I need to validate the format of the URL using regular expressions. Specifically, I am looking for invalid URLs such as: http://www.google.com//test/index.html //Invalid due to double slash after hostname http: ...

prompting users in a node.js application

I need help with querying the user multiple times in my Node.js application. Currently, all responses get printed out together and the first response is processed by both functions. I suspect this issue arises from the asynchronous nature of Node.js. Can s ...

JavaScript scripts are unable to function within an Angular directive's template due to compatibility issues

I'm facing an issue with a directive (function (angular) { 'use strict'; function digest(factory) { var directive = { restrict: 'E', templateUrl: '/js/app/digest/templates/digest.tem ...

Strategies for redirecting search queries when adding a new path

Issue I am facing a challenge with pushing a new path to the URI while maintaining existing search queries. For example: Current URL: https://example.com/foo?bar=123&foobar=123 When I use history.push('newPath'), I end up with https://exa ...

Why is the type of parameter 1 not an 'HTMLFormElement', causing the failure to construct 'FormData'?

When I try to execute the code, I encounter a JavaScript error. My objective is to store the data from the form. Error Message TypeError: Failed to create 'FormData': argument 1 is not an instance of 'HTMLFormElement'. The issue arise ...