Fog? Height Fog? Transparent textures? There are many ways to achieve the same effect, but sometimes the answer is 'none of the above'.
Every once in a while, someone in the Hubs community asks a question about how they can make something look like it fades away at the edges. This is usually an attempt to avoid having objects in their scene that abruptly end or otherwise appear unfinished at the edges. At first, this seems like a relatively easy thing to accomplish. But because this effect is something you usually want happening across the entirety of an object–not just part of a texture–it can be a little tricky to wrap your mind around.
Fortunately, all of the ingredients for this effect are readily available and already supported by Hubs. For a while, there was a missing ingredient in Blender: support for vertex alpha (transparency). Fortunately, this was added several Blender versions ago, but getting it to work is still a little bit of a hidden trick.
For this example, I’ve set up a common scenario. I have a platform with some supporting columns below it. I would like those supporting columns to fade away to nothing as they descend into the empty space below.
Usually, the first thing to try is adding some sort of transparency to the material itself. However, this is somewhat inefficient since I’d like the entire mesh to fade away. So if, for example, my support legs had multiple textures on them like algae or barnacles, I would also want those parts to fade away. So that would require a lot of material editing and custom work for each material. I don’t have that kind of time for something that’s mostly a cosmetic effect. Besides, I’ll likely have to iterate on this quite a bit–testing different transparency amounts and distances–so having to edit multiple materials and textures would get very annoying very quickly. Last, this model isn't set up to have a texture stretch across the entire height since it's using a simple tiling wood texture. So what's the best way to deal with this situation?
Vertex Color: What’s Old is New Again
In addition to storing material and texture parameters, the glTF (and .glb) file format supports vertex colors. If you’re not familiar with this concept, the basic idea is that the vertices of the mesh itself can store color values that will be multiplied on top of any texture(s) you may be using.
Vertex colors are a somewhat old construct, used a lot in older video games where texture memory was extremely limited. But don't let that fool you-- there are actually quite a few clever things you can use them for. If you want to see how older games used vertex colors and other ingenious tricks to make level art, I highly recommend visiting noclip.website to see some incredible examples. It’s not always immediately obvious how things work but you can dissect them pretty well.
The above example is pretty close to what we’re trying to achieve. Except we’ll be using alpha (transparency) of the vertices to do it.
Let’s Paint those Verts
To paint vertex color information, we first need to have our model selected. Then we’ll change modes using the dropdown menu at the top of a 3d View.
You’ll also want to open up the side (n) panel so you can see the ‘Tool’ tab. Depending on your resolution and text scaling in Blender, the tab’s text may be partially obscured.
The last thing to make sure of is that your Viewport Shading is set to Solid mode. Without this toggled, you will not be able to see the colors you’re painting. With this set, upon selecting a color and painting on the model, you’ll see it working.
If our plan was to have a plain color background, like black, we could simply color the bottom-most vertices black. This would give a very similar effect to the Noclip game example shown earlier. However, since we may want to use a skybox or other background image, it would be better to have some flexibility.
Vertex ALPHA: The lesser-known part of vertex color
Each vertex can store 4 channels of information, just like many image formats do. These channels are Red, Green, Blue, and Alpha. When you paint normally, the Alpha channel is mostly ignored and stays fully white (opaque).
But by switching the ‘Blend’ mode in the painting tool to ‘Erase Alpha’, we are able to paint that alpha information directly.
BUT WAIT! We won’t be able to see it properly without adjusting the material first!!!
Let’s take a small detour here to open up the object’s material in the Shader Editor.
In order to actually see the transparency as we paint, we need to add a node called ‘Color Attribute’. In its dropdown, we’ll select the item called ‘Col’ (the default vertex color channel that gets created when you paint.). Then, we plug that node’s ‘Alpha’ output into the ‘Alpha’ input of the ‘Principled BSDF’ node.
The last step, (and the one I almost always forget–including while writing this), is to set the material to use ‘Alpha Blend’ transparency. Without it, the object will only show your changes as plain color.
Since this is part of the material now, we need to switch our 3d View to use ‘Material Preview’ mode. Otherwise, you won’t see your paint strokes at all.
Switch the Blend mode to ‘Erase Alpha’, then paint over the vertices that should be transparent. Remember, you don’t have to use just black (invisible) or white (opaque)-- you can use any value in between for partial transparency.
This works great in my example because my support columns only have vertices at the very top and very bottom. So the color fades from top to bottom smoothly. If you are dealing with mesh that has more vertices, you’ll have to compensate for that extra resolution.
When you are ready to export, you need to have ‘Vertex Colors’ checked in the glTF/glb export settings. This is on by default, so that makes things simple.
Check it Out in Hubs
Once our scene is loaded up in Hubs, we can check to see if it’s working as expected. I chose a plain blue background to make the transparency more obvious.
We quickly see that although the support columns are, in fact, fading out as they descend, they are also being drawn on top of the platform, depending on our viewing angle. In this case, it’s happening because the renderer doesn’t understand that only the support columns should have actual transparency. This will require having two materials: one with--and one without--Alpha Blend transparency.
Fortunately in Blender, it’s very easy to assign a different material to the top platform.
I just need to assign this new material to the platform part of the object...
After re-exporting and uploading to Hubs, we can finally see everything working–even when we use a 360-panorama image as a background:
If you’re wondering if you can use environmental fog as a way to achieve similar results, you’d be correct. However, fog is made to become opaque with distance from the camera, nothing else. So trying to achieve this sort of ‘height fog’ look isn’t quite as easy to do without tricks like using vertex alpha.
If your scene already contains lots of alpha blend transparency, you may find you have to make more adjustments to materials and what they’re assigned to in order to avoid sorting problems. Not impossible, but definitely something to factor into your workflow.
I’ve seen this technique used to add additional dark areas to simulate contact shadows to great effect. I’ve also seen multiple textures blended together using vertex alpha. I’m sure someone reading this will come up with something cool to demonstrate. As always, please visit our #show-and-tell channel on the Hubs Discord and share your wizardry with the community.