Tips for adding texture to the uneven surfaces of a Sphere?

My goal is to assign a unique texture to each face of a THREE.js sphere. To achieve this, I utilized a SphereGeometry to calculate the vertices and then converted each face into a PlaneGeometry by utilizing the vertices of the faces.

THREE.SpherePlaneGeometry = function ( v1, v2, v3, v4 ) {

  THREE.Geometry.call( this );

  var normal = new THREE.Vector3( 0, 1, 0 );

  this.vertices.push( v1.clone() );
  this.vertices.push( v2.clone() );
  this.vertices.push( v3.clone() );
  this.vertices.push( v4.clone() );

  var face = new THREE.Face4( 0, 1, 2, 3 );

  face.normal.copy( normal );
  face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone(), normal.clone() );

  this.faces.push( face );

  var uvs = [
    new THREE.UV( 1.0, 0.0 ),
    new THREE.UV( 0.0, 0.0 ),
    new THREE.UV( 0.0, 1.0 ),
    new THREE.UV( 1.0, 1.0 ),
  ];
  this.faceVertexUvs[ 0 ].push( uvs );

};

To ensure proper execution with the resulting geometry later on:

geometry.computeCentroids();
geometry.computeFaceNormals();
geometry.verticesNeedUpdate = true;
geometry.uvsNeedUpdate = true;
geometry.normalsNeedUpdate = true;
geometry.tangentsNeedUpdate = true;
geometry.elementsNeedUpdate = true;
geometry.dynamic = true;

Upon applying this texture:

The outcome obtained is:

How can we address the distortion between the red and green points? At the poles, one vertex is used twice which may not be ideal. Any suggestions on improving this?

Answer №1

This particular issue is quite complex. Despite our efforts, the texture mapping remains affine in nature.

It may be necessary to explore perspective correct texture mapping at some point. I vaguely remember reading about interpolating a w somewhere, but I am unsure if that would effectively address your specific problem.

To simplify matters, consider examining the quad in the texture mapping image under an affine transformation. Envision shifting the top left vertex to the top right position. This action essentially transforms the left triangle into a single line running from bottom left to top right, rendering it invisible. However, since the vertices of the right triangle remain unchanged, it remains visible with assigned UVs for each vertex.

The possible solutions that come to mind are:

  1. Introducing an additional level of tessellation for those polygons.
  2. Creating a custom pre-corrected texture (using tools like canvas or photoshop) for such scenarios.

Answer №2

There are a few key points to address.

First and foremost, there is no need to convert every face of your geometry to plane geometry unless it serves a specific purpose. The Fiddles below demonstrate how this can be managed effectively.

Secondly, the root of your issue lies in your UV settings.

For instance, consider this scenario: I have created a simpler geometry resembling yours where the quad faces appear as trapezoids. By following your method of setting UVs for each face at the texture corners (0,1), (0,0), (1,0), and (1,1), an outcome of a distorted circle ensues. You can view this example in the following Fiddle: http://jsfiddle.net/PBjEE/.

To rectify this distortion, take a look at another Fiddle illustrating improvements made by adjusting the UV coordinates: http://jsfiddle.net/PBjEE/1/.

It is crucial that the UV coordinates accurately reflect a trapezoid similar to the face's proportions to ensure optimal results.

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

Having trouble sending data to an API through jQuery: the function is not functioning properly

Currently, I am in the process of developing an HTML form that allows users to input values into text fields and submit them to an external API called ThingSpeak. This API then uses the received values to generate a plot displayed within an iframe. Althoug ...

Transition effects applied to images with transparency using CSS

My collection includes three transparent PNG images: https://i.sstatic.net/80Jxj.png https://i.sstatic.net/Eewcq.png https://i.sstatic.net/VXk7A.png I have arranged them using the following HTML/CSS: <div style="position: relative; left: 0; top: 0; ...

Utilizing an Ajax call within "for" loops can result in skipping either odd or even iterations

Seeking assistance because we are facing a challenge that we cannot seem to overcome. Despite researching on platforms like StackOverflow and search engines, implementing a solution or solving the problem remains elusive. The goal is to develop a JavaScri ...

Injecting Vibrant Lines into Browser Using three.js

My current project involves drawing colored lines in a browser without using meshes. I am retrieving data from a MySQL database where geometry and other attributes are stored, and then converting this data into text blocks that create individual line objec ...

