Individual Learning – Snow Effect

This week I did some more work with vertex displacement and started work on an effect I had wanted to make for a while, even before I started writing shaders: Snow resting on top of an object.

Everything went pretty smoothly, in the vertex function i find the slope angle, if it’s flat enough for snow to be there i set a mask value to white and if not it’s black;  I also displace the vert vertically.

Then in the fragment function I use the mask to lerp between the object’s texture and a snow texture (I left it white as I didn’t have one to hand). The effect is quite appealing though it does stretch the UVs around the displacement and the transition from snow to object can be jagged where there are sharp changes in geometry.

Here’s a video of the shader in action using a rock from the asset store for demonstration.

 

Once I had finished i decided to look into using tessellation which would give me more vertices to work with and in theory a better result. I found this page on the documentation which demonstrates how to implement tessellation in a surface shader.

I had been writing individual vertex and fragment shaders so I would have to re-write them however it did show me that I could perform vertex functions inside a surface shader using the vertex:vertFunction define in my shader code.

I used the Surface shader examples page on the unity docs to help me with my syntax and quickly got this very similar result the only major differance was that i could now store my mask value as a float in the Input struct and not a float4 in the v2f struct.

SnowShader_SurfaceExample

I did manage to get Tessellation and Phong Tessellation working without the snow effect but whenever I tried to include my vertex function I would get an error which i assume is caused because unity uses the vertex modifier after tessellation as it would usually be used to perform some sort of height map displacement. The tessellation was surprisingly easy to get up and running though.

This slideshow requires JavaScript.

The next step I would like to take is finding a way to use the tessellation with my snow effect to hopefully see an improvement compared to the original shader.

Individual Learning – Vertex Displacement

Last week I wrote a vertex displacement shader that uses a heightmap to displace vertices on a mesh. I managed to get a simple terrain example working very quickly by using an existing heightmap downloaded from google Images.

Here’s what it looks like with a standard plane:

VertexDisplacement_WorkingonPlane

I also created a higher resolution plane in Max to get this more detailed look. It is probably possible to use Tessellation to get the same result at runtime.

VertexDisplacement_HighPoly

Following this i decided to experiment with Unity’s Perlin noise function using what I had learned from creating my own procedurally generated terrain in Monogame. It’s not a very practical approach to terrain generation but it was interesting to experiment with. I also added some colour and a water plane.

VertexDisplacement_fractalterrain

I had some trouble with the noise generation as I discovered Unity’s perlin noise function returns the same value at integer values but after i added some values to tweak the scale I was using floats anyway. I also had an issue where the texture didn’t appear to generate as I was getting no displacement or colour on the plane, this however was because I had forgotten to call Texture.Apply() after setting the pixels.

It would be interesting to explore the use of tessellation to skip having to create a pre-subdivided mesh.

Heightmap available here.