Nicolas Sievers
Slope determinant snow
Last update: 4/11/04
Assignment:
Create a shader such that "snow" is produced in the "valleys" of the shader.
My Analysis:
Complicated problem as the snow should be based on the rate of change in the slope of the surface not on an arbitrary height value. Will have to use formula based off the normal values of points on the surface.
So using (asin(ycomp(n)) * 180 / PI) where n = normalize(N); This will produce an angle onto which I could base where the surface would be colored white with snow. I got to this point by looking at the output a many different values that are part of the renderman shading language. Such as N, Ng, du, dv, dPdu, dPdv, etc...
Basically the first derivative ( Du or Dv depending on direction) tells you whether the slop is increasing or decreasing and the second derivative ( Du(Du) or Dv(Dv) ) tells you whether in rate of change of the slope is increasing or decreasing. Using these two values you can determine where the hill and valleys are on the surface.
Here are some pics.
The first is at a 30 degree rotation and the second is at a 60 degree rotation. The displacement was generated by the noise function. So noise is the function that you want to calculate the derivative of. S in my case it would be the same as Du( abs(.5-noise(P*freq)) / freq) - .5) the second derivative would thatn be Du(Du).

However there are two problems with this:
1. This would also put snow on 'gentle' peaks the have a low slope(low or no surface change) on their crests, not just in the valleys where there is also low slope.
2. This will not take into account rotation of the surface about an axis. This can be seen with the difference of the two pics above. The one on the left that
is at the 30 degree rotation is close to what the proper shading would be, however as the angle increases the problem can be see more easily as in the 60 degree rotation on the right.
To take care of problem 1. We need to find the second derivative of the function that created the surface. This particular surface was created with noise().
The first derivative of your function will find if the the surface is increasing or decreasing from point to point and the second derivative with tell you whether the rate of change is increasing(+) or decreasing(-).
Gets rid of the snowy peaks, however there seems to be artifacting bands that I have found somehow related to shading rate.

A good site on 3d transform/rotation matrices is here
Update 4/11
So the prior work still left me with two problem areas:
1. The account for rotations about and axis. I took care of this problem by taking the dot product of the old normal vs. the old normal. This returned a value which could be used to determine the correct level of snow no matter the rotation. n = normalize(N) is the original normal and the dot product of that vs. the new normal is newNormal = normalize(N).n
2. The second was the banding artifacts that where being generated within the snow. At first because these lines where perfectly perpendicular to the camera I thought that it had something to do with the shading rate or the actual noise function which generated the displacement. It occurred to me however to try and rotate the mesh to see if the effect is still the same. It was! You can somewhat see the banding in the one on the left, however the simplified displacement on the right shows it more effectively.


So what possibly could be the problem? It had to be somewhere in the way I was using the derivative and the second derivative. Finally after some time I finally figured out that I was only taking into account the derivatives in the 'u' direction. I needed to implement them in the 'v' direction as well. Thus I needed to use th Dv(x) and Dv(Dv(x)).
So after the fix here is the snow animated melting, as if the snow was in a drift like pattern such that the valleys had more snow that the mountain tops. This version also has anti-aliasing via smoothstep.