Physically Based Rendering - Changes in Pipeline
Changing To Physically Based MaterialsNow that we have physically based rendering in place, as discussed in my previous post, we need to make some changes in our material pipeline. It's nothing crazy, but it's worth talking about because it changes up how artists control the look of their materials.
Until PBR came along, the common convention for material detail was (and in many engines still is) using diffuse, normal, and specular textures. There are plenty of other textures that can be used, but these are commonplace for controlling how things are lit. As you may have noticed, we've now removed the need for a specular texture, at least with my setup. We calculate the specular factor ourselves based on the roughness and metallic factors that we pass in, so we don't need the texture anymore.
What we do need now is a roughness/metallic texture that controls which parts of the character have varying degrees of smoothness, and which parts are metallic. Up until now (as seen in the videos of my PBR tutorial), we've only had 0.0-1.0 values for roughness and metallic. That isn't exactly ideal for something like the mage character I use, because he needs metal armor pieces and smooth leather gloves, as well as rough cloth for his clothes.
In my engine, what I've done is replace my specular texture input with my roughness/metal texture input, and in my gbuffer pass, I use what used to be my specular render target as a roughness/metal render target. This is where we notice another added benefit of PBR - we've replaced an RGBA value (specular color rgb, and specular power in the alpha channel) with just an RG pair for roughness and metallic. That means we now have an extra two channels to store data in our gbuffer pass! Or depending on your set up, this could potentially mean you can eliminate an extra target by storing these two values in channels of other targets. Either way, this is a big win that we can get excited about.
I store roughness in the R-channel of the texture, and metallic in the G-channel. Metallic is pretty simple, for me it's just a black/white channel (0 or 255) where my metallic parts are white and everything else is 0. Roughness is pretty much just as simple, except it's a range between 0-1 (or rather 0-255) where 255 is very rough and 0 is very smooth. I haven't done this yet, but since this is a variable that has huge visual variance, it may be beneficial to add a roughness multiplier variable so that you can scale the entire texture's roughness values at once in order to get the variance looking the way you want it to.
Here's an example of what one of these textures might look like. To the left is the diffuse texture, for reference, and to the right is the roughness/metal texture. It's just an example, but you can see where some parts are darker and lighter red for the roughness variance, and the light green that we get from the metal channel being enabled (255 green) and a mostly smooth in the roughness channel (55 red). Obviously you can get into a lot more detail with the roughness variable to make it look better, but since I'm not an artist and this is just an example that someone was nice enough to give me, this is as far as this one is going for now. However, you can already see how the quality of the character has improved:
That's it for now! Hopefully in the future I can get a bunch of different models together to create a nice looking scene that takes full advantage of our new lighting system, but this should give you a good idea of where we can go with it.