Mapping UVs for partial spheres in Three.JS

In a previous inquiry regarding the mapping of a stereographic projection onto a sphere for virtual reality live-streaming purposes, I delved into UV mapping techniques and successfully achieved a visually stunning result. However, there is one aspect of this mapping method that I find unsatisfactory: a workaround where the bottom of the sphere must map to "nothing," leading me to assign it to a corner of the texture.

In an attempt to refine this approach, I experimented with creating a partial sphere by adjusting the theta length as suggested in the Three.JS documentation on SphereGeometry.

Although I managed to attain the correct spherical shape, I encountered an intriguing observation concerning the UV mapping:

// JavaScript code snippet
var fov = 270;
// Sphere geometry creation
...
console.log("minX: " + minX + ", maxX: " + maxX);
console.log("minY: " + minY + ", maxY: " + maxY);
console.log("minZ: " + minZ + ", maxZ: " + maxZ);

My past experience with UV mapping highlighted the range of x, y, and z values from -1 to 1, independent of mesh size. An x value of 1 signifies "far right on the sphere," while a y value of 1 indicates "top of the sphere." However, when manipulating a partial sphere (via thetaStart and thetaLength) such that a hole is created at the top, the maxY value unexpectedly capped at approximately 0.7854.

Why does this mesh conclude at 0.7854 instead of following a scaled range from -1 to 1? My aim was to streamline the UV mapping process by adjusting the sphere's shape (eliminating the need for the scaledY term mentioned in my prior question) but altering the sphere's configuration seemed to have negligible impact on the UV map.

Is there a way to inform Three.JS that this partial sphere represents the full extent of the shape, guiding its coordinates to span from -1 to 1?

Answer №1

It seems there may be some confusion between Normals and UVs in the explanation and code snippet provided. The code appears to be referencing Normals, as shown below:

    var x = face.vertexNormals[j].x;
    var y = face.vertexNormals[j].y;
    var z = face.vertexNormals[j].z;

When looking at the attributes of SphereGeometry, the min and max y normals seem to align with the expected values: https://i.sstatic.net/2ESbJ.jpg

To retrieve the correct information, focus on the min and max UV values. Here is an updated code snippet that retrieves UV values:

var fov = 270;
var geometry:THREE.SphereGeometry = new THREE.SphereGeometry(
    2, // Radius
    50, // Horizontal segments
    50, // Vertical segments
    0, // Phi start
    2 * Math.PI, // Phi length
    Math.acos((360 - fov) * Math.PI / 180 / 2), // Theta start
    Math.PI - Math.acos((360 - fov) * Math.PI / 180 / 2) // Theta length
);
var minX, minY, minZ, maxX, maxY, maxZ;
var faceVertexUvs = geometry.faceVertexUvs[0];

for ( var i = 0; i < faceVertexUvs.length; i++ ) {
    var vertUV = faceVertexUvs[i];
    for ( var j = 0; j < 3; j ++ ) {
        var x = vertUV[j].x;
        var y = vertUV[j].y;

        // Capture the upper and lower bounds for all points
        if (!minX || x < minX) minX = x;
        if (!maxX || x > maxX) maxX = x;
        if (!minY || y < minY) minY = y;
        if (!maxY || y > maxX) maxY = y;
    }
}
console.log("minX: " + minX + ", maxX: " + maxX);
console.log("minY: " + minY + ", maxY: " + maxY);

Upon running this code, you will notice that the range always falls within [0, 1], rather than [-1, 1]. It's worth noting that UVs only include X and Y values, without a Z component, since they are used to map a 2-dimensional image.

Normals:

  • x: (-1, 1)
  • y: (-1, 1)
  • z: (-1, 1)

UVs:

  • x: [0, 1]
  • y: [0, 1]

You can refer to how ThreeJS constructs sphere UVs in this specific section of the code, particularly around lines 90, 94, and 111.

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

Echo input and refresh on the current page upon submission

I am facing an issue with refreshing the page after submitting a form. I want to refresh the page so that the login attempt can be counted, but currently, the form is displayed without the page being refreshed to add to the count. This is my current code s ...

Rearranging the img element within the dom structure to optimize display in various blog posts

Hey there, I have a specific task that I need help with: Currently, I am using Business Catalyst as my framework. They have a blog module that does not offer much customization when it comes to blog lists. There is a preview tag that displays a preview of ...

Navigating with Angular - sending users to an external webpage?

When working with AngularJS routes, there is the option to use an otherwise route as a replacement for a 404 error: $routeProvider .when(...) .otherwise({ redirectTo: 'my/path' }); Is it possible to configure the otherwise route to redirect ...

