Generating normals for 3D noise displacement on arbitrary meshes

Hi there,

I’m trying to generate accurate normals for 3d noise displacement on arbitrary meshes. For 2d noise applied to a plane, this is easy: simply find the neighboring noise values with a small offset, and normalize the vectors.

However, for 3d noise, this approach doesn’t seem to work. I tried using the following approach but the results are really weird:

float3 GetNormal (float3 pos)
{
    float small = 0.001;
    float3 normal = float3(0.0, 0.0, 0.0);

    normal.x = Noise( float3(pos.x+small, pos.y, pos.z)) - Noise( float3(pos.x-small, pos.y, pos.z));
    normal.y = Noise( float3(pos.x, pos.y+small, pos.z)) - Noise( float3(pos.x, pos.y-small, pos.z));
    normal.z = Noise( float3(pos.x, pos.y, pos.z+small)) - Noise( float3(pos.x, pos.y, pos.z-small));
            
    return normalize(normal);
}

I’ve also read this article on normal perturbation but I have not been able to implement it correctly. Am I on the right track here?

Any suggestion would be greatly appreciated!

Hi, there is a article on gpu gems that shoes how to do this, found here.

The basic ideas is as follows. Havnt tested this but should work something like this.

float3 GetNormal(float3 N)
{

float e = 0.001;
float F = Noise(float3(x,y,z));
float Fx = Noise(float3(x+e,y,z));
float Fy = Noise(float3(x,y+e,z));
float Fz = Noise(float3(x,y,z+e));

float3 dF = float3((Fx-F)/e, (Fy-F)/e, (Fz-F)/e);

return normalize(N-dF);
}

Where N is the mesh normal

Ahh very good, this seems like a great idea. It’s not far from my original idea, but of course I must take the mesh normal into account, silly me… Thanks, I’ll try this out right now!