Calculating normals of SDF

I have an SDF of a sphere which I distort with unity’s snoise function that returns the gradient. What I need help with is using that gradient to calculate the new normal of the sphere. Before distorting the sphere, the normal would just be the sampling point normalized, but since distorting the sphere also distorts the sample point, I need to calculate a new normal. I hope that made sense, and here is the code:

private readonly VolumeOutput SphereSDF(in float3 sample)
            {
                float leng = length(sample);
                float distance = leng - Height; // sphere sdf
                float noise = noise.snoise(sample, out float3 gradient);
                distance -= noise; // distorted spehre sdf

                float3 norm = normalize(gradient); // very bad normal, I need help with this!

                return new VolumeOutput(distance, noise, norm); // return the sdf data
            }

I think you would need three very-close-together height samples to develop an idea of what the surface is doing at a single point:

  • the original
  • one along the U (or X)
  • one along the V (or Y)

Since its sphere, shouldn’t I also need to calculate the Y? And that stuff is the gradient I believe.

Normals are calculated in local UV space, AFAIK.

This means that you would need to know what constitutes U or V at any given point in your geometry.

float3 norm = cross(normalize(sample), -normalize(gradient)); this gets me close to what I want, but it doesn’t look correct and has patches of normals that seem to be the exact same:
Note: this is the planet at it’s left side
This is what the terrain looks like8679018--1169850--upload_2022-12-21_13-1-25.jpg
this is it’s normals
8679018--1169844--upload_2022-12-21_13-0-48.jpg