Exploring Head-Linked/Off-center View in Three.js

I'm attempting to create a permanent head-coupled perspective without relying on the full headtrackr library. My head will remain stationary, but it will not be directly facing the screen.

For those interested, I have a small demonstration available for download and can be run using python -m SimpleHTTPServer 8000

The code I am using is derived from primarily this example by headtrackr and some parts of the headtrackr source code

My expectations are based on this particular image:

In the third image, I envision tilting my monitor slightly counterclockwise from above. This action should result in reducing Z and making X less than zero. Although I anticipate seeing the middle image displayed on my monitor, the actual output looks more like this:

Is the "window" I perceive as the XY-plane supposed to stretch similar to the middle orange rectangle depicted in the first diagram? To further illustrate my point about the "window," here is another static window:

Are off-axis perspective and head-tracking completely unrelated concepts? How can I achieve a convincing illusion of off-axis perspective in THREE.js?

Answer №1

By utilizing the setViewOffset function, you can achieve your desired outcome. Upon reviewing your diagram, I notice a slight discrepancy. It seems that the absence of a cube in the off-axis projection may be causing this. The key is to ensure that the frustum remains centered on a fixed point without any rotation of the camera to avoid perspective distortion.

To implement this using the setViewOffset method, it is recommended to set the fullWidth and fullHeight to a significantly larger size. This oversized view will then serve as the window for the view offset. As the user moves, this window will shift in the opposite direction of the viewer.

Answer №2

Projection mapping in 3D involves two key steps: corner-pinning textures and adjusting perspective. Despite their differences, they work together seamlessly.

In Three.js, creating a textured quad surface can be achieved by manipulating the corners of the quad in the XY plane without affecting the Z-axis. This process typically does not result in perspective errors but rather minor texture deformations. The extent of these deformations depends on how the projector illuminates the surface. Minimal corner adjustments are needed if the projection is perpendicular to the surface. In contrast, using a monitor eliminates the need for corner-pinning altogether.

The following step involves adjusting the texture based on the viewer's position relative to the physical surface. This adjustment requires considering the XYZ distance from the viewer to the screen center, pixel-to-real-life scaling factor, and surface dimensions.

In my demonstration, the blue faces of the cubes face the positive Z direction. Even when I rotate the real-world monitor, the orientation remains consistent in the monitor's Z axis. A slight discrepancy may occur due to local rotations compensating for changes in the physical world's orientation.

While Processing offers various techniques for projection mapping, SurfaceMapper stands out for its ability to map textures onto curved surfaces. Unfortunately, it only supports versions before Processing 2.0.

An interesting possibility would be developing a SurfaceMapper library for Three.js, allowing for immersive virtual environments with camera perspectives calibrated to match real-life viewers' positions on displays.

Answer №3

To achieve the desired effect, make adjustments to the perspective matrix by altering the values of -left, +right, -bottom, and +top. This will help you achieve the desired outcome.

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

Tips for updating the content within an HTML tag with jQuery

I am looking to update the parameter value of an applet tag based on the selection from a dropdown menu. As I am new to jQuery, I would appreciate any guidance on how to achieve this using jQuery. This is my current applet code: <applet id="decisiontr ...

What is the Best Way to Toggle the Visibility of Specific Buttons in a Table Using Jquery?

