This is the fifth part of the online series dedicated to Journey Sand Shader.

- Part 1. A Journey Into Journey’s Sand Shader
- Part 2. Journey Sand Shader: Diffuse Colour
- Part 3. Journey Sand Shader: Sand Normal
- Part 4. Journey Sand Shader: Specular Reflection
**Part 5. Journey Sand Shader: Glitter Reflection**- Part 6. Journey Sand Shader: Sand Ripples

In this fifth post, we will recreate the shimmering reflections that are typically seen on sand dunes.

Shortly after the publication of this series, Julian Oberbeck and Paul Nadalack made their own attempt at recreating a Journey-inspired scene in Unity. You can see in the thread below how they have improved the glitter reflection to have more temporal coherence. You can read more about their implementation on IndieBurg’s article Mip Map Folding.

Made a journey like shader just for fun starting of from @AlanZucconi tutorial and a little help form @littleBugHunter expanding on it for better glittering. So much glitter đ

*Rocks from asset store #shader #madewithunity #unity3d #Unity pic.twitter.com/nt7MOrxbnt— Julian Oberbeck (@fleity) January 8, 2020

The previous lecture in this online course covered the two basic specular reflections features in *Journey*‘s sand rendering: **rim lighting** and **ocean specular**. This post will explain how to implement the last variant of specular reflection: **glitter**.

If you have visited an actual desert, it is hard not to notice how shimmering the sand really is. As discussed in the third lecture, Journey Sand Shader: Sand Normal, each grain of sand can potentially reflect light in a random direction.Â By virtue of sheer numbers, some of these reflected rays will hit the camera. This causes random points of the sand to appear as very bright. These glitters are also very sensitive to movement, as even the slightest misalignment will prevent the reflected rays from hitting the camera.

Other games, including Astroneer and Slime Rancher, have used glitter reflections for sand and caves.

It is easier to appreciate these shimmering specs in the zoomed images below:

It is undeniably true that the glitter effect that can be seen on real dunes is solely determined by the fact that some grains of sand randomly reflect light back into our eyes. Technically speaking, that is something that we have already modelled in the second part of this online course, Journey Sand Shader: Sand Normal, when we have modelled the random distribution of the normals. So why do we need yet another effect for this?

The answer might not be so obvious. Let’s imagine that we try replicating the glitter effect using the normals only. Even if all normals would point towards the camera, the sand still would not shimmer. This is because the normals can only reflect as much light as available in the scene. So, at best, that approach could only reflect 100% of the light back (if we had completely white sand).

What we want here, however, is different. To make a pixel appear so bright that light *leaks* on its nearby pixels, the colour must be greater than . This is because in Unity, when a **bloom filter** is applied to the camera using a **post-processing effect**, colours brighter than will be propagated to nearby pixels, resulting in a halo that gives the impression certain pixels are glowing. This is the base of **HDR rendering**, where HDR stands for **High Dynamic Range**.

So no, normal mapping cannot be easily used to create glitter surfaces. This is why such an effect is more conveniently implemented as a separate process.

## Microfacet Theory

To approach this scenario more formally, we need to treat the dunes as if they were made out of microscopic mirrors, each one with a random orientation. This approach is called **microfacetÂ theory**, where a **microfacet** is the technical name of one of these tiny mirrors. The Mathematical foundation of most modern shading models is based on microfacet theory, including Unity’s Standard shader.

The first step is to divide the dune surface in microfacets, and to find the orientation of each one. As already discussed, we have done something similar already inÂ Journey Sand Shader: Sand Normal, where the UV position of the dune’s 3D model was used to sample a random texture. The same approach can be reused here, to associate a random orientationÂ to each microfacet. The size of each microfacet will depend on the scale of the texture, and on its **mipmap level**. Our task is to reproduce a particular aesthetics, not to embark on a quest for photorealism; this approach will be good enough.

Once we have sampled a random texture, we can associate a random directionÂ with each grain of sand/microfacet that makes up the done. Let’s call it . This represents the **glitter orientation**, which is the **normal direction** of the grain of sand we are looking at. An incoming ray of light that hits the glitter will be reflected assuming the microfacet as a perfect mirror which is facing the direction . The resulting reflected ray of light, , is what needs to hit the camera (below).

Once again, we can use the **dot product**Â between and to measure their degree of alignment.

One approach is to take the power of , as explained inÂ Journey Sand Shader: Specular Reflection. If you try, you will see that the resultÂ looks very different from what seen in *Journey*. Glitter reflections should be rare, and very bright. The simplest solution is to only consider the glitter reflections for which is below a certain threshold.

## Implementation

