Need help understanding WPO with local/world space

Hi,

I’ve been battling with this for a while and looked around quite a bit for applicable documentation without luck. My goal is to create a fish shader, that will move the mesh in a wave imitating the swimming motion.

I’ve succeeded with the motion that I want, and isolated it to the Y-axis, but the issue is that I can’t find how to set up the shader, so it can work independent of the meshes rotation in the world. Now, as you can see in the second image, it breaks if rotated.

I’ve tried having the TransformPosition in the end, and feeeding a subtraction of the new/old positions, which resulted in a large offset from the origin, but with success in the rotation goal.

Please let me know if you need mroe info, I would be forever grateful for your help


1 Like

This looks pretty good

What you were trying to do makes little to no sense at all - think of it this way see if it helps you create your own thing before jumping to the tutorial.

A point in space is multiplied by some time - making it a different point,
Then divided by a wave, making it yet another point. Then multiplied by some value and generating yet anther point value - etc.

Now that would be well and good if all you were interested was a specific point, but you have a shader here - every vertex of this mesh is going to be doing what you wrote above.

And it makes little to no sense at all by application - the fish is bound to move - WPO will change by time and by position - now your “fish” is going to act more like a blurry mess than a fish…

So, why not use the proper type of WPO?
Click the node, check its properties. You’ll find some options there that will make it make more sense for your purpose.

Now with that out the way, do keep in mind that SubNautica re-wrote half the engine to introduce a proper pipline to have skeletal meshes with the fish swim shader working in order to create the schools of fish - they have some free to watch talks on how and what they did which you should probably look up just for knowledge sake.

Additionally - you would be way better off animating this via a texture and time.

You can do this straight up yourself by making an appropriate texture and time sine which will slightly shift the poistion of each vertex differently by getting mapped to the UV somehow.
You can think of a white to black tail to head texture being used to define what “band” of the mesh gets the “most” movement based on the other time node.
Say a full motion takes X time, you can create that time sine and use the known value to define how the image scrolls through the values you pick offset by that texture.

Or - and this could he better - you just use PivotPainter to set this up entierly in a DCC and will be able to get a very custom yet very lightwait complete animation…