A Practical Approach to Creating Glass Materials for Physically Based Rendering / by Ryan Smith

Watch 2019-03-24 23-05-39 GIF by @virtuosic on Gfycat. Discover more related GIFs on Gfycat

A colleague of mine recently asked me how i’d go about creating glass, so I figured I would make a walk through. We’ll start by making some grunge textures in painter and then we’ll import them into UE4. This walk through isn’t intended for beginners. As such, i’ll be skipping over some details that i’m assuming you already know.


Making the Grunge Textures

The grunge texture we’re going to make will act as a mask between our glass sub-material and our dirt sub-material. This is probably the most important part of the process because without decent grunge textures, our glass won’t look convincing. Anywhere where the grunge is applied will increase roughness, opacity, and base color resulting in the appearance of dirt on the glass.

Don’t pick a random noise or grunge to use for the dirt map. Find some textures that make sense to use on a window pane that’s exposed to the outdoors. Tell a bit of a story with it. Did the window get dirty and splattered before someone came by and tried to wipe it down? Would you see the evidence of those wipes and leaks? How about moisture? If the window was exposed to morning dew, humidity, and rainstorms, you’d definitely see some of that. Those were the questions I asked myself before starting to make some of the textures.

In the GIFs below I’m using Substance Painter’s stock noises because they work really nice for what I need. I start with a Dirt1, then add in Grunge Leak Small and then subtract Grunge Wipe Brushed to give it the look like someone tried to clean it off at some point. I then use a Perlin Noise to subtract some detail and break up the tiling a bit. I then add on some Moisture Noise. Finally I adjust levels a bit and finish up with a Sharpen. I did a similar process for the secondary grunge using similar maps. You can see that on the bottom right.

Watch 2019-03-24 19-08-14 GIF by @virtuosic on Gfycat. Discover more related GIFs on Gfycat

Watch Grunge00 New GIF by @virtuosic on Gfycat. Discover more related GIFs on Gfycat

To preview these in painter, i have a really simple setup of just two layers. Before you start, navigate over to the Shader Settings and set the shader to PBR Metal Rough with Alpha Blending. This will allow you to preview the mesh with transparency. I’ve also loaded in a flat plane oriented to the X axis for my preview mesh.

The Base glass layer has the following properties

BaseColor - 0.01 (Grayscale)

Roughness - 0.0

Metallic - 0.0

Opacity - 0.5

The Dirt layer only has 3 channels enabled and their properties are as follows:

Base Color - 0.15

Roughness - 1.0

Opacity - 1.0

I then add a black mask to the Dirt Layer and build the above textures directly in the mask stack. Result should look something like below.

If you want to create Opaque glass, simply set the opacity of the glass base to 1.

 

Watch 2019-03-24 21-20-20 GIF by @virtuosic on Gfycat. Discover more related GIFs on Gfycat

 

Building the Glass Shader

Time to pull the textures we made into Unreal and build a shader with them.

Lets first think about the properties which are relevant to physically based lighting of a completely flat pane of glass . We’ve got Base Color, Roughness, and Opacity. We don’t care about Metallic, since glass isn’t metallic. I don’t care about the normals either, since we’re building the shader for typical glass that doesn’t have bumps and grooves or warps. I’m also going to use the Spiral Blur function that comes with the unreal engine, and as a consequence of that decision, i won’t be able to use refraction, so i’m not going to worry about that for now. I can drive all of the effects above through a single packed texture map that contains the two textures I created above. One other important assumption to make here is that that this shader is designed to be used on a flat plane mesh. Adding this constraint enables us to add some cool features that will help improve its versatility.

So, I’ve created a shader. I have Blend Mode set to Translucent, Shading Model set to Default Lit and Lighting mode set to Surface Forward Shading. A warning here, using the surface forward shading is the most expensive lighting mode for translucent shaders because it calculates lighting for each light that’s hitting it, rather than using a deferred method. It also takes forever to compile so i hope you’ve got some patience. If you don’t have patience you can always just set blend mode to opaque to act as a “preview” until you need to swap back to translucent to test out the spiral blur. I’ve also enabled “Use Material Attributes” because i prefer to work that way when working on a shader that is blending multiple sub-materials.

