Obtain a transformed mesh that has been displaced using a displacementMap within three.js

Seeking to extract and export the mesh affected by a displacementMap.

The displacement of vertexes is determined by this line in the shader (taken from three.js/src/renderers/shaders/ShaderChunk/displacementmap_vertex.glsl):

transformed += normalize(objectNormal) * (texture2D(displacementMap, uv).x * displacementScale + displacementBias);

This process displaces a vertex based on the displacementMap, in conjunction with the uv coordinates for that vertex.

I am aiming to generate this mesh/geometry in order to export it at a later time.

For a closer look at the issue, a "demo" has been created here: Github Page Upon clicking 'exportSTL', I would like to obtain the displaced mesh seen in the viewport; however, I am only receiving the undisplaced plane.

I am aware that this occurs because the displacement solely occurs in the shader and does not directly displace the geometry of the plane.

I have yet to come across a method provided by three.js that allows for capturing the shader's changes. Therefore, I am attempting to address this using a function in my "demo.js" file. However, being new to WebGL/three.js, I am encountering difficulties in replicating the shader's actions.

I have encountered exporters that handle morphTargets, but these are not aiding in this situation. After reviewing this question, I experimented with PlaneBufferGeometry, as it closely resembles the shader - yet, this yielded the same outcomes for me. I believe this question was attempting something similar, yet settled on a different approach.

In the end, my goal is to draw on an HTML-canvas that dynamically updates the texture (which is currently functional). Then, users can export the mesh for 3D printing.

Is there a way for three.js to provide me with the modified geometry from the shader? Alternatively, could someone assist in converting the shader line into a more conventional three.js function? Perhaps my current method of obtaining a displaced mesh is completely misguided?

Update - Example is working

Thanks to DeeFisher's example, I am now able to compute the displacement on the CPU, as originally suggested by imerso. Upon visiting the Github Page now, you will find a functional demonstration. I am still attempting to grasp why I must mirror the canvas to achieve the correct displacement in the end, but this is, at worst, a minor inconvenience.

Answer №1

If you want to achieve that while still implementing a shader for the displacement effect, you'll have to make the switch to WebGL2 and utilize Transform-Feedback. A quick search on Google for 'WebGL2 Transform-Feedback' will provide you with more information.

Another option would be to retrieve the texture data back to the CPU and analyze it while adjusting the vertices using CPU operations only. You can find more details on this by searching 'WebGL readPixels' on Google.

Both approaches will require some dedicated effort, so I won't be providing any code snippets at this moment. =)

Answer №2

BABYLON.js has the capability to work alongside THREE.js, allowing you to manipulate mesh vertices with displacement maps:

var sphere = BABYLON.Mesh.CreateSphere("Sphere", 64, 10, scene, true);
sphere.applyDisplacementMap(url, minHeight, maxHeight, onSuccess, uvOffset, uvScale)

Check out an example of this function in action here.

Afterwards, you can use a for loop to transfer the BABYLON mesh data into a THREE mesh object.

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

Troubleshooting Angular: Unidentified property 'clear' error in testing

I've implemented a component as shown below: <select #tabSelect (change)="tabLoad($event.target.value)" class="mr-2"> <option value="tab1">First tab</option> <op ...

The number range filter in ng-table is malfunctioning

what I am trying to accomplish My goal is to create a column that can accommodate two numbers in order to filter numeric data within a specific range for that column. While sorting, pagination, and filtering by 'contain text' are working correct ...

Sorting through a JavaScript array

I am facing a peculiar problem while trying to filter an array in TypeScript. Here is the structure of my object: Sigma.model.ts export class Sigma { sigmaId: number; name: string; userId: number; starId: string; } `` The starId property contains com ...

Enhance your Angularfire experience with $firebaseArray by enabling dynamic counting and summing

