Guide on identifying the 3D limits of a camera's field of vision in three.js

I am working with a three.js scene and am interested in determining the 3D boundaries of the viewport.

Imagine a canvas that is 500px wide and 1000px tall. The camera is fixed at position { 0, 0, 100 }, looking towards the origin at { 0, 0, 0 }.

The camera's position is static and will not change.

If there is an object located at { 0, 0, 0 }, I need to be able to move it to different locations within the camera's field of view. How can I calculate the upper-left corner of the field of view, as well as the point that is 20% from the left and 10% from the top of the field of view?

Below is the camera object data:

{
    "object": {
        "uuid": "E26C5F88-CD17-45F8-A492-F3DD704949BF",
        "type": "PerspectiveCamera",
        "matrix": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 100, 1],
        "zoom": 1,
        "fov": 50,
        "aspect": 0.625,
        "near": 0.1,
        "far": 1000
    }
}

Answer №1

To position an item 20% from the left and 10% from the top, you can achieve this with the following code:

var left = 0.2;
var top = 0.1;
var depth = 0.7; // ranging from -1 to 1, determines the object's distance from the camera, with -1 being close and 1 being farthest
object.position.set( -1 + 2 * left, 1 - 2 * top, depth ).unproject( camera );

This code transforms a position from NDC (normalized device coordinates) within the range [-1, 1] into world coordinates.

It essentially reverses the process depicted in the following image (source), converting a point in NDC back into world coordinates:

https://i.sstatic.net/AMYuu.png

For instance:

var canvas = document.getElementById('canvas');
var scene = new THREE.Scene();
var renderer = new THREE.WebGLRenderer({canvas: canvas, antialias: true});
var camera = new THREE.PerspectiveCamera(45, canvas.clientWidth / canvas.clientWidth, 1, 1000);
var clock = new THREE.Clock();

var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({color: '#f00', wireframe: true});
var box = new THREE.Mesh(geometry, material);

scene.add(box);

var period = 5;
  
var top = 0.3; // 30%
var left = 0.2; // 20%
var depth = 0.7;

render();

