Utilizing an animated GIF for displacement mapping in THREE.js - exploring the power of shaders

Recently, I came across this interesting example at , which uses an animated gif as a displacement map. However, the code provided in the example was based on THREE.js r58, while I am currently working on THREE.js r85 and facing some issues with compatibility.

dispTexture = new THREE.Texture(llamacanvas);

var shader = THREE.ShaderLib[ "normalmap" ];
uniforms = THREE.UniformsUtils.clone( shader.uniforms );

uniforms[ "enableDisplacement" ] = { type: 'i', value: 1 };
uniforms[ "tDisplacement" ] = { type: 't', value: dispTexture };
uniforms[ "uDisplacementScale" ] = { type: 'f', value: 35 };

uniforms[ "enableDiffuse" ] = { type: 'i', value: 1 };
uniforms[ "tDiffuse" ].value = dispTexture;

uniforms[ "tNormal" ] = { type: 't', value: new 
THREE.ImageUtils.loadTexture( 'flat.png' )};

In my attempt to resolve the issue, I encountered an error message when using

var shader = THREE.ShaderLib[ "normalmap" ];
:

Uncaught TypeError: Cannot read property 'uniforms' of undefined

To address this, I replaced normalmap with normal. Although this fixed the previous error, the line

uniforms["tDiffuse"].value = dispTexture
now throws:

Uncaught TypeError: Cannot set property 'value' of undefined

This discrepancy became evident due to significant changes between different versions of THREE.js. I'm seeking guidance on how to adapt this implementation to newer versions of THREE.js

A crucial aspect is related to geometry.computeTangents();, which existed in r58 but has been removed.

Thank you for any assistance!

Update: I made further modifications by replacing tDiffuse with diffuse. Subsequently, I began encountering an error message every time the animation loop updated:

Uncaught TypeError: Cannot set property 'value' of undefined

