Calculating gradient of a scalar field + bug in Noise POP `NoiseGradient`?

Hi folks, I’m getting into pseudo-scientific simulations like flow-fields with convection and diffusion and need to calculate the gradient (“first-order derivative”) of a float attribute stored on a Grid POP.

I have a GLSL code that seems to be working for this (yay!)
tox is attached - in a nutshell this is the calculation:
Retrieve the point’s index along the dimensions, using

uint[2] dimcoords = TDDimCoords(TDIndex());
int indexI = int(dimcoords[0]);
int indexJ = int(dimcoords[1]);

then grab the values from the up/down, left/right neighbors (after clamping the index):

	float fRight = TDIn_Noise(0, neighborIndex(indexI + 1, indexJ));
	float fLeft  = TDIn_Noise(0, neighborIndex(indexI - 1, indexJ));

then calculate the “central-difference” derivative dFdx = (fRight - fLeft) * 0.5;

First question: is this a good approach, is there a better way, or a native POP’s way?

Second question: To debug the code and figure out what’s going on, I was comparing my GLSL-calculated gradient vector against the Noise POP-generated NoiseGradient vector and found some strange behaviour.

When Offset = 0 and Positive Only is disabled, the two methods look very very similar. Any small differences are likely attributable to the GLSL doing a finite-difference calculation on a roughly-spaced grid, while the Noise POP is doing this analytically from the noise function.

However, increasing the Offset leads to a change in the Noise POP-generated gradient - higher offset makes it point “up and to the right”. This is strange… mathematically-speaking, adding a constant offset to a function should not change the gradient! The GLSL-calculated gradient, in fact, does not change.

A similar thing happens when Positive Only gets enabled. The GLSL-calculated gradient looks “correct” but the Noise POP-generated one looks off.

Is this a bug, or am I not understanding correctly what the Noise POP is outputting here?

.tox attached, thanks for your inputs here.
base_gradient.tox (13.3 KB)

Hello @michaeljohnson.tv

I think this works fine if your points are close enough. Another approach is to have multiple similar fields translated by small amounts and calculate the gradient by averaging the difference in scalar values.

At some point, we would like to add the option to compute an analytical gradient on the Field POP, for example, but we haven’t gotten around to it yet.

(See this post)

For the second part of your question, I believe there’s a bug with the gradient computation on the Noise POP. The offset should not affect the gradient. I checked and the gradient on the Noise TOP, for example, is not affected by offset. I believe the ‘Positive Only’ parameter should not behave this way on the gradient either.

Maybe these parameters were meant to be post-operations applied to all noise-type outputs. I’ll check with the team, but from what I see, this is just an oversight. We’ll look into this. Thank you for reporting the issue.

Hi @Guillaume.L and thanks for following up. I learned a lot from diving into Tim’s post, thanks for sharing that. I also checked the Noise TOP and using Slope TOP confirmed the derivatives are not impacted by changing Offset, like you say.