Adapting the Three.js displacement map shader to incorporate all RGB values instead of solely relying on the red

My goal is to enhance the precision of the displacement map by using an rgba texture to display displacement values with 32 bits accuracy instead of the default 8 bits in three.js. I am working on visualizing a flooding scenario and need to observe minute differences in terrain height.

After making adjustments to the displacement map shader function in the Three.js package, particularly in the file_three.js-master\src\renderers\shaders\ShaderChunk\displacementmap_vertex.glsl, I modified the code as follows:

transformed += normalize( objectNormal ) * ((texture2D( displacementMap, uv ).r*256.0*256.0*256.0)+(texture2D( displacementMap, uv ).g*256.0*256.0)+(texture2D( displacementMap, uv ).b*256.0)+(texture2D( displacementMap, uv ).a)) * displacementScale + displacementBias;

However, the result appears distorted when compared to the 8-bit displacement map. The 8-bit version shows smooth transitions, while the 32-bit map creates unexpected bumps and holes. It seems like some information from the 32-bit height data has been lost or altered. How can I encode displacement across all four channels rather than just red?

The input textures for my displacement map are:

1. PNG with height encoded in the red channel: https://i.sstatic.net/cP2Ff.png

2. PNG with height encoded in all four channels: https://i.sstatic.net/fwPNN.png

The segment of code where I create the mesh with a displacement map looks like this:

displacementMap0 = textureLoader.load(list_depth_images[0], function(mt0) {
    displacementMap0.wrapS = displacementMap0.wrapT = THREE.ClampToEdgeWrapping;    
    addPlanes();
});

function addPlanes() {
    // MeshPhongMaterial properties
    material = new THREE.MeshPhongMaterial({
        color: 0x88ffaa,
        normalMap: normalMap,
        normalScale: new THREE.Vector2(1, 1),
        aoMap: aoMap,
        aoMapIntensity: 0.5,
        specularMap: specularMap,
        specular: 0x222222,
        displacementMap: displacementMap0,
        displacementScale: ((settings.displacementScale) * overall_scale) / (256.0*256.0*256.0),
        displacementBias: 0.0,
        side: THREE.DoubleSide 
    });
    var planeGeo = new THREE.PlaneBufferGeometry(2000*2*overall_scale, 2000*2*overall_scale, 1000, 1000);
    THREE.BufferGeometryUtils.computeTangents(planeGeo);
    plane = new THREE.Mesh(planeGeo, material);
    plane.rotation.x = -Math.PI / 2;
    plane.position.y = -400.0 * overall_scale;
    scene.add(plane);
}

I have provided a downloadable zip file containing a functioning example of both the 8-bit and faulty 32-bit displacement maps: downloadable .zip

Answer №1

After some troubleshooting, I discovered that my textures were inverted (ABGR instead of RGBA)! By rewriting the shader and utilizing the packing shader in Three.js, everything now works as intended. Here is a snippet of the new shader code:

const float UnpackDownscale = 255. / 256.;
const vec4 UnpackFactors = UnpackDownscale / vec4(256. * 256. * 256., 256. * 256.,  256. ,1.);
transformed += normalize( objectNormal ) * (dot(texture2D( displacementMap, uv ).rgba,UnpackFactors) * displacementScale + displacementBias );

The end result is much smoother now. Take a look at it here: https://i.sstatic.net/GdQ2Z.png

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

Dramatist: What are effective methods for distinguishing and monitoring frames within a webpage?

When it comes to storing my own copy of frames, I want to utilize the page.on("frameattached") and page.on("framedetached") events to properly manage the lifecycle of the frames. My main concern is how I can uniquely identify them across these events. I ...

Passing JSON information from a website to a Node.js server

<script type="text/javascript" src="data.json"></script> var mydata = JSON.parse(data); data = '[{"yer" : "Besiktas", "lat" : "41.044161", "lng" : "29.001056"},{"yer" : "Eminönü", "lat" : "41.017513", "lng" : "28.970939"},{"yer" : "Zeyt ...

I continue to encounter an error every time I attempt to place an HTML nested div on a separate line

When I structure the HTML like this, I don't encounter any errors: <div class="game-card"><div class="flipped"></div></div> However, if I format it differently, I receive an error message saying - Cannot set property 'vi ...

What is the best way to retrieve the current value of a range slider?

Having some trouble with the "angular-ranger" directive that I loaded from a repository. Can anyone assist me in figuring out how to retrieve the current value of the range slider? Any guidance or suggestions would be greatly appreciated! For reference, ...

