Implement the heightmap onto the SphereGeometry using three.js

[UPDATE: Refer to this jsfiddle for a live demo along with the relevant code]

I am using three.js to create visualizations of celestial bodies with distinct characteristics.

While there are no specific examples available on implementing spherical heightmaps with threejs, there is an example showing how to apply a heightmap to a plane.

I adapted this example by utilizing a SphereGeometry(); instead of a PlaneGeometry();

Given that the geometry of a sphere differs significantly from that of a plane, I encountered difficulty as the rendered sphere appeared as a flat texture.

The heightmap code for planes:

var plane = new THREE.PlaneGeometry( 2000, 2000, quality - 1, quality - 1 );
plane.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
for ( var i = 0, l = plane.vertices.length; i < l; i ++ ) {
    var x = i % quality, y = ~~ ( i / quality );
    plane.vertices[ i ].y = data[ ( x * step ) + ( y * step ) * 1024 ] * 2 - 128;
}

I believe the solution lies in altering the mapping within the for loop to calculate the surface coordinates of the sphere in 3D space rather than the 2D coordinates of a plane. However, my limited knowledge of 3D mathematics has left me stuck at this juncture.

An illustration applying the heightmap to a sphere alongside all related code can be found in this jsfiddle. An updated version is available in this revised jsfiddle, displaying an altered sphere with randomized data instead of actual height map information.

I am aware that it is possible to distort the 3D points of a sphere to generate surface details, but my goal is to achieve this using a heightmap. The current JSFiddle demonstrates my progress so far – it distorts points randomly to simulate a rocky texture on the sphere, albeit appearing unnatural.

UPDATE: Here is the targeted logic required to implement mapping heightmap data onto a sphere.

To map the data onto a sphere, we must convert coordinates from a basic spherical coordinate system (longitude φ, latitude θ, radius r) to Cartesian coordinates (x, y, z). Similar to traditional height-mapping where the value at (x, y) corresponds to z, here we map the value at (φ, θ) to r. This transformation involves:

x = r × cos φ × sin θ

y = r × sin φ × sin θ

z = r × cos θ

r = Rdefault + Rscale × d(φ, θ) 

The parameters Rdefault and Rscale can be adjusted to control the size of the sphere and the resulting height map applied to it.

Answer №1

Utilizing vector3 for manipulating each vertex:

  var vec = new THREE.Vector3()
  vec.set(geometry.vertices[i].x, geometry.vertices[i].y, geometry.vertices[i].z);
  vec.setLength(dist);
  geometry.vertices[i].x = vec.x;
  geometry.vertices[i].y = vec.y;
  geometry.vertices[i].z = vec.z;

Demo: http://jsfiddle.net/someuser/abc123/

Answer №2

To project a 2D map onto the surface of a 3D sphere, you must utilize the UVs associated with the sphere. Luckily, UVs are readily available with THREE.SphereGeometry.

However, since the UVs are stored per-face, you will have to cycle through the faces array.

Here's what you need to do for each face in the geometry:

  • Retrieve the corresponding UV value from the FaceVertexUvs array for every linked vertex.
  • Access the height map value at that UV coordinate.
  • Move the vertex along the normal direction by this value. The faces array provides the vertex index, allowing you to access the vertices array and modify the vertex position accordingly.

Once these steps are completed, remember to set verticesNeedUpdate to true for the vertices to be updated.

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

Running into memory issues while constructing the heap

After attempting to build and deploy our React application, I encountered the following error: FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory While I initially thought this was solely a JavaScript issue, I am uncert ...

Using Vue.js: Invoking a Function from a Different Component

Here is the HTML snippet from Component1 <component2></component2> This is the <script> block from Component1 export default { methods: { fetchData() { ... } } } Now, I want to call the method fetchData() in Compon ...

Is it possible to extract information from a string with regular expressions?

As I sift through a myriad of arbitrary "Header" data in node. Here's an example of what it looks like: _Aa:GA1.1.78037747.867108, 44907=5xyz; Webstorm-a36041d5=9fbb-48e9-b19e-e3f0a3282151; srce=coolernode; nsid=1234; cookie_data=T%3D1; _gat_PP= ...

What is the best way to utilize multiple models under a single root in ReactJS?

Greetings! I currently have a root structure in the following code snippet: <body> <noscript>You need to enable JavaScript to run this app.</noscript> <button >Platform</button> <button >Game</button> < ...

