Hey dear friends, developers, and contributors!
When I worked on the Flow movie project, I used the sum of sine waves for water rendering. One part in geonodes - to generate the mesh and displace the geometry, and the other part in shaders - to generate fragment normals. That was necessary so the water waves look pixel-perfect, even when the water geometry was coarse.
And getting the normals for a sine wave is easy.
Recently I switched the wave generation to the new Gabor noise. The Gabor texture waves look stunning. Unfortunately, the performance is⦠not. Normal generation is the main bottleneck here. Each wave sample uses 3 texture lookups, and with 16 samples, thatās 48 procedural lookups per pixel. Not ideal.
āBump to Normalā nose is one solution, but it relies on partial derivatives.
Partial Derivative Normals
These are computed using the partial derivatives of the pixel value with respect to screen-space or UV-space coordinates, using functions like dFdx()
and dFdy()
.
Advantages:
- Automatic: Rely on built-in GPU functions.
- Flexible: Works for basically any texture where analytic normals are unavailable.
Disadvantages:
- Approximate: Based on finite differences of nearby fragmentsāless accurate than analytic normals.
- Unreliable: The result depends on the screen-space sampling rate and can be noisy under certain conditions.
Analytic Normals
These are computed from an explicit mathematical representation of the surface. For example, if a surface is defined by a function or a parametric equation, its normal can be derived using vector calculus (like the cross product of tangent vectors).
Advantages:
- Exact: Derived directly from the underlying function, so they are as accurate as the model allows.
- Stable: Do not rely on sampling or finite differences, so no approximation error.
So, I propose to include analytic derivatives for Gabor noise and, ideally, also for other procedural textures. This would make per-pixel lighting calculation for procedural surfaces fast and easy.
For geo-node textures, the feature is not required as the normals are calculated directly from vertex normals.
Here are some examples of what I am talking about:
Gabor:
Simplex 3D:
(I have more links to, basically all noise types +(2D, 3D and 4D), but I can only add 2 links right now)
I live in shaders, so I am proficient at implementing that myself, but I would like to discuss this further.
MÄrtiÅÅ” UpÄ«tis