Verify the presence of an email in MongoDB in real-time as it is being

This particular project utilizes js, mongoose, and node.js. If an email that is already in use is attempted during registration to create an account, the page will reload, all fields will be cleared, and a pop-up message using AJAX will notify the user tha ...

What is the best way to send a prop from a parent component to its child using context in React?

Currently, I am working on fetching data in a React application. My goal is to extract an individual value from the response and pass it as a prop in a context from a parent component. The `trendingData` variable holds information retrieved from an API cal ...

Child element casting shadow over parent element

I am currently using box shadow for both the parent (.map) and child (.toggle-button): .map { position: fixed; top: 20px; right: 0; width: 280px; height: 280px; z-index: 9999; box-shadow: 0px 1px 6px 0px rgba(0,0,0,0.3); } .map ...

PHP and JS with Jquery often face challenges when trying to work together due to their conflicting array structures

This is a perplexing issue that has me stumped. I retrieved an array of workers from a MySQL database using json_encode and then copied it to two other arrays for future operations. var workers = <?php echo json_encode($tablica_pracownikow); ?>; va ...

Serving Files in Express JS: the benefits of serving files directly from memory compared to serving static

Should I keep images and other assets in memory or serve them from static assets? Will often-requested static assets be stored in memory? Does anyone have insight into the performance implications of this decision? ...

Is it possible to close the navigation menu by clicking on a link or outside of the navigation area?

Hey everyone, I've recently dived into the world of web design and encountered my first hurdle. I need your expertise to help me solve this problem. How can I modify my JavaScript to close the NAV element by clicking on one of the links or outside t ...

What is the best way to utilize TypeScript module augmentation with material-ui components?

I have gone through the answers provided in this source and also here in this link, but it appears that they are outdated. I attempted to enhance the type definition for the button component in various ways, including a separate typings file (.d.ts) as we ...

Leveraging the power of HTML5 alongside Angularjs and Node/Express within the MEAN.js boilerplate framework

I've decided to kickstart my app using the mean.js () boilerplate because of its built-in authentication/authorization features. However, I've hit a roadblock when it comes to incorporating HTML5 into my project. In my Angular app, I've en ...

Using jQuery to target a specific item from a retrieved list of elements

I'm currently working on a photo gallery feature that is reminiscent of Instagram or Facebook user photos. My goal is to enable users to view details about each image (such as the date) in a box that appears over the image when they hover over it. E ...

Encountered an error when attempting to use 'appendChild' on 'Node': the first parameter is not the correct type. It was able to work with some elements, but not with others

I'm currently working on a script that utilizes fetch to retrieve an external HTML file. The goal is to perform some operations to create two HTMLCollections and then iterate over them to display a div containing one element from each collection. Here ...

Troubleshooting Issue with Angular Property Binding for Image Dimensions

Currently, I am exploring property binding in Angular through an example. The idea is to use an image and bind its width, height, and src attributes using property binding. Surprisingly, even though there are no errors and the image renders successfully vi ...

When a div tag containing PHP is empty, it should either be hidden or show specific text based on your requirements

Among the plethora of unanswered queries regarding hiding empty divs, I find myself unable to make any of the suggested solutions work. Hence, I am putting forth my own question. On my webpage, there is a specific section dedicated to showcasing various it ...

The PopupControlExtender in ajaxToolkit seems to be malfunctioning when used with a textbox that has Tinymce

I recently built a website using ASP.NET, and I have a feature where a small tooltip appears on the right side of a text box when the user focuses on it. To achieve this, I am using the ajaxToolkit:PopupControlExtender in my code. <asp:TextBox ...

Performing an action once all AJAX requests have finished

I'm dealing with a situation where I have a click event triggering 3 ajax calls: $("#button").click(function(e) { e.preventDefault(); $.ajax(call1); $.ajax(call2); $.ajax(call3); some_function() //needs to be executed only afte ...

Optimizing Backend Access with Laravel and Vue JS: How to Choose the Most Effective Approach

Currently, I am utilizing Laravel API passport to handle authentication in my Single Page Application (SPA) built with Vue. At the moment, whenever I need to access the backend server, I have to include a header in order to be allowed through the protected ...

Having trouble transferring ASP server control value to a Javascript function

Currently working with ASP.NET 2.0. My Entry Form contains various ASP.NET Server Controls, such as TextBoxes. I want to pass the value of a TextBox on the onBlur event. Here is an example of a TextBox code: <asp:TextBox ID="txtTotalTw" Width="80px" r ...