Easy method for generating a JavaScript dictionary using an array containing arrays

I have a collection of paired items, and I am looking to convert it into a dictionary. const collection = [['apple', 3], ['banana', 5]] const transformed = {'apple': 3, 'banana': 5} If I were using Python, I could ...

Looking for guidance on where to find a functional code sample or comprehensive tutorial on working with ViewMetadata in Angular2

I am currently trying to understand the relationship between viewmetadata and the fundamental use of encapsulation: ViewEncapsulation, including ViewEncapsulation.Emulated and ViewEncapsulation.None. Here is a link for further information: https://angula ...

What steps are involved in bundling a Node project into a single file?

Recently, I've been using npm to create projects. When it comes to AMD, I find the native node require to be very convenient and effective for my needs. Currently, I rely on grunt-watchify to run my projects by specifying an entry file and an output f ...

Integrate properties into a React component using an object as the representation

Can props be added to a component represented by an object? I am looking to add these props just once, within the map function, if possible. children: [ { id: '1', isActive: false, label: 'Home', component: & ...

What is the best way to retrieve the values from the labels for two separate buttons?

I designed a pair of buttons with a single label below. Both buttons acted as standalone entities. <label for="buttons" class ="val">0</label> <input class="btn btn-primary button1" type="button" ...

The HTML5 range input is consistently defaulting to the minimum value and is not triggering the onChange event for text input

My goal is to implement a feature where an input type text is used along with an input type range with three specific use cases: 1. Default case: When the page loads, the slider should point to the value specified in the text input field. 2. When a user e ...

What is up with this strange JavaScript variable string / DOM selection?

I'm facing a strange issue with a variable that appears to be a string when alerted, but in the console, it is actually a DOMSelection presented in tree form. How can I retrieve the actual string value from this console output? DOMSelection anchorNod ...

Avoiding bootstrap modal from disappearing upon validation failure when submit button is pressed using PHP

Could somebody please help me figure out how to prevent a modal from closing when the user clicks the sign-up button under two different scenarios: If the input fields contain invalid data, I want to display a PHP error message If the inputs are valid, I ...

My Vue frontend project is encountering an error during compilation that states "this relative module module was not found."

I have created a vue frontend to interact with my spring backend, which is working well. However, when I compile the frontend, it compiles to 98% and shows an error message: ERROR Failed to compile with 1 error 11:24:51 The relative module was not foun ...

Alerting Users Before Navigating Away from an Angular Page

I am looking to implement a feature in my app that will display a warning message when attempting to close the tab, exit the page, or reload it. However, I am facing an issue where the warning message is displayed but the page still exits before I can resp ...

Tips for utilizing JSON in a TypeScript file within a Node.js environment

I have been working on implementing JSON type in my Node.js application, but I am encountering some data in a scripted format. Here is the response: }, data: '\x1F\b\x00\x00\x00\x00\x00\x00\x00]PMo0\f ...

Having trouble accessing Kotlin JS from JavaScript

I'm currently experiencing an issue where I am unable to call any Kotlin JS function and receiving an error stating that 'something' is not defined. Initially, I attempted compiling the project with Gradle but found success after following ...

Utilize the .not() filter function in JavaScript

I am trying to apply a filter of not(.pseudo-element) using JavaScript, but I am unsure how to add it. So far, I have been able to extract #app from the DOM with the following code: const app = document.getElementById('app') app.style.filter ...

Generating requests using ExpressJS

Is it possible to send a POST request using a GET action? Although everything seems to be working fine, the "TOKEN" does not appear after the post. I am puzzled as to why this is happening. const request = require('request'); exports.g ...

How do you manage dependencies for nested components within Angular2?

Encountering an Issue: browser_adapter.js:76 Error: Cannot resolve all parameters for NestedComponent(undefined). Make sure they all have valid type or annotations. at NoAnnotationError.BaseException [as constructor] Diving Deeper Into the Problem: ...

What is the best way to implement Bootstrap 5 jQuery plugins in an ES6 project with Webpack?

Currently in the process of transitioning an ES6 project from Bootstrap 4 to Bootstrap 5, encountering the following error: Error: Uncaught TypeError: bootstrapElement.Tooltip is not a function According to the Migration Notes, Bootstrap 5 no longer inc ...