How can I selectively apply a texture to a specific section of a face in Three.js?

I am exploring the idea of creating portals using threejs by sketching an ellipse and then applying a WebGlRenderTarget texture mapping to its face. Currently, I have a function that partially works, but it attempts to stretch the large rectangular buffer from the render target onto the ellipse. What I am aiming for is to project the texture onto the ellipse in its original dimensions and remove any excess that does not align with the ellipse, as shown below:

Before Projection:

https://i.sstatic.net/3nSbp.jpg

After projection:

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

I am seeking guidance on achieving this effect in threejs. I have explored texture coordinates, but I am unsure of how to implement them. Additionally, I came across a projection light PR in threejs that could potentially be useful?

Edit: I recently watched a video by Sebastian Lague on portals, where he utilized "screen space coordinates" for a similar effect. Any tips on using those effectively?

Thank you for your assistance!

Answer №1

Check out my codepen demonstration:
https://codepen.io/cdeep/pen/JjyjOqY

Understanding UV mapping allows us to assign specific parts of a texture to certain vertices of a geometry. More information can be found here:

You can iterate through the vertices to set the corresponding UV values.

const vertices = ellipseGeometry.attributes.position.array;
for(let i = 0; i < numPoints; i++) {
  const [x, y] = [vertices[3*i], vertices[3*i + 1]];
  uvPositions.push(0.5 + x * imageHeight / ((2 * yRadius) * imageWidth));
  uvPositions.push(0.5 + y / (2 * yRadius));
}
ellipseGeometry.setAttribute("uv", new THREE.Float32BufferAttribute(uvPositions, 2 ));

UV coordinates range from (0, 0) to (1, 1) from bottom left to top right. The provided code is effective for an ellipse on the x-y plane. Otherwise, adjustments need to be made for the ellipse's plane.

Further resources on texture mapping in three.js can be found here:

Edit: Please note that the demo may not exactly resemble a portal. To achieve that effect, you would need to dynamically move the texture based on the camera perspective, which can be a complex task.

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

"What could be the reason for web3.eth.getAccounts() method returning an empty array when used with console.log

Upon executing web3.eth.getAccounts().then(console.log);, I encountered an empty array and also received a warning stating ./node_modules/web3-eth-accounts/src/scrypt.js Critical dependency: the request of a dependency is an expression. The project began w ...

Is it secure to transmit Tenant ID's as GET parameters to the API in a Multi-Tenant database environment?

When working with a Multi-Tenant database, is it secure to pass Tenant ID's as query string parameters to the API while using popular JavaScript-based UI platforms like Angular or Vue and ensuring both the site and the API are HTTPS? For example, let ...

Increase the totalAmount by adding the product each time

Can someone help me understand why the totalAmount shows as 20 when I add a product? Also, why doesn't it increase when I try to increment it? Any insights would be appreciated. Thank you. ts.file productList = [ { id: 1, name: 'Louis ...

Issue with XHR progress not functioning properly when cache is not cleared in CHROME

I will provide a detailed explanation of my issue. IMPORTANT-1: This issue arises with large files and under slow upload speed network conditions. IMPORTANT-2: The progress bar functions correctly in browsers like Edge. IMPORTANT-3: The problem only manif ...

What is the best way to insert a line break into every row of the table I'm displaying?

My current project involves building a web scraper that successfully prints a table, but the formatting of the table is less than satisfactory. I've experimented with a few solutions so far: 1) const people = [...peopleList].map(personEntry => pe ...

Difficulties accessing MongoDb database using Node.js

Having issues when trying to read this data collection using mongoose and Node.js: I have a single JSON object within my Collection and I'm attempting to access it with the following code: materias.find().exec(function(err1,materias){ if(err ...

Cannot locate module required for image change

If I drag the mouse over a flexible component, I want the image to change dynamically. import React, { Component } from "react"; export default class DynamicImageComponent extends React.Component { render() { return ( <img src= ...

How can I prevent right-clicking with Ctrl+LeftMouseClick in Firefox on MacOS?

I'm looking to implement a shortcut using Ctrl+LeftMouseClick in my React project. It functions perfectly on Chrome on my Mac, but in Firefox the shortcut initiates a right mouse click (event.button = 2). I believe this may be due to MacOS's Rig ...

JavaScript: Break apart and tally the number of words within a given string

If I have an input string with the value "testing the string", I want to create a function that splits each word and counts how many times each word appears in the input string. The desired output should look like this: testing: 1, the: 1, string: 1 Than ...

Adding a fresh HTML element to a list at a designated location

I found this excellent example on CODEPEN Is there a way to insert a new random number into the list so that it appears after 24 but before 19? Is there an efficient solution or do I need to manually check each li element and determine where to place the ...

Click the button to dynamically add a Bootstrap select element

I need assistance creating a select element with a Bootstrap class using a button click event. The element is successfully inserted into the body, but it does not appear on the page. https://i.sstatic.net/ppHfL.png <html> <head> <link re ...

A step-by-step guide to incorporating expandable and collapsible images within a div element using X

I have successfully created dynamic divs with some data that expand and collapse perfectly. Now I am looking to add expand and collapse images on these divs. I am relatively new to designing in xslt. <xsl:template match="category[key!='org.model.C ...

Show React compilation errors

Whenever I used to start React as per their tutorial, it would show compile errors in this specific scenario. However, after setting up a webpack configuration for a React project, if there are compilation errors, the page simply remains blank. Is there ...

In what ways can you toggle the visibility of table rows and data dynamically with the onchange event in HTML?

I'm dealing with an HTML code that can dynamically change table data based on user selection. Here's the snippet of my HTML code: Select an option: <select name='set' id="set" class="selectpicker" onchange='displayFields(this. ...

Trouble arises when attempting to append a class through ng-class upon clicking

In a specific scenario, I am trying to change the border color from black to red in a div by appending a class using ng-class when clicked. However, when clicking a button, the modal opens but the class is not being appended as expected. <div ng-class ...

Issue with Three.js sample scene not functioning correctly

Forgive my lack of experience, but I am new to three.js and seeking guidance from the experts. I am starting with a basic scene to build my understanding from there. I began with an example scene from the documentation, but when I run it locally or on my s ...

Unlocking Hidden Functions within React Components

I just finished creating my first React component as a Function based one, and now I'm attempting to refactor it to be Class based. However, I'm facing some challenges in the conversion process, particularly with the RenderItem method. Every time ...

The Ionic search bar will only initiate a search once the keyboard is no longer in view

In my Ionic application, I have implemented a search bar to filter and search through a list. The filtering process is triggered as soon as I start typing in the search bar. However, the updated results are not displayed on the screen until I manually hide ...

The performance of Three.js significantly decreases when utilizing onMouseMove in conjunction with RayCaster

I am currently working on an application using three.js, but I am encountering serious performance issues. This particular part of the application is inspired by the Voxel Painter example. In my version, the user initiates placement by clicking on a cell, ...

How to add Bootstrap and Font Awesome to your Angular project

After attempting to add Bootstrap and Font Awesome to my Angular application, I am encountering issues. I utilized the command npm install --save bootstrap font-awesome and included both libraries in the angular.json file as follows: "styles": ...