Smooth Normals in raycast?

Hi Everyone,

so I have my simple hover craft ‘game’.

I am aligning the ship to the ground mesh using normals I got from a downwards ray cast hit. The problem is it makes the movement jerky presumably because of the changing per face normals.

Is there a way to smooth out the normals without changing the mesh? Like gouraud shading?

I am already saving samples over time and averaging using these. I will also shoot four rays instead of one.

Any other suggestions?

Cheers Fred

Shoot multiple rays, say 1 from each corner of the craft and one from the center. Then add all the normals together and divide (or apply a per-normal weight if you want to). This will give you a smoothed normal.
You could go further and raycast from beyond the craft, so in effect “looking ahead” on the terrain, and factor those normals into the calculation.

Finally, and I’m not sure if you are doing this already or not, the resultant normal - don’t apply it directly to the craft. Instead interpolate it in over a period of time. Something like:

Vector3 centerCastNormal; // raycast from model center
Vector3[] cornerCastNormal; // raycast from model corners
Vector3[] lookaheadCastNormal; // raycast from beyond model edge

float centerFactor = 0.4f;         // These need to all add to 1.0f
float cornerFactor = 0.4f / 4.0f;
float lookAheadFactor = 0.2f / 4.0f;

Vector3 smoothedTerrainNormal = centerCastNormal * centerFactor +
                          (cornerCastNormal[0] * cornerFactor) +
                          (cornerCastNormal[1] * cornerFactor) +
                          (cornerCastNormal[2] * cornerFactor) +
                          (cornerCastNormal[3] * cornerFactor) +
                          (lookaheadCastNormal[0] * lookAheadFactor) +
                          (lookaheadCastNormal[1] * lookAheadFactor) +
                          (lookaheadCastNormal[2] * lookAheadFactor) +
                          (lookaheadCastNormal[3] * lookAheadFactor) ;

Vector3 craftUpVector = Vector3.Slerp(transform.up, smoothedTerrainNormal, Time.deltaTime);

Hi Paul,

and thanks a lot for your suggestions.
I will definitely try shooting four rays.
And I’ll try to Slerp a bit too to see how much that helps. Do I just use Time.deltaTime like that or should I add a multiplier?
Cheers Fred

Add a multiplier, sure. Whatever you need to do to get the effect you desire is good.