unity-game-engineshaderpixel-shader

Unity Shader Graph: Combining texture rotation and offset


I'm making a water simulation, and I'm trying to visualize the velocity field. In this demo I continuously add water in the centre of the image, where the blue 'raindrop' things are.

I have a texture where rg is the X and Y direction of the velocity, and ba is the total movement of water through it (ie: every step ba = ba + rg * delta_time).

I'm working in Unity Shader Graph.

I want to rotate a 'ripple' texture in the direction of the velocity, and then translate in that direction as well. To prevent the shader from jumping around when the velocity changes I thought of using the ba channels (which were previously unused) to keep like a total velocity like described above.

However, both the rotation (based on velocity alone), and the translation (based on the 'total velocity') work fine on their own. But when I sum them together it looks like the translation is also rotated. I'm not sure why this happens.

Here's what I do:

First part: rotating my water texture in the direction of the velocity, and that looks fine:

enter image description here

The shader itself looks like this:

enter image description here

So basically I discretize the uv (custom function on the right), get the angle of the velocity (using arctan2), and then rotate each discrete block using the Rotate block. This works as expected.

Second part: translating the texture based on the total velocity (in the ba channels), also works as expected:

enter image description here

The shader itself looks like this:

enter image description here

Again I used the discretized uv, now I translate each block based on the ba channels, which contain the total of the velocity (ba = ba + rg * delta_time each time step). As you can see this shows the textures flowing away from the centre (where water is added constantly). This is what I would expect to happen.

Now, when I combine them, it goes wrong:

enter image description here

enter image description here

The one I circled in red shows the problem the best (though all block seem to have it to some degree, depending on how much they were rotated). The arrow point to the bottom-right, which seems to be correct, however it flows to the top now.

The shader:

enter image description here

So here I add the rotated discrete block to the translation. But it looks like the translation part now also rotated, even though I add them together after the rotation block. So while the translation isn't rotated, it looks like it is.

Why is this happening? And how can I fix it.

I hope I explained it adequately, since it's not easy to show in just pictures and gifs.

Thanks!


Solution

  • So I fixed my problem by rather than storing the x and y of the offset in the b & a channels, to just storing the total distance moved in the b channel (thus b += length(rg)). Then I'm using float2(0, b)` as the offset. This is then also rotated for some reason and visually works as I wanted it.

    However, I still don't really see why, sometimes I think I get it, and then I think some more and I don't any more. So if anyone knows why this happens and can explain, I'm happy to accept that answer. However, for now it is solved.