Shaky xy positions while mapping a vector to NDC

Exploring ThreeJS has been an intriguing experience for me, especially when projecting vectors in the world space onto normalized device coordinates (NDC). Surprisingly, everything works flawlessly without any hiccups.

However, a noticeable issue arises when swiftly panning the view, resulting in a significant amount of jitter in the x/y coordinate produced by the projection. While object #2, which orbits around the origin, shows less obvious jitter, object #1 positioned at the origin should remain stationary as the camera pans, only to orbit around the origin:

https://i.sstatic.net/PJO5j.gif

Initially, I suspected that the DOM updates might not be keeping pace with the rAF callback execution. However, upon inspecting the x/y coordinates of object #1, I observed the same jittering behavior. For instance, focusing solely on the x-coordinate, it fluctuates around the value of 323.50 while rotating the camera, despite pointing directly at the vector's center:

https://i.sstatic.net/22E1n.png

Take a look at the example provided below:

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

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

// Rest of the JavaScript code and example omitted for brevity
body {
  position: relative;
  margin: 0;
  padding: 0;
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

.overlay {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 0;
  display: grid;
  place-items: center;
  background-color: #555;
  width: 48px;
  height: 48px;
  border: 4px solid #fff;
  border-radius: 50px;
  transform: translate(calc(var(--x, 0) - 50%), calc(var(--y, 0) - 50%));
  color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.146.0/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dca8b4aeb9b99cecf2ede8eaf2ec">[email protected]</a>/examples/js/controls/OrbitControls.js"></script>

Answer №1

To achieve the desired result, ensure that you call camera.updateMatrixWorld(); before executing project(camera) in order to utilize the current matrix for accurate calculations.

In a practical scenario where the overlayElement and the scene require full synchronization in each frame, it is recommended to first invoke controls.update() and renderer.render(scene, camera), and then proceed with updating the overlays as shown below.

controls.update();
renderer.render(scene, camera); // the renderer.render() function automatically includes camera.updateMatrixWorld()

// camera.updateMatrixWorld();

pointsToProject.forEach((vector, i) => {
  const {
    x,
    y
  } = vector.clone().project(camera);
  :
});

// controls.update();
// renderer.render(scene, camera);

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

Strange error message regarding ES6 promises that is difficult to interpret

Snippet getToken(authCode: string): Promise<Token> { return fetch(tokenUrl, { method: "POST" }).then(res => res.json()).then(json => { if (json["error"]) { return Promise.reject(json); } return new Token ...

When an import is included, a Typescript self-executing function will fail to run

Looking at this Typescript code: (()=> { console.log('called boot'); // 'called boot' })(); The resulting JavaScript is: (function () { console.log('called boot'); })(); define("StockMarketService", ["require", "exp ...

Preventing an image from being repeated when using Canvas drawImage() without having to clear the entire canvas

How can I prevent multiple instances of the same image from smearing across the canvas when drawing it? The platforms seem to stick together and not separate properly. Why do I have to clear the entire rectangle for everything to disappear? Does anyone ha ...

Issue with Window.close() not working to close the current tab

When navigating from my webpage to a new page in a different tab, I would like for my original webpage to close once the new tab has loaded. For example, if I am on pageA and I open pageB using window.open(), I want pageA to close when pageB is opened. I a ...

When attempting to call the remove() function of an AFrame component, an error occurs stating that the property 'object3D' is undefined

Currently, I am developing a custom timer component for AFrame. This unique timer is created using basic three.js elements by grouping various Object3D's and then associating them with the entity (el) using: seconds = new THREE.Object3D(); parent1 = ...

"Despite the null date in Node.js, the validation for expiration dates less than Date.now() is still being enforced

I am currently working on implementing validation for evaluating the finish status. However, my validation is encountering a problem with the "null" value of expiresAt. It should indicate that the evaluation has been successfully completed. The issue lie ...

Generate a novel item by organizing the key of an array of objects

I have an array of objects containing various items: [ { CATEGORY:"Fruits" ITEM_AVAIL:true ITEM_NAME:"Apple" ITEM_PRICE:100 ITEM_UNIT:"per_kg" ITEM_UPDATED:Object ORDER_COUNT:0 }, { CATEG ...

What is the best way to automatically set today's date as the default in a datepicker using jQuery

Currently utilizing the jQuery datepicker from (http://keith-wood.name/datepick.html), I am seeking to customize the calendar to display a specific date that I select as today's date, rather than automatically defaulting to the system date. Is there a ...

javascript The onclick function works only for a single interaction

Every time I click on the Button, the first click triggers func1 successfully. However, subsequent clicks fail to execute the function. Even the alert('func1') statement is not being displayed. What mistake am I making here? func ...

Utilizing AngularJS "controller as" syntax within templates

Recently diving into the AngularJS world, I embarked on setting up a simple laravel/angular JWT authentication by following this specific tutorial. My goal is to utilize the "Controller As" syntax instead of relying on $scope as instructed in the tutorial ...

What is the best approach for retrieving values from dynamically repeated forms within a FormGroup using Typescript?

Hello and thank you for taking the time to read my question! I am currently working on an Ionic 3 app project. One of the features in this app involves a page that can have up to 200 identical forms, each containing an input field. You can see an example ...

Developing with Phonegap Build: A Guided Process

With all the conflicting information available, I am seeking clarity on this topic. Objective: To create and enhance a Phonegap app using Phonegap Build. 1) My preference is to utilize Phonegap Build without needing to install Android and iOS SDKs. 2) I ...

Unable to execute an Angular 2 application within Visual Studio 2015

I encountered an error while trying to set up an environment on VS 2015 with Angular2. Whenever I run the command "npm start," I receive the following error message. I attempted using "npm cache clean --force" before running "npm start," but the error pers ...

Is there a way to prevent a background video from automatically playing whenever the user navigates back to the home page?

Recently, I was given a design that requires a background video to load on the home page. Although I understand that this goes against best practices, the client has approved the design and now I need to come up with a solution. The video is already in pla ...

Utilizing lazy evaluation, multiple functions are triggered by ng-click in succession

Successfully disabled ngClick on an element when the scope variable (notInProgress) is set to true as shown below: <a data-ng-click="notInProgress || $ctrl.setTab('renewal');</a> Now, I want to include additional functions to be execut ...

Unable to access npm run build on localhost

I have developed a web application using react and node.js, and now I want to test it with a production build. After running npm run build in the app directory, I successfully created a build folder. However, when trying to run the application using local ...

Listening for an event or using a CSS pseudo-class to detect when the scrollbar becomes

Are there any JavaScript event listeners or CSS pseudo classes that can detect when a scrollbar appears and disappears? For example, on Mac OS and Windows Internet Explorer 10 or newer, the scrollbars are hidden by default but appear when scrolling begins. ...

What strategies can be utilized to condense code when needing to adjust a className based on various props?

I am looking to condense this code, particularly the [if~else if] block, in order to dynamically change a className based on different props passed. export default function Button(props) { const { name, height, color, bgColor } = props; let className = ...

Understanding the time complexity of Object.entries()

Is the complexity of Object.entries() in JavaScript known? According to information from this question, it seems like it could possibly be O(n) if implemented by collecting keys and values as arrays and then combining them together? ...

Modifying the background image of div elements with JQuery in a loop function is ineffective when using Google Chrome

I am facing an issue in my application where I have a for loop to change the background image of two divs. The code snippet is as follows: for (var i = 0; i < length; i++) { $("div_" + (i + 1)).css("background-image", "../imageFile.png"); ...