Scaling a plane in Three.js to cover the entire screen

My process of adding a plane to the scene goes like this:

// Setting up Camera
this.three.camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 60);
// Creating Plane
const planeGeometry = new THREE.PlaneBufferGeometry(1,1,this.options.planeSegments,this.options.planeSegments);
const planeMat = new THREE.ShaderMaterial( ... )
this.three.plane = new THREE.Mesh(planeGeometry,planeMat);
this.three.scene.add(this.three.plane);

It's a simple process so far. The next step involves determining how to adjust the position of the plane on the Z axis in order to fill the browser viewport. To accomplish this,

// Referencing attachment "solving for this" - closeZ is calculated
const closeZ = 0.5 / Math.tan((this.three.camera.fov/2.0) * Math.PI / 180.0);
this.uniforms.uZMax = new THREE.Uniform(this.three.camera.position.z - closeZ);

https://i.sstatic.net/7tRku.png

With this information, I can determine how much needs to be added to the Z axis in my shader to make the plane fill the viewport. Here is what the Vertex Shader looks like:

uniform float uZMax;

void main() {   
    vec3 pos = (position.xy, uZMax);
    gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1 );
}

The current setup zooms the plane to fill the viewport, but it impacts the Y-Axis, not the X-Axis.

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

I am eager to discover why my calculations are influencing the Y-Axis and how I can adjust them to ensure that the plane fills the width of the viewport instead of just its height?

Edit:

The goal I'm striving for is similar to what is demonstrated in this example. However, in the provided example, they simply scale the x- and y-pixels to occupy the screen without true 3D rendering or lighting effects.

I aim to physically move the plane closer to the camera by adjusting z-values, allowing me to calculate surface normals and eventually incorporate lighting in the fragment shader based on the alignment of these normals with the direction of light - akin to raymarching techniques.

Answer №1

To easily achieve a fullscreen visual effect, follow this setup:

const view = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );

const shape = new THREE.PlaneBufferGeometry( 2, 2 );

By creating a mesh using this geometry and a personalized shader material, the orthographic camera will deliver the desired fullscreen display. This method is commonly employed in post-processing examples where a single quad must fill the entire viewport.

Answer №2

After some investigation, I managed to find the root cause of the issue which was related to the aspect ratio provided to the camera. In case someone else encounters this problem in the future, here is a breakdown of how to address it:

I had mistakenly assumed that the camera's field of view (FOV) was uniform in all directions. However, it actually refers to the FOV along the Y-Axis, requiring us to convert it for the X-axis as well:

function calculateXAxisFOV() {
        // Convert angle to radians
        const FOV = this.three.camera.fov;
        let yFovRadians = FOV * Math.PI/180;
        // Calculate X-FOV in radians
        let xFovRadians = 2 * Math.atan( Math.tan(yFovRadians/2) * (window.innerWidth / window.innerHeight));
        // Convert back to degrees
        let xFovDegrees = xFovRadians * 180/Math.PI;
        return xFovDegrees;

}

Subsequently, we can utilize this calculated angle in the closeZ computation instead of directly using the camera's fov. This adjustment ensures proper alignment with the window width.

const closeZ = 0.5 / Math.tan((this.calculateXAxisFOV()) * Math.PI / 180.0);
this.uniforms.uZMax = new THREE.Uniform(this.three.camera.position.z - closeZ);

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

Node: permit the event loop to run during lengthy tasks and then return

