WPO Smooth Calculation for Normals?

Hello. I’m using WPO for a thick, flowing lava material, but the WPO does not affect the normals. I researched and figured out using world position> cross product of DDX and DDY will derive normals from the displacement of the mesh, BUT the displaced normals derived from this method are not smoothed out. It looks like flat shading.

Is there a way to derive smoother results from a DDX/DDY normal calculation?

Using ddx and ddy, probably not since positional data is by definition a series of linear blends (ie the edges that connect 2 verts are straight). ddx and ddy return the slope or the rate of change and the rate of change is constant across a polygon.

but you can almost always define the normal mathematically, either by knowing the derivative of your function or if using textures, by combining some kind of companion normal maps. For sine waves this is by far the easiest since the derivative of sin(x) is cos(x). Then all you need is some very light geometry ( like pythagorean theorum) to convert it into a normal.

In ideal case UE4 would expose vertex normal and tangent output in similar fashion that it does expose WPO. Then procedural animation would be neat and performant without ridiculous amount of cludge.

I’m using the SimpleGrassWind function to derive my WPO. It’s surprisingly effective at more than just grass. I parameterized the sizes and used a negative intensity with a slower time and it works perfectly as a procedural flowing lava wave generator! Unfortunately, I tried transforming spaces and doing the math, but I’m definitely doing something wrong for calculating the normals. GGX/GGY is not good enough because the lava is affecting landscape, which does not have enough vertices to appear smooth.

There is a FunctionToNormal material function that probably would’ve helped doing all that math, but it doesn’t work. If there was an easy way to make a simple transform-to-normal function that works with any WPO procedural, or at least a normal option out of the SimpleGrassWind function, that would be awesome to include in the material function library! Unfortunately, the procedural I’m using is definitely more complicated than a sine or cosine: it’s displacing in all 3 axes with radial displacement.