function render() {
  requestAnimationFrame(render);
  
  if (canvas.width !== canvas.clientWidth || canvas.height !== canvas.clientHeight) {
    renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
    camera.aspect = canvas.clientWidth /  canvas.clientHeight;
    camera.updateProjectionMatrix();
  }
  
  box.position.set(-1 + 2 * left, 1 - 2 * top, depth).unproject(camera);
  box.rotation.y += clock.getDelta() * 2 * Math.PI / period;
  
  renderer.render(scene, camera);
}
html, body, canvas {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
    display: block;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js"></script>
<canvas id="canvas"></canvas>

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

Error: Attempts to access the 'avatar' property of a null value result in a TypeError

I've been attempting to showcase both an avatar and the user name, but I keep encountering this error. Despite trying to declare a user variable to troubleshoot, it's not resolving the issue. Error: Cannot read property 'avatar' of n ...

Transforming multi-layered form data into a JSON array structure for seamless integration with application/json

I'm currently developing a Laravel application and facing an issue with the $controller->wantsJson() method in the back-end. This method returns TRUE only if the content type of the request is set to application/json. jQuery.ajax({ type: ...

Absence of shadow casting in ThreeJS within react-three-renderer

I'm struggling to get a shadow to show up in my scene. Here are the steps I've already taken: Added the shadowMapEnabled attribute to the React3 element Configured the directional light in my scene exactly like the example in this repository En ...

How to effectively trigger a function to load images in React

When my react app loads, I want the images to load immediately. This involves calling the function collectionChanged(e.target.value) on application start. Inside a .jsx file, there is a function named getHomePage() which contains 4 functions. Upon calling ...

Creating a Paytm payment link using API in a React Native app without the need for a server

Suppose a user enters all their details and the total cost of their order amounts to 15000 rupees. In that case, the app should generate a Paytm payment link for this amount and automatically open it in a web view for easy payment processing. Any suggesti ...

Issue Encountered While Attempting to Show a Div Element within a Function

Check out this HTML code snippet: <div class="div1" id ="div1" onclick="onStepClicked()" style ="text-align:center">Step 1</div> And here is the corresponding Script: function onStepClicked() { var elem = document.getElementById(&apo ...

The Jqueryui image link is not displaying the image despite no error being reported

Can anyone help me figure out what I'm missing? I'm currently working with ASP.NET MVC 5 and have downloaded the JqueryUI combined via Nuget package. Despite no error references for css/js files, the close button is still not showing in the ima ...

Send various pieces of information using Jquery/Ajax

I have encountered a challenge with my script - it currently only sends one value to the requested URL, but I now need it to handle two values. Unfortunately, I haven't been able to figure out how to do this. Each checkbox on the page is paired with ...

Include the document when the query results in zero documents

Struggling to figure out how to add a document to a collection if a query returns no results. The current query lacks operators for checking the length or size of the result. How can this be achieved? The query in question: this.monthCollection = this.af ...

Sizing labels for responsive bar charts with chart.js

I'm encountering a problem with my bar chart created using chart.js - the responsive feature works well for some elements but not all. Specifically, the labels on my bar chart do not resize along with the window, resulting in a strange look at smaller ...

Wordpress-inspired navigation on the left

Currently, I am in search of a JavaScript library, preferably built with jQuery, that can replicate the functionality of the left menu bar in WordPress when a user is logged in. This menu features images with text, the ability to expand and collapse, a ho ...

Utilizing the power of Material-UI with React in conjunction with Python-Django: A comprehensive

I am seeking guidance on implementing React with Material UI components in my web application. The technologies I have utilized in multiple projects include: Materialize CSS, Javascript, Jquery. The technologies I wish to explore for future projects are ...

Managing headers for localhost with Access-Control-Allow-Origin

I've run into a challenge with my React app. I'm making endpoint calls to different servers and have withCredentials set to true to include a token/cookie in the requests. The issue arises when trying to make this work seamlessly on localhost. S ...

Is there a RxJS equivalent of tap that disregards notification type?

Typically, a tap pipe is used for side effects like logging. In this scenario, the goal is simply to set the isLoading property to false. However, it's important that this action occurs regardless of whether the notification type is next or error. Thi ...

How to troubleshoot passing json data from a controller to an AngularJS directive

I recently started learning AngularJS and I'm facing an issue with passing JSON data from the controller to a directive. When I try to display the data, nothing shows up and I encounter the following errors: 1. Uncaught SyntaxError: Unexpected token ...

Modal closes automatically after being clicked twice on data-bs-dismiss

Having an odd issue with Bootstrap 5.0.2 In order to close the modal, I have to double-click the button (data-bs-dismiss) It's worth noting that I use multiple modals on the page, but they only open when needed. <div class="modal" id="open-rat ...

Angular form displayed on the screen

I'm having trouble finding a solution to this issue, as the form data is not being output. var app = angular.module('myApp', []); app.controller('mainController', ['$scope', function($scope) { $scope.update = funct ...

When it comes to utilizing the method ".style.something" in JavaScript

Here is some javascript code that I am working with: function createDiv(id){ var temp = document.createElement('div'); temp.setAttribute("id", id); document.getElementsByTagName('body')[0].appendChild(temp); } c ...

Is there a way to use JavaScript to import several custom fonts at once?

Is there a way to import a long list of custom fonts as icons using Javascript? I have been obtaining the font list from an API, but importing them one by one with pure CSS using @font-face is time-consuming and difficult to maintain. @font-face { fon ...

JavaScript believes that the function is not defined, despite its clear existence

This question pertains to an issue regarding the recognition of Bookshelf.js model function as a function. The error message "Function is undefined, Bookshelf.js model function is not being recognized as a function" arises when trying to POST to the login ...