Loading necessary CSS when needed in React JS

I am currently in the process of converting a bootstrap template to react framework. My question is, is there a way for me to load stylesheets on demand? For instance, if I have 2 components and I import the same stylesheet separately in both components, ...

Manipulate HTML Table to Obtain Value of First Column Cell When Another Cell is Clicked using Javascript

I have a PHP web application where I am retrieving data from MySql and displaying it in the HTML table below. <table id = "table" width="500px" cellpadding=2 celspacing=5 border=2 > <tr> <th>Subject Code</th> <th>Subje ...

Dealing with Vue's performance problems when using input type color and v-model

I am encountering a problem with setting the v-model on an input of type color. Whenever I change the color, there is a noticeable drop in frame rate and the application's FPS spikes from 60 to 3. You can see it reflected in the Vue performance graph ...

Unlocking the Power of Typescript and ReactJS: Maximizing Efficiency with Previous State

I'm encountering difficulties implementing the previous state in React 18 with Typescript version 4.8.3. Here is my refreshToken code and I'm receiving the following error: Value of type '(prev: any) => any' has no properties in c ...

Issue encountered when trying to insert an array in JavaScript into MongoDB using Mongoose

I am currently learning about node.js and mongodb. I attempted to insert a JavaScript array variable into mongodb using mongoose, but encountered an error. Upon running this code, I received the following error message: ValidationError: CastError: Cast t ...

Change the color of the navbar when scrolling using bootstrap and jquery

Using Bootstrap to design a navigation bar, I have two main goals: I want the navbar to change color when the page is scrolled down by 20%, and then revert back to its original color when scrolling back to the top. When the collapse featu ...

The ctx.drawImage function is drawing only half of the image

I am attempting to upload an image and then display it on a canvas, but at the moment I can only get half of the image to render: let picture = new Image(); picture.crossOrigin = 'Anonymous'; picture.onload = function() { let canvas = docume ...

Managing an undetermined quantity of elements from a form in PHP

Currently developing an inventory page for my job. I've crafted a page that will iterate through my database and showcase all the items stored within. include 'auth.php'; //authentication required for login change $sql="SELECT * FROM `inven ...

Is the `document.documentElement` consistently defined and always representing the HTML element?

I am looking to make changes to the <html> element using a script within the <head> section of an HTML page. My goal is to only access and modify the <html> element itself, without affecting any of its children. Should I wait for the DOM ...

Decoding the build ID in NextJS: A step-by-step guide

When working with NextJS, there's the option to generate a build ID as mentioned in the documentation here: https://nextjs.org/docs/app/api-reference/next-config-js/generateBuildId Alternatively, it is also possible to retrieve the build ID based on ...

Differences Between Using Array.push() and Literal (Bracket) Notation in JavaScript

I am looking at this specific answer. What is the reason behind Code Snippet 2 not producing the same result as Code Snippet 1? Code Snippet 1: var firstEvents = events.reduce(function(ar, e) { var id = e.getId(); if (e.isRecurringEvent() && ...

Steps for sending an image to Cloudinary using the fetch API

Struggling to figure out how to successfully upload a file to Cloudinary using fetch on my front-end. After consulting the documentation and various StackOverflow threads, I'm still facing a frustrating 400 error: export async function uploadImageToCl ...

JavaScript: Organizing values based on their case sensitivity

Imagine a scenario where we have models ABC23x, ABC23X & abc23X all referring to the same model. These model names are retrieved from API endpoints. Now the UI has two tasks: Display only one model name (ABC23X) When calling the REST API, we need to sen ...

Tips for creating a JSON object list

I'm currently working with asp.net mvc2 and attempting to send a list of JSON objects with predefined values from the home controller, then receive them in the index page.... the code snippet below shows how I am sending a single JSON object .... but ...

Tips for properly utilizing the setState method to update an object property within an array in a class component

In my current project, I have an array of objects stored in the state. Here is an example of the structure: const arrayOfTests = [ { id: 1, name: "test1", description: "test description"    }, {     ...

Having trouble getting Vue to properly focus on an input field

I am attempting to use this.$refs.cInput.focus() (cInput being a ref) but it seems to not be functioning as expected. I expect that when I press the 'g' key, the input field should appear and the cursor should immediately focus on it, allowing me ...

Looking for assistance with aligning the content of an input label using Bootstrap?

Is there a way to adjust the label content if it is larger than the input box size? My goal is to keep all input boxes on the same line while allowing labels to wrap accordingly. https://i.sstatic.net/NrLck.png I'm trying to achieve the alignment sh ...