Tips on extracting and displaying data from a JSON response in JavaScript to HTML

Hello! I'm new to JavaScript and I have a question regarding AJAX requests. I've successfully received a JSON response and I want to dynamically append specific data from this response to HTML fields. Below is an example of the JSON response tha ...

Creating an interactive drop-down menu in HTML populated with data from an Excel or Access

I have just started my programming journey and am slowly getting the hang of it. I feel comfortable with HTML, CSS, and have a basic grasp of Javascript. Currently, I am working on creating a website to streamline our order processing system. The website ...

Cease the execution of the express function once a response has been sent

Recently delving into the world of .js and .ts, I've been exploring express.js. Take a look at the snippet below: private post = async ( request: express.Request, response: express.Response, next:express.NextFunction) => { await this.myfu ...

Creating an array of objects with string keys in JavaScript can be achieved by defining an array

In order to simulate a response from the server, I would like to use keys such as 1.0.0 instead of default indexes. This will result in something like the example below: https://i.sstatic.net/JUzjf.png I attempted using { 'versions': [ '1. ...

Which is the better option for opening a link in a button: using onclick or href?

What is the most effective way to open a link using a button? <button type="button" onclick="location='permalink.php'">Permalink</button> <button type="button" href="index.php">Permalink</button> ...

What is the best way to add new key value pairs to the dictionary?

I am attempting to distinguish between single clicks (assigned value 0) and double clicks (assigned value 1), while also keeping a log of the click and its position in a map. However, I have noticed that the keys are automatically sorted in ascending order ...

What steps can be taken to identify the two highest numbers in an array, one being positive and the other

Seeking the optimal solution to resolve this issue Issue: Develop a function called ArrayChallenge (Javascript) that takes a single argument "arr" representing an array of numbers. The function should return the string true if there exist two numbers in t ...

Initiating a NodeJS reboot using a PHP script directly within NodeJS

I'm facing an issue with updating a folder and redeploying its contents. My task involves using NodeJS and I've managed to get port 8080 up and running. My attempt at creating a php script (update.php) goes like this: <?php echo exec("git pu ...

Guide to sending various dates in the Check-in and Check-out sections on the website https://www.expedia.co.in/ using Python with Selenium

Currently developing a basic code to input and select arrival place, departure place, arrival date, and departure date on the Expedia website. Everything seems to be working fine except for the issue where the arrival date and departure date are displayin ...

Ordering in D3 Code

I'm struggling with understanding the correct structure for writing D3 code. For example: In the code snippet below, I noticed that if I place the 3rd section (Chart Title) of the code after creating the svg element, the title text doesn't displ ...

Utilize another function located within a JavaScript module

I'm encountering an issue while trying to reference the getJSONS function from another function within the script. The error message I'm seeing is (node:5857) UnhandledPromiseRejectionWarning: TypeError: this.getJSONS is not a function. How can ...

Hover over a DOM element to highlight it, similar to the functionality of the inspect tool

Our website features a bookmarklet that triggers an inspect-like highlighter when a user clicks a button. We are aiming for this functionality to be compatible across different browsers. To achieve this, we must be able to detect the DOM element during mo ...

When using Stripe checkout, the database IDs are altered, causing issues when trying to delete or update stock in the database using a webhook

I have been working on developing an ecommerce platform using NextJs, Sanity as the CMS, and Stripe as the payment gateway. However, I have encountered an issue during the checkout process. When creating the checkout session, Stripe seems to alter the prod ...

Step-by-step guide to aligning layout using material design in generator-gulp-angular

I am currently using generator-gulp-angular with angular-material-design and ui-router All views are loaded into index.html in the <div ui-view></div> element However, when I attempt to center the element with material design directives insid ...

Ways to transfer ID to a different HTML page

I have some Javascript code in a file named nextPage.js. When this code is executed by clicking on something, it should transfer the value of category_id to another page called reportlist.html. Can you please provide assistance with this? var base_url = " ...

Tips for utilizing Vue router query parameters while in hash mode:

Is there a more efficient way to access URL parameters in Vue methodology, without having to rely on window.location.href and parsing the URL? router/index.js const router = new Router({ mode: 'hash', routes: [] }); router.beforeEach((to, f ...