Is there a way to dynamically count certain nodes if they are defined? The current implementation requires explicitly calling sum(). app.factory("ArrayWithSum", function($firebaseArray) { return $firebaseArray.$extend({ sum: function() { var ...

Ways to showcase the content of a page once the controller variables have been set

As someone who is just starting out with AngularJS and web development, I am curious to know if there is a way to delay the display of a page until after all of the controller's $scope variables have been initialized. Most of my $scope variables are c ...

Passing data as a parameter from the view to the controller using AngularJS

I am attempting to retrieve data from a view, which must be passed as a parameter in a function in order to populate an array in the controller. However, I am not receiving any objects in return. Here is what I have tried: VIEW <div ng-repeat="cssfram ...

Encountering difficulties in JavaScript while trying to instantiate Vue Router

After following the guide, I reached the point where creating a Vue instance was necessary (which seemed to work). However, it also required providing a Vue Router instance into the Vue constructor, as shown below. const router = new VueRouter({ routes }) ...

React Application not reflecting recent modifications made to class

My current project involves creating a transparent navigation bar that changes its background and text color as the user scrolls. Utilizing TailwindCSS for styling in my React application, I have successfully implemented the functionality. // src/componen ...

Error encountered in Vue3: An uncaught TypeError occurred when attempting to "set" a property called 'NewTodo' on a proxy object, as the trap function returned a falsish

I encountered an error message: Uncaught TypeError: 'set' on proxy: trap returned falsish for property 'NewTodo' This error occurs when attempting to reset the input text value within a child component (FormAddTodo.vue). App.vue: expo ...

Running a Node.js worker on an Amazon ECS-hosted server: A step-by-step guide

Our team is currently running a node server on Amazon ECS that receives up to 100 hits per second. Due to the single-threaded nature of JavaScript, we are hesitant to block the event loop. As a solution, we are looking to implement a worker that can peri ...

Obtain all the selection choices in a dropdown list using Selenium

Although I have come across similar questions, this one is distinct in its simplicity. Unlike other queries that involve iterating over options in a loop, my question revolves around the usage of the getOptions() method mentioned in Selenium documentation. ...

Issue encountered when running a minification build on Angular 5

After successfully updating my Single Page Application (SPA) from Angular 4 to Angular 5 along with all dependencies, everything seemed to be working well. Both the development and production builds were functioning without any errors or warnings. However ...

Is it possible to increment an integer value in jQuery after obtaining the sum result?

Actually, I'm trying to extract the integer value from my input field. For example, if I enter the value 4+5, I want to display the result as 9 in a separate div. However, instead of getting the expected result, I am receiving [object Object]. I&apo ...

Implementing Jquery after async ajax refresh in an asp.net application

My ASP.net page is heavily reliant on jQuery. Within this page, I have a GridView placed inside an UpdatePanel to allow for asynchronous updates. <asp:GridView ID="gvMail" runat="server" GridLines="None" AutoGenerateColumns="false" ...

Leveraging AngularJS for parent-child communication through bindings in a unique and effective manner

I've come across the following code snippet: <div class="parent"> <div class="child"> and I have two directives, one for parent and one for child. When an event (such as a click) occurs on parent, I want something to happen on child ...

Struggling to retrieve information from a JSON file and display it within a component?

After accessing the JSON data and storing the necessary values in a dictionary named details, I am encountering an issue where the values are displayed when console logged from inside the function but appear as undefined when console logged in the parent f ...

Strange interaction observed when working with Record<string, unknown> compared to Record<string, any>

Recently, I came across this interesting function: function fn(param: Record<string, unknown>) { //... } x({ hello: "world" }); // Everything runs smoothly x(["hi"]); // Error -> Index signature for type 'string' i ...

What is the method for verifying a password in the login process when it has been hashed by bcrypt during registration?

Currently in the process of developing a signup and login page using Node.js with Pug, Mongoose, and bcrypt. I am encrypting and storing passwords in the database after registration or sign up. I'm facing an issue with the comparison function as it r ...

The functionality of Vue slot-scope seems to be restricted when used within nested child components

Here is the component configuration being discussed: Vue.component('myComponent', { data () { return { msg: 'Hello', } }, template: ` <div class="my-component"> <slot :ms ...

Is there a way to retrieve the Angular-Redux store in a child module?

Within my Angular application, I utilize angular-redux for managing the application state. In my main module, I have defined the redux store in the following manner: export class MainModule { constructor(private ngRedux: NgRedux<MainAppState>, ...