Speed control in NodeMaterials


Today, I encountered an interesting issue. I work a lot with NodeMaterials, but I’ve never faced this before because I haven’t had a case where I needed to dynamically change the speed of “animation” in a node material. I noticed that I don’t understand how to make the animation speed change gradually.

Here’s a simple case: we have a Perlin noise block, and we want to animate it. We add time to the initial coordinates, and it becomes animated. If we want to speed it up or slow it down, we add a scaling block, attach time and a coefficient, and adjust it as needed. However, this works as long as we don’t change this coefficient dynamically. If we try to change the coefficient dynamically, the noise starts jittering until the value stabilizes. As far as I understand, this happens because when we multiply the time value by something, we get the previous frames.

Due to this effect, we cannot smoothly control the animation speed. Have you encountered this? Perhaps there are possible ways to make the animation smoother. I thought about providing my own time value to the shader, which would be changed outside the shader. But I want to check if there are any other ways.

PG: https://playground.babylonjs.com/#RSYBAN#3

Answer from chatGPT:

t looks like you’re trying to animate a Perlin noise block using Babylon.js NodeMaterials, and you’ve encountered an issue when dynamically changing the animation speed. The jittering effect is likely caused by abrupt changes in the speed, leading to discontinuities in the animation.

One approach to achieve smoother animation speed changes is to smoothly interpolate between different speed values over time. Instead of directly updating the speed value, you can calculate a target speed and gradually approach it.

Here’s an example modification for the second case (ground2):

javascriptCopy code

nm2.then((m) => {
    ground2.material = m;
    let targetSpeed = 1; // Set your desired speed here
    let currentSpeed = 0;
    let easingFactor = 0.05; // Adjust the easing factor as needed
    scene.onBeforeRenderObservable.add(() => {
        // Smoothly interpolate towards the target speed
        currentSpeed += (targetSpeed - currentSpeed) * easingFactor;
        // Update the time value in the shader
        ground2.material.getBlockByName('customTime').value += currentSpeed / scene.getEngine().getFps();

In this example, targetSpeed represents the desired animation speed, and easingFactor controls the rate at which the animation speed approaches the target speed. By using an easing function, you can create a smoother transition between different speeds, avoiding sudden jumps and jittering.

Feel free to experiment with the values of targetSpeed and easingFactor to achieve the desired visual effect.

Babylon.js Playground (babylonjs.com)

Is the result better?

Hello and Thank You!

The second result (right square) which i showed in my topic is what I want. But I prefer to do it in NM without providing of time variable to the material. And here I just want to check if somebody knows how to do it inside NM (If it’s at all possible)

Hello there! Passing the Scaler through a smoothstep seems to soft the animation a bit, does that work for you? Babylon.js Node Material Editor (babylonjs.com)