We can easily implement the glitter effect described in the paragraph above thanks to the reflectÂ function in Cg, which allows calculating very easily.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
sampler2D_float _GlitterTex; float _GlitterThreshold; float3 _GlitterColor; float3 GlitterSpecular (float2 uv, float3 N, float3 L, float3 V) { // Random glitter direction float3 G = normalize(tex2D(_GlitterTex, uv).rgb * 2 - 1); // [0,1]->[-1,+1] // Light that reflects on the glitter and hits the eye float3 R = reflect(L, G); float RdotV = max(0, dot(R, V)); // Only the strong ones (= small RdotV) if (RdotV > _GlitterThreshold) return 0; return (1 - RdotV) * _GlitterColor; } |

Technically speaking, if is completely random, then as well will be completely random. It might seem unnecessary to use reflect. While this is true for a static frame, what happens if the lighting source is moving? This could either be because the sun itself is moving, or because there is a point light attached to the player. In both cases, the sand would lose temporal consistency between a frame and the next one, causing the glittering effect to appear at random locations. Using the reflectÂ function, instead, allows for a much more stable rendering.

You can see the result below:

If you remember the first post in this series, the glitter component is added to the final colour.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#pragma surface surf Journey fullforwardshadows float4 LightingJourney (SurfaceOutput s, fixed3 viewDir, UnityGI gi) { float3 diffuseColor = DiffuseColor (); float3 rimColor = RimLighting (); float3 oceanColor = OceanSpecular (); float3 glitterColor = GlitterSpecular (); float3 specularColor = saturate(max(rimColor, oceanColor)); float3 color = diffuseColor + specularColor + glitterColor; return float4(color * s.Albedo, 1); } |

That is likely to cause certain pixels to end up with a colour greater than , which will result in a bloom effect. This is exactly what we want. The effect is also added on top of the already existing specular reflection (discussed in Journey Sand Shader: Specular Reflection), so that shimmering grains of sand can also be seen where the dunes are well lit.

There are many ways in which this technique can be improved. It all depends on the final look that you want to achieve.Â BothÂ Astroneer and Slime Rancher, for example, rely on this effect only at night. This can be achieved by modulating the strength of the glitter effect based on the direction of the sunlight.

The quantityÂ max(dot(L, fixed3(0,1,0),0)), for instance, is when the sun comes from above, and zero when is behind the horizon. But you can create your own to fit the aesthetic that you have in mind.

â Why the Blinn-Phong reflectance does not use*reflect*?

**ocean specular**that we have seen in the previous post,Â Journey Sand Shader: Specular Reflection, was implemented using the

**Blinn-Phong reflectance**.

That is a very popular model used in early 3D graphics to shader highly reflective surfaces, such as metal and plastic. It’s equation is:

(1)

where

(2)

The Blinn-Phong reflectange is a variant of the more expensiveÂ **Phong Reflectange**, which equation is:

(3)

which indeed calculates the amount of reflected light that goes back into the camera.

The problem is that reflectÂ can be expensive. For front facing surfaces, the Blinn-Phong reflectance replaces with , which is a very close approximation.

## What’s Next…

In this fifth part of the online series about the sand rendering in Journey, we continued working on the specular reflections, adding tiny glitters to the dunes to make it even more realistic.

The next part,Â Journey Sand Shader: Sand Ripples, will conclude this online series by adding ripples based on the dunes inclination.

- Part 1. A Journey Into Journey’s Sand Shader
- Part 2. Journey Sand Shader: Diffuse Colour
- Part 3. Journey Sand Shader: Sand Normal
- Part 4. Journey Sand Shader: Specular Reflection
**Part 5. Journey Sand Shader: Glitter Reflection**- Part 6. Journey Sand Shader: Sand Ripples

### Credits

The videogame Journey is developed byÂ **Thatgamecompany**Â and published byÂ **Sony Computer Entertainment**. It is available for PC (Epic Store) and PS4 (PS Store).

The 3D models of the dunes, backgrounds and lighting settings were made by Jiadi Deng.

The 3D model of the Journey’s player was found on the (now closed)Â FacePunch forum.

## Download Unity Package

If you want to recreate this effect, the full Unity package is available for download on Patreon. It includes everything needed, from the shaders to the 3D models.

##### đ§ Stay updated

A new tutorial is released every week.

##### đ Support this blog

This websites exists thanks to the contribution of patrons on Patreon. If you think these posts have either helped or inspired you, please consider supporting this blog.

##### đ Licensing

You are free to use, adapt and build upon this tutorial for your own projects (even commercially) as long as you credit me.

You are not allowed to redistribute the content of this tutorial on other platforms. Especially the parts that are only available on Patreon.

If the knowledge you have gained had a significant impact on your project, a mention in the credit would be very appreciated. â¤ď¸đ§đť

Thanks for this tutorial. How do you pass in the uv to the GlitterSpecular function? In your code you have not passed in the parameters in line 8.