The error leads me to a section within three.min.js rather than the actual example code being used:

 // Code excerpt from three.min.js causing the issue...
      if (c.lights && (l.ambientLightColor.value = da.ambient,
 

Where it seems to have trouble with da.ambient. Any suggestions on how to proceed would be greatly appreciated.

Answer №1

Surprisingly straightforward compared to my expectations.

In this version, there's no requirement to manually configure the uniforms in r85. All I had to do was import the gif, create the material, and then utilize the gifCanvas as a displacementMap:

var newGif = new SuperGif({ gif: document.getElementById('gif1') } );
newGif.load();
var gifCanvas = newGif.get_canvas();

                          .      .      .

material = new THREE.MeshStandardMaterial();
material.map = new THREE.Texture( gifCanvas );
material.displacementMap = material.map;

Then within the animate() function:

material.displacementScale = 200;
material.map.needsUpdate = true;
material.displacementMap.needsUpdate = true;

I spent some time exploring CanvasTexture and ShaderMaterial, but they weren't needed for this task.

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

An easy way to pass props to a component using useNavigate in React Router

Is it possible to send props directly to a component in React? const goToProjectPage = useNavigate(); useEffect(()=>{ ..... goToProjectPage("/projectpage"); //send props here },[]); ...

What could be causing req.files to be empty in Multer for Node.js?

It seems that there is an issue with multer not receiving a value from the form: //Set Storage Engine var storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/uploads') }, filename: function (req, file, cb ...

Tips for preventing NextJS from including a dynamically imported component in the main _app.js bundle while utilizing Module Aliases

Currently, I am in the process of transforming some shared-ui components into dynamically imported ones within NextJS 11. I have set up module aliases using @nx/next:library, for example @my-site/shared-ui, all exported from an index.ts file as shown belo ...

Modifying the HTML <select> element with JavaScript

[resolved] I'm encountering an issue with the code below that is supposed to dynamically change the options in a second drop-down menu based on the selection made in the first menu. I've tried to troubleshoot the problem but haven't been suc ...

What is the best way to dismiss the additional modal popup?

Here is an example that I need help with: http://jsfiddle.net/zidski/Mz9QU/1/ When clicking on Link2 followed by Link1, I would like the Link2 box to close automatically. Is there anyone who can assist me with this issue? ...

Tips for resolving the final item issue in Owl Carousel when using right-to-left (RTL)

Encountering a bug with the rtl setting in owl-carousel. When the rtl is applied to the slider and I reach the last item, the entire slider disappears! Here's the code snippet: var viewportWidth = $("body").innerWidth(); if (viewportWidth & ...

Encountering Angular Material UI issues following the transition from version 11 to 12

I am currently in the process of updating my Angular application from version 11 to 12, integrating Angular Material, and encountering some error messages: Error No.1 - Error NG8002: Cannot bind to 'ngModel' as it is not a recognized property of ...

Tips on retrieving all visible objects in the camera view using Three.js

Is there a way to implement lazy loading of textures for meshes, loading only the ones that are within camera view without relying on an excessive number of vectors in Raycaster? ...

Using the Ternary Operator in JavaScript to Dynamically Update HTML Elements with Angular

Is there a way to convert the code below into a ternary operator so that it can be used in an .HTML file? statusChange && statusChange === 'Employed' ? true : employmentStatus === 'Employed'; To clarify, I want to assign the re ...

In what scenarios is it most beneficial to utilize an isolate scope in Angular?

The AngularJS guide states that the isolate scope of a directive isolates everything except models explicitly added to the scope: {} hash object. This is useful for building reusable components because it prevents unintended changes to your model state, al ...

Adding initial data to MongoDB in ExpressJS: What's the best way to include fixture data upon startup?

I've set up my expressjs server and mongoDB (using the mongoDB native driver and not mongoose). I want to check for existing documents in the database and add some fixture documents when the server starts, but I'm unsure where to do that. Someth ...

Ways to trigger Bootstrap modal through a PHP GET call

I have been searching for a solution to create a modal similar to this one, but I haven't found anything yet. My requirement is that when we pass true in a GET request, the modal should be displayed. Otherwise, if there is no value specified in the $ ...

The jQuery mobile button may occasionally appear selected without triggering a page transition

When using a Phonegap Application with jQuery mobile, I have encountered an issue where clicking a button sometimes only selects it and does not transition to the next page. This even happens with the back buttons generated automatically by the library, re ...

Uncaught TypeError: Cannot read property 'e' of undefined in vue.js

Feeling a bit frustrated now :( This is my first time trying to use vue.js, which comes after jQuery as the second JS framework I'm diving into on this planet. Here's the HTML code I have: var main = new Vue({ el: ".main-content", data: { ...

Issues with React in a Production Environment

After successfully developing a react app and express API that worked correctly in localhost, I decided to move my API to a digitalocean droplet. The droplet only had an IP address and used HTTP. While utilizing the API from the react app in development m ...

Uncovering data with the power of jQuery: Metadata

Hey there! I have a bunch of divs similar to this: <div class="card {toggle:'A'}"> <div class="card {toggle:'B'}"> <div class="card {toggle:'C'}"> <div class="card {toggle:'D'}"> Right now, ...

Using JavaScript, the list of items (images) will be displayed and placed into HTML panels

Below is the layout structure on my website: <div class="panel-heading"><h3 class="panel-title">Suggestions</h3></div> <div class="panel-body"> <div class="col-md-7"> <h3><span class= ...

Make sure accordion items stay open even when another one is clicked

I have implemented an accordion component that currently opens and closes on click. However, I am facing an issue where clicking on one item closes another item that was previously open, which is not the behavior I desire. I'm unsure of the best appro ...

The JavaScript function is unable to fetch information from the controller

I am working with a controller called Map1 that returns a JSON object. Within my scripts folder, there is a .js file named init.js. In this file, I am attempting to call the controller using the following code: $(document).ready(function() { $.getJSO ...

Tips to avoid multiple HTTP requests being sent simultaneously

I have a collection of objects that requires triggering asynchronous requests for each object. However, I want to limit the number of simultaneous requests running at once. Additionally, it would be beneficial to have a single point of synchronization afte ...