The shader we’re going to build consists of 5 elements; We’ll first create the Glass and Dirt sub-materials just like we did in Substance Painter. We’re going to then create the grunge map expression that is the most involved part of the shader. After that we’ll hook up spiral blur and call it a day.

The final material at a glance. You can use this image to get your bearings when looking at the closeups below.

Lets first look at the Glass and Dirt sub-materials. This is a great place to start. I use Make Material attributes to set up our sub-materials because it’s just so much easier to work with when creating a shader that’s blending between two or more of them. If i didn’t use Material Attributes i’d have to blend all of the relevant attributes which would create a spaghetti node network. This method lets me keep it pretty clean.

Glass and Dirt Sub-materials

After the Glass and Dirt are set up to blend, I start to craft my Grunge Map expression. This is made up of a block of code that samples the packed grunge texture twice. The first texture (the one on top of the graph) is sampled with a slight bump offset to give the illusion of thickness to the glass pane. The second texture doesn’t have this effect. Both samplers have independent UV Tiling controls and scale based on the actor’s scale. This is accomplished by multiplying the coordinates by the Object Scale node. I’ve also implemented some functionality that you can see near at the beginning of the graph which adds a random offset to the texture coordinates whenever it is dragged 32 units in either axis in world space. This will help reduce obvious repetition in the texture in the event the planes are placed adjacent to each other. After I sample the textures i multiply them by a grunge intensity to help hone in the look i’m going for.

Grunge Map Sampling and Bump Offsetting

The inverse edge mask is a great way to break up the glass pane from the middle out to the edges. It’s just an easy tool to add to the box. You can see it’s effect bottom right.

Inverse Edge Mask to help break up glass panes if needed.

Watch 2019-03-25 00-38-25 GIF by @virtuosic on Gfycat. Discover more related GIFs on Gfycat

The mask adjustments block is a place where i add a bias so i can sort of control a minimum amount of grunge. I then multiply it by a “Master Intensity” which is essentially a master knob for the grunge intensity that happens after all the other values are nailed down. I have a bunch of saturates here to act as a sort of check on user input as well as keep the values in the range of 0-1. They’re practically free to use on modern hardware so it’s not too shitty to use them… although I may be able to get rid of one of them below but i got lazy.

Mask Adjustments

The last part of this is setting up the Spiral Blur. This expensive node ships with UE4. It samples the scene beyond the glass pane a shit ton of times and then blurs it in a spiral, which when used right gives some pretty great results. In our case, we’re multiplying the strength of the blur by our roughness parameter since it acts as a pretty good representation of our grunge mask. I’ve also got a custom Distance Mask that’s derived from Scene and Pixel depth. Subtracting Pixel Depth by Scene Depth gives us the distance of the pixel BEHIND the glass to the pixel on the glass plane. This will give a falloff to the blur based on that distance. After that setup, I follow the node’s instructions and hook the Result into Emissive Color and add the “Scene Color clamp to 0” into the opacity chain to finish everything off.

Quick tip: Use the Get and Set Material attribute nodes to quickly modify their attributes without using the big clunky “Break” material attributes node.

After all is said and done, you should have all the parameters you need to tweak yourself a cool lookin’ glass material! Try scrubbing Master Grunge Intensity back and forth. It’ll show you the range you can get from your grunge maps. Also notice the effect of the spiral blur as the grunge density increases and decreases. It does a great job at blurring the scene behind the glass when the grunge gets thick.

Watch 2019-03-24 23-02-05 GIF by @virtuosic on Gfycat. Discover more destiny2 GIFs on Gfycat

Try adding your own features or tweaking the shader to get some cool results. I really hope this walk through helps you in some way! Cheers.