I have a basic tri-planar shader that samples from the x, y and z components of the surface normal, which works nicely for standard ‘y is up’ terrain, but what I really want is to apply it to the surface of a planet, such that I can sample from an ‘inward’ texture (towards the core of the planet), an ‘outward’ texture (away from the core of the planet) and a third texture for everything in between. How would I go about doing this?
Well you could just construct up/right/forward vector relative to your planet surface and then transform your global-normal into normal relative to surface. Something like this (code untested):
float3 up = normalize(v.vertex);
float3 right = normalize(cross(up, float3(0, 1, 0));
float3 forward = normalize(cross(right, up);
float3 localNormal = float3(dot(v.normal, right), dot(v.normal, up), dot(v.normal, forward));