Currently, I am facing an issue with a function that works like this: function longFunc(par1,par2) { var retVal = [], stopReq = false; function evtLs() { stopReq = true; } something.on("event", evtLs); for(var i=0; ...

Discover the ultimate strategy to achieve optimal performance with the wheel

How can I dynamically obtain the changing top position when a user moves their mouse over an element? I want to perform some checks whenever the user scrolls up, so I tried this code: HostListener('window:wheel', ['$event']) onWindowS ...

I'm looking to extract the values of input fields from a specific form that I have just clicked on. Each form and their input fields share the same class, but each input field contains

When working with a PHP while loop that generates multiple forms with the same id and classes, it can be challenging to target specific input values. Each form input has its own distinct value, but clicking on the submit button of a particular form shoul ...

Implement the callback-console.log feature from the epic-games-api into an Express.js application

Looking to integrate Epic Games output into an Express.js GET request but don't have any JavaScript experience, so go easy on me! XD const EpicGamesAPI = require('epicgames-status'); const express = require('express') const app = ...

Angular implementation of a dynamic vertical full page slider similar to the one seen on www.tumblr

I'm determined to add a full-page slider to the homepage of my Angular 1.x app After testing multiple libraries, I haven't had much luck. The instructions seem incomplete and there are some bugs present. These are the libraries I've experi ...

jinja2.exceptions.TemplateSyntaxError: instead of 'static', a ',' was expected

My current project involves using Flask for Python, and I encountered an error when running the project from PyCharm. The error message points to line 192 in my home.html file: jinja2.exceptions.TemplateSyntaxError: expected token ',', got &ap ...

Clicking on a table will toggle the checkboxes

I am facing an issue with this function that needs to work only after the page has finished loading. The problem arises due to a missing semicolon on the true line. Another requirement is that when the checkbox toggle-all is clicked as "checked", I want ...

Looking for specific styles within CSS classes

I am looking to identify all the classes with styling attributes defined using either vanilla JS or jQuery. Specifically, I want to find classes that have the border style defined along with its value. It would be great if I could also modify these classes ...

How can I display a loading indicator in an Angular 7 application while waiting for all API responses to complete?

I have multiple API calls on a page, each with different response times. When the first API call finishes and sets the loading indicator to false, I want to keep the indicator active until all five API calls have responded. Can you provide any suggestions ...

Sending Data From Child Component to Parent Component in React Using a onClick Event

I am a newcomer to using React and am currently immersed in a React Rails application. <h1><img src={activity.image_url}/></h1> <p> {activity.name} </p> <p> Rating: {activity.rating} </p> ...

Finding a way to extract a singular text node after the Span element but before the br tag using Selenium WebDriver

I am trying to retrieve the text between span and br tags. In the HTML snippet below, I am aiming to extract the Orange text: <td role="grid cell"> <span class="ui-column-title">Fruits</span> <span id="all fruits"> "Orange" < ...

Using AngularJS to filter options in a dropdown list and trigger a function with ng-change

I have a dropdown menu that is being formatted using filters to display the text in a certain way. I need to send the selected item's ID value to the controller instead of just the name: <select ng-model="my_field" ...

What are some ways to avoid an image looking faded when adding it to the scene background in Three.js?

I've been experimenting with loading images onto the scene background using the TextureLoader() class to prevent them from appearing greyed out. Following a tutorial on three.js https://www.youtube.com/watch?v=xJAfLdUgdc4&list=PLjcjAqAnHd1EIxV4FS ...

Warning: The NextUI ThemeProvider may trigger a notice for additional attributes from the server, such as class and style

I recently integrated NextUI into my NextJS 14 application The issue seems to be originating from the ThemeProvider in my main providers.tsx file: 'use client'; import { NextUIProvider } from '@nextui-org/react'; import { ThemeProvide ...

Refresh object attributes with newly retrieved data from MongoDB

I've been attempting to update object properties with new data retrieved from MongoDB. However, the following code isn't working as expected and I can't figure out why. Can anyone provide some assistance? var UserDB = require('../mode ...

The AJAX success callback function failed to execute in cases where the dataType was set to JSONP during Cross domain Access

type = 'math'; var ajurl = "sample.com&callback=myhandler"; var datas = "cateid=" + cateid + "&type=" + type + "&pno=" + pno + "&whos=" + whos; $.ajax({ type: "GET", url: ajurl, data: datas, contentType: "application/json; ...

Parse JSON files from a folder and concatenate them to a CSV using Node.js

Thank you for offering your help. I have a collection of JSON files located in a directory with unknown names. I need help with the following: (1) Reading all the JSON files (2) Appending the data from the JSON files to output.csv (3) Adding "-Appended" t ...

I'm having trouble getting the npm install for classnames to work within my li tag

I need some help with React JS. I'm attempting to merge my classes using the npm package called classnames. https://www.npmjs.com/package/classnames However, I'm encountering an issue: classnames doesn't seem to be working as expecte ...

Utilizing the power of Koa.js in conjunction with MongoDb for seamless development

Having an issue, or maybe just lacking some knowledge here. The question is pretty straightforward - I have this code: router.get('/', (ctx, next) => { MongoClient.connect(url, {useNewUrlParser: true}, function (err, db) { if (err) th ...

How can we eliminate the 'www' in a URL using NodeJS and Express?

What is the best way to eliminate the 'www' in a URL using NodeJS + Express? For instance, when a client connects to , how can we automatically redirect them to without the 'www'? ...