<html> <head> <script> $( "#clickMeButton" ).click(function() { $(this).next("#hiddenButton").slideToggle( "slow", function() { // Animation complete. }); }); </script> </head> <body> <table> <tr& ...

What method can be used to keep Chromium open while using Puppeteer?

I am trying to figure out how to launch only one instance of Chromium from my first script and then connect to it from subsequent scripts. I am aware of the puppeteer.connect() method, but the issue is that when I start the script responsible for launching ...

How to dynamically load a component within a class-based Vue component

I am facing an issue with loading two components dynamically using an object map. Info (options-based) SearchBar (class-based) While it works for the options-based component, I encounter an error stating _currentTab is undefined when trying to load a si ...

An unusual 'GET' request has been made to the '/json/version' endpoint in Express.js

Hey there, I'm facing a challenge with my Express project. For some reason, I keep receiving a 404 error due to a mysterious GET request to '/json/version'. The request seems to bypass the defined routers after adding session data and eventu ...

Display or conceal a text field in Vue 2/Vuetify 1.5 depending on whether a checkbox is selected, with the possibility of duplicated

I've created a product checkbox selection feature that dynamically shows or hides text fields based on the user's selection. Unfortunately, there is a glitch in the system where selecting the second item causes duplication of text fields from th ...

Alter the value of a parameter within a script tag with JavaScript/jQuery

Looking to dynamically change a parameter value using JavaScript or jQuery. Here is an example URL: www.exampleurl.com/somepage?foo=test I have a function that can extract the value after the 'foo' parameter: function getParameterByName(name, ...

Update the path dynamically in Next.js without the need to reload the page

Every time the user clicks on the continue button, a function is triggered. Within that function, I make the following call: push("/signup/page-2", undefined, { shallow: true }); All dynamic routes resembling /signup/[page].js that return <Component / ...

Tips for fixing the error "Unhandled error: state.set is not a function"

My code is utilizing immutable.js in the reducer, but I keep encountering an error stating 'state.set is not a function'. Interestingly, when I modify the code to exclude immutable, the error disappears. import React from 'react'; impo ...

I'm trying to display hidden forms on a webpage when a button is clicked using the DojoToolkit, but I'm having trouble figuring out what's going wrong with my code

Currently, I am trying to grasp the concepts of Dojotoolkit and my objective is to display a form when a button is clicked. Upon reviewing other examples, my code seems correct to me; however, there appears to be something crucial that I am overlooking but ...

Having issues with $_POST not retrieving values from .post

Below is the javascript snippet that I have written: function submitForm() { var name = document.getElementsByName('name').value ,email = document.getElementsByName('email').value ,subject = document.getElementsBy ...

What is the best way to allow JavaScript to access a Laravel asset?

Currently, I am working on creating a slideshow and have implemented a navbar.js file with the following code: images[0] = "{{ asset('cover/deanna-j-3GZlhROZIQg-unsplash.jpg')}}"; images[1] = "{{ asset('cover/kevin-laminto ...

Error Alert: React Native object cannot be used as a React child within JSON, leading to an Invariant Violation

When using React-Native: To start, here is the example code of a json file: Any placeholders marked with "..." are for string values that are not relevant to the question. [ { "id": "question1" "label": "..." "option": [ { "order": 1, "name": "..."}, ...

Problem encountered when trying to use the sharp package in NuxtJS

I attempted to implement this code in my Nuxt project, but it encountered an issue during compilation. Within my plugin/sharp.js file: import vue from "vue" import sharp from "sharp" vue.use(sharp) And in my nuxt.config.js file: plugi ...

Adding Jade template variable to an inline function

Trying to implement the JSCharts library. block content | <div id="chartcontainer">This is just a replacement in case Javascript is not available or used for SEO purposes</div> script. var myData=new Array() var myData = new Array([10 ...

JavaScript tool for connecting tags with JSON properties

As a beginner in JS, I am curious if there exists a JS library that can help bind html fields to a JS object. For example: <div class="js_source"> <input field="name" /> <input field="surname" /> <button type="button">S ...

Utilizing the $set method to capture a jQuery variable and append it to a Vue array object

Currently, I am retrieving data from an API using jQuery's getJson method to extract the information. After successfully obtaining the data, my aim is to assign it to a Vue array object by making use of app.$set. Although I have managed to extract an ...

Enhance Your Tables with JQuery Calculations

I have a table that is populated from a database. Each field in the table is hidden until it is selected from a dropdown list. I also need to calculate the total of only the visible rows, not all rows including hidden ones. Can you please advise on how I c ...

What is the process of generating a dynamic card/button element on an ASP.net webpage using information from the backend database?

I'm faced with a challenge of displaying employees' names and titles from a MSSQL Server database table on an ASP .NET webform as individual "card" objects. Currently, I am able to showcase a static number of records by using an asp button object ...

When I click on the delete button in the dialog box, a horizontal scroll bar appears on the page

I'm dealing with a table that includes an 'approved' column with three conditions. One of these conditions triggers the appearance of a delete button along with a confirmation dialog box made using Vuetify's dialog component. The iss ...