Fast Arctan and Arctan2 in [-1, 1]

https://www.dsprelated.com/showarticle/1052.php

One of the approximation of arctan() is:

$$ atan(z) \approx \frac{z}{1.0 + 0.28 z^2} $$

Another is a polynomial:

$$ atan(x) \approx 0.9724x - 0.1919x^3 $$

Vegetation Procedural Animation

GPU Gem 3: https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-16-vegetation-procedural-animation-and-shading-crysis

Vertical Weight

Simply using y-axis as weight on swing calculation might not be enough. When the mesh is too high on the y-axis, the bending will be too strong to look good. We can use another set of UV’s v value as weight so that the weight is between 0 and 1.

Linear weight on calculation might not achieve the best result, we can add some smoothing.

// simple
half simpleSmooth = uv.y * uv.y;

// fancy
half fancySmooth = vertex.y + 1.0;
fancySmooth += 1.0;
fancySmooth *= fancySmooth;
fancySmooth = fancySmooth * fancySmooth - fancySmooth;

Swing

Another feature of interest is that the swing can be forward or back-and-forth. Remapping the sine wave result to 0 and 1 can achieve this result.

Variation

To add some variation in the swing, we can use world space position as a random factor input.

half randomFactor = lerp(0, frac(UNITY_MATRIX_M[0][3] + UNITY_MATRIX_M[1][3] + UNITY_MATRIX_M[2][3]), _BendMainParams.w);