Logo 3.5Cats_AndHalfAFish

3.5Cats_AndHalfAFish

Glass, fake shadows, and light shafts.

June 11, 2020 Shade, Godot, 3d, Blender, glass, fake shadow, light shaft
Simple fakery.

Note : Blender 2.82, Godot 3.2.1.
 

Looking at the room I've been working on, it seems it's time to try and implement windows in the game.
I would like to get at least some basic idea of how to do 'plain' glass, stained glass with colored shadows, and light shafts.

I'm guessing that should also involve baking light, and using GIProbes and ReflectionProbes. But, one scary new thing at a time ...

Glass material in Blender.

Since all of my modeling and texturing so far has been done in Blender, I first tried to create a simple glass material there. As it turns out, Blender has a dedicated 'glass shader' that seems to work out of the box :

Blender : glass shader.
Blender : glass shader (default settings).

Rendering an object with this glass material however only seems to work with the Cycles renderer. Rendering the glass object in Godot also fails.

Glass material rendered with Cycles, Evee, and in Godot.
Glass material rendered with Cycles, Evee, and in Godot.

Glass material in Godot.

My next line of attack was to try and find a Godot tutorial, but there doesn't seem to be much information around on how to create nice materials. I found 2 videos by 'tutor tomato' (see list at the bottom), and one by 'Stanley'. I also found a glass material on the 'scificar' model in the Godot tps-demo.
The list also includes 2 of the easier Unreal and Unity tutorials for comparison.


Below are some suggestions on how you can go about creating a basic (non-realistic) glass material in Godot :


1) No textures :

Godot : tps_demo glass material.
Tps-demo (indoor scene) : glass material.
Godot : tps_demo glass material properties.
Tps-demo (indoor scene) : glass material properties.

Notice the 'transparent' flag and the albedo alpha value.
The only other settings in this type of glass are the 'metallic' setting of 1 (meaning : the material will act as a mirror), and the roughness value of 0 (fully smooth surface).
If you increase the roughness slightly, you will start to see a highlight from the sun (directional light) in my scene.

Godot : tps_demo glass material with roughness = 0.07.
Godot : tps_demo glass material with roughness = 0.07.


It's also possible to add in some 'refraction'. I used a setting of 0.02.

Godot : tps_demo glass material with refraction = 0.02.
Godot : tps_demo glass material with refraction = 0.02.


Note : the 'blend mode' (under the 'parameters' heading) is set to 'mix'. So, normally, this would mean that the default (opaque) render pipeline is used. That means : no transparency !
If you do want to use transparent materials with the 'mix' blend mode, you have to turn on the 'transparent' flag so that the engine will use the more expensive render pipeline for transparent materials.
Another way of forcing the rendering to go through the transparency pipeline (without setting the transparency flag) is by using any of the other blend modes (add, subtract, multiply).


2) Simple textures :

This glass is pretty similar to the previous glass, but it uses a texture for the albedo (albedo color = white, with alpha = 30) :

Godot : glass material with albedo texture.
Godot : glass material with albedo texture.

The light green tint comes from the texture (made in Gimp).

Godot : albedo texture (Gimp).
Godot : albedo texture (Gimp).

The texure is made up of a circle and a border. Tthe 'edge' opacity is set to 24 in the texture used in Godot.

The nice thing about this texture is that you can still change its color from within Godot (I guess it would have been better to create a white texture in Gimp rather than a light green one) simply by changing the albedo color :

Godot : glass material with a blue tint.
Godot : glass material with a blue tint.


This is a silly example of a glass material with an albedo texture and a normal map:

Godot : glass material with albedo texture and normal map.
Godot : glass material with albedo texture and normal map.


And, a more serious example : frosted glass (albedo texture + normal map).

Godot : frosted glass (albedo texture and normal map).
Godot : frosted glass (albedo texture and normal map).

The frosted glass was created from a JPG image I found online (search for 'frosted glass').
The normal map was created using the NVIDIA Texture Tools Exporter. This is a free Windows tool that comes as a standalone version and an Adobe Photoshop plugin. It can be used for all kinds of texture-related things (compression, mipmapping, cube maps, transparancy, ...) but I've only used it for the creation of normal maps.

Colored glass with colored shadows.

As far as I can tell, transparent materials cannot cast shadows.
But, of course, you can fake them ...


1) Using existing lamps :

If you use the lamps already present in your scene to create the shadows, it's an all or nothing thing.

The easiest way is to duplicate the transparent object, make it slightly smaller than the original object ('mesh : make unique'), give it an opaque material ('material : make unique'), and set it to 'shadow only'.
Of course, do not forget to set the lamp to cast shadows as well !

Godot : faking shadows for a transparent ball.
Godot : faking shadows for a transparent ball.
Godot : faking shadows for a transparent ball (settings).
Godot : fake shadows (settings).


2) Using a textured plane :

If you have static shadows, you could use a textured plane (maybe deform it a bit) with some emission added ... Just put the plane close to the floor, at the location where you want the shadow to appear.

Godot : faking colored shadows.
Godot : fake colored shadows for a stained glass window.

Of course, this would be even better with some blur, and a shaft of colored light.
Oh well. One can always dream ...

Light shafts.


As far as I know, Godot 3.2.1 does not implement 'volumetric light' (the technical term for 'light shaft'). But we can fake it :


1) Shader material :

The first example is based on the Godot tps demo.
(I added an extra OmniLight (very pale orange) right where the window is, to give some extra light to the start of the beam as well as the stone setting for the window.)

Light shaft based on the Godot tps demo.
Light shaft based on the Godot tps demo.


And this is how they did it in the demo :

. the mesh :
Open 'demolevel.blend' (demo > level > geometry) in Blender and search for 'lightshaft'.

Godot tps demo : light shaft mesh.
Godot tps demo : light shaft mesh (Blender).

. the material :
Open 'level.tscn' in the Godot editor, search the nodes for 'lightshaft', and take a look at the material ...

Godot tps demo : light shaft shader material.
Godot tps demo : light shaft material (Godot).

The material is actually a Shader material that makes use of a gradient texture (256x256).
At this point, I'm not sure exactly how the shader works (a topic for later), but you can play with the 'shader params' in Godot and see what effect they have in the scene.

Godot tps demo : light shaft shader.
Godot tps demo : shader.
Godot tps demo : light shaft gradient texture.
Godot tps demo : gradient texture.


2) Spatial material :

The second example is even simpler.
I created a cone mesh in Blender and uv-unwrapped it. I then imported the mesh into Godot and gave it a material.

Simple light shaft.
Simple light shaft.

This is how it was done :

Simple light shaft - material.
Simple light shaft - material.

I set the 'unshaded' flag to true, and 'culling' to disabled (but both are optional).
I also enabled the 'proximity fade'. The result is that the light beam 'becomes softer'/fades out when it is close to another object (the wall and the floor). In the image below, I turned the transparency down to better show the effect.

Simple light shaft - proximity fade.
Simple light shaft - proximity fade : no ugly circle on the floor.


This is what it looks like in-game :


There's one more setting that you might want to turn on, and that's the 'distance fade'. This makes the light shaft fade out when the player gets close to it. Compare the clip below with the one above.
I used the default settings for 'PixelAlpha' (0 and 10) :


3) Animated light shaft :

The last example is an animated light beam. I have left the transparancy a bit too low, and made the animation speed a bit too fast so you can see better what happens :


Basically, everything is similar to example 2, except that I'm now also using an AnimationPlayer node to animate the texture ! Or rather, I'm keyframing the uv1 xyz offset ...

Simple animated light shaft : animation player.
Simple animated light shaft : animation player.
Simple animated light shaft - keyframes and speed setting.
Simple animated light shaft - keyframes and speed setting.


Of course, the possibilites are endless : almost everything can be animated in Godot. So you could change the transparency, or the color, or even the texture ...

One thing that would be 'nice to have' here, is a Fresnel effect. The 'Dave Wilson' UE4 tutorial (see list) demonstrates the effect of that : the light beam becomes 'softer' at the edges.


Note : there's one more thing I would like to mention about materials in Godot. It has confused me for the longest time ... Well, it's still a bit confusing, but at least I understand -some- of it now.

As mentioned in the 'spatial material' documentation, there are 3 places where one can set a material !
1) in the material property of the mesh - header 'MeshInstance' :
→ every time this particular mesh is used, it will automatically have the material.
2) in the material property of the node using the mesh (eg. a MeshInstance node) - header 'Material' :
→ the material is only used with this particular node ; if a material was set in (1), it is overriden.
3) in the material override property of the node using the mesh - header 'GeometryInstance' :
→ the material is used only with this particular node, and overrides (1) and (2)
(this is the one that still confuses me - how is this different from (2) ?)


So. That's the end of this rather long blog post.
And now ... back to work !

Relevant information.

  • tutor tomato :
    A simple glass material - video 1.
    Good looking glass material (without info) - video 2 (0:23).
  • Stanley :
    A simple glass material - video.
  • Godot engine tps-demo :
    Godot Shooter Demo : High Quality Version - Gamefromscratch : video
    Github project - tps demo.
  • vrayguide :
    UE4 ArchViz Glass Material - video.
  • SpeedTutor :
    Creating a Basic Glass Material in Unity - video.
  • Godot engine documentation : Spatial materials.
  • Godot engine documentation : lights and shadows.
  • Godot engine documentation : environment and post-processing.
  • Dave Wilson :
    Unreal 4 Creating simple God Rays (light shafts) - video.
  • John Hamilton :
    Moving texture - Godot Shader Tutorial - video.
  • Unreal Engine documentation - Using transparency :
    Some good, general info.