Adaptive snow shader

In UnrealEngine 3


Introduction

When we started developing MetaBall2, we soon realized that we're going to need a generalized approach to snow. A method which lets us reuse existing objects, so I developed this technique, where the snow stays on top of the object, regardless of its rotation. It can be animated, and used for moss or sand deposits as well. The only drawback is the supressed normal map, which seems to be impossible to fix with the current set of nodes in RoboBlizt's Unreal Engine version.

Required assets

Obviously you will need a base texture, with diffuse, specular, etc textures, and a texture for the snow. The other important thing is a proper cubemap which will be used as a mask for blending between the base and the snow textures. It was made in modo using a gradient sky environment (white at the top, black at the bottom) and a fractal noise for the irregular, cloudy look.

Setting up the shader

On the left you can see the whole shader tree. The most important part is the "SnowMarks" group which generates the alpha for blending between snow and (in this case) rock textures.

The basic idea is that we get the direction of each pixel on the surface, and transform that vector so it becomes world relative. We feed it into the UV slot of the cubemap. At this point it looks like the cubemap is painted onto the surface. Now we start tweaking this gradient. The snow level can be shifted up and down by modifying the linked constant. If you use a scalar parameter instead then you can animate the amount of snow from kismet.
The "power" node modifies the contrast of our gradient, which makes the transition between rock and snow less or more accented. Finally we limit the end values to the 0..1 range, and its ready to use as an alpha texture.

The "Diffuse channel" group is pretty straightforward, we just use our newly created snow mask to interpolate between the two textures. It's the same deal with the SpecularPower group.

Now let's see the "Normal channel" group. Here we decrease the effect of the normalmap, it's only 20% visible. Ideally we would need only the normal of the polygon, unaffected by the applied normalmap, so the snowline follows the curve of the raw mesh, where the changes of the normal value have a low frequency. The normal maps have sudden normal changes which make the snowline scattered and noisy. Unfortunately with the current set of nodes we can't get the raw polygon normal, so we have to supress the normalmap.

To counteract this loss for a certain extent, I added a few extra nodes to the specular group. First I amplified and colorized the original specular texture. The bluish color feels like a thin layer of ice, which could explain the relative smoothness of the surface. I also applied the displacement map to make the surface more interesting by dimming specularity at places which supposed to be deeper, therefore less accessible to light.

And this is how it looks on the test object:

"Hmmm... donuts... " - Homer Simpson