-
Notifications
You must be signed in to change notification settings - Fork 6
True PBR
About True PBR
PBR (physically based rendering) approximates how real materials react to light and is used in most modern games. True PBR is a (work in progress) part of Community Shaders that allows the usage of metallic workflow PBR materials in Skyrim. The biggest upside to using PBR materials is the available tooling and workflow for texture creation. Most modelling and texturing tools also use a PBR workflow, and therefore what you create in e.g. Blender will look the same way in Skyrim; there is no need for experimenting to make your textures as bright as vanilla, or for messing with env masks to try replicating a metallic look. Additionally, there are many free PBR materials available online, and it is easy to mix and modify them while retaining realistic and consistent visuals.
The base textures for True PBR are albedo, normal, roughness, metallic, ambient occlusion and specular. Parallax and emission are also supported. Additionally the material can use two-sided foliage or subsurface shading, which require subsurface color map.
True PBR only cares about meshes marked with a specific flag, everything else is rendered as usual. True PBR mods therefore contain meshes marked for PBR and a set of PBR textures.
Frequently Asked Questions
- Do I care about this as a user? No, it just works. There may be some settings in the CS menu that you can customize. If a mod doesn't come with its own meshes or you have custom meshes that you want to apply the textures to, you might want to use the PBR Mesh Patcher.
- Do I care about this as a modder? If you create custom meshes or textures, you might want to switch over to True PBR. The upside is easier workflow and potentially better quality. The downside is that your creations will only work with Community Shaders (it is possible methods of fallback will be available though).
- What about Complex Materials? Complex materials are totally separate from True PBR and there would be no point in combining them. You can still use complex materials on non-pbr objects as usual.
- Can I convert vanilla shaded textures to True PBR? If you originally had PBR textures that you somehow converted for Skyrim, you can use those easily. Otherwise it is impossible to do without assumptions, because Skyrim textures contain fundamentally different data. For example, many objects using enviornment mapping are metallic, but not all of them. You can do manual work or use some AI to make the necessary textures, but it is unlikely that it will be a meaningful visual improvement over vanilla.
- My materials ingame look wrong? There is many possibilities for this, I will list the common ones. If the material is really shiny, the mesh probably isn't marked for PBR, so is vanilla shaded with specularity 1. If the material is too dark in the shadows, you might have too dark ambient occlusion. If the material gets black when you walk to it with a torch, your normal maps might be wrong - either flipped, or wrong format (opengl).
Reference - Everything you need to know
Shader implements roughness-metallic workflow closely following Unreal. In base version it requires base color, opacity, normal, roughness, metalness, AO and nonmetal reflectance (specular in Unreal) to be provided. Additionally it supports emission if emissive color map is provided and parallax occlusion mapping if displacement map is provided. Two additional shading models are implemented (also following Unreal):
Two-sided foliage which simulates transmission of light through foliage. Requires subsurface color to be provided.- Subsurface which approximates subsurface scattering with provided subsurface color and opacity.
- Multilayer Parallax which approximates a semitransparent surface above a hard surface.
- Base color in RGB, opacity in A.
- Normal in RGB, A unused.
- OPTIONAL Emissive color in RGB, A unused.
- OPTIONAL Displacement in R, GBA unused.
- Unused.
- RMAOS - Roughness in R, metallic in G, AO in B, specular in A.
- OPTIONAL Multilayer normal in RGB, roughness in A.
- OPTIONAL Subsurface color in RGB, subsurface opacity in A. Multilayer coat color in RGB, opacity/strength in A.
Color maps are assumed to be in SRGB format. If the actual colors are sRGB (gamma in Mixer), use sRGB flagged dds. If the actual colors are linear, use linear dds.
Three flags of BSShaderProperty are replaced:
- Byte 55 (Unused01 in NifSkope) - enables PBR for this BSGeometry
Byte 57 (Soft_Lighting in NifSkope) - enables two-sided foliage shading- Byte 58 (Rim_Lighting in Nifskope) - enables subsurface shading in NifSkope
Some parameters of BSShaderProperty are reused:
- Specular Level (replaces Glossiness) - linear multiplier for nonmetal reflectance. Should be 0.04 for meshes which do not have specular map (and have 1 in alpha of RMAOS map) or 0.08 for meshes which have specular map created for Unreal.
- Subsurface Color (replaces Specular Color) - used in Two-Sided Foliage and Subsurface models. If subsurface map is provided it's used as linear multiplier for its RGB.
- Roughness Scale (replaces Specular Strength) - linear multiplier for roughness.
- Subsurface Opacity (replaces Lighting Effect 1) - used in Subsurface model. If subsurface map is provided it's used as linear multiplier for its alpha. Higher opacity makes the effect weaker - lower opacity allows more light through the surface.
- Displacement Scale (replaces Lighting Effect 2) - linear multiplier for displacement.
Enabled by: MultilayerParallax flag + MultilayerParallax shader type
Base parameters:
- Coat strength - strength of coat layer contribution from 0 to 1. Equals to subsurface opacity field * alpha of slot 8 texture (if present)
- Coat roughness - roughness of coat layer. Equals to parallax inner layer thickness * alpha of slot 7 texture (if present)
- Coat specular level - reflectance of coat layer. Equals to parallax refraction scale (just set to 0.04)
Three more flags are used:
- EffectLighting - enables diffuse contribution. Color of top layer is then taken from specular color field * rgb of slot 8 texture (if present)
- SoftLighting - enables interlayer parallax. I.e. with it enabled displacement works as displacement between upper and lower layer to simulate vanilla multilayer parallax
- BackLighting - enables own normal map for coat layer. It's then taken from rgb of slot 7 texture
Landscape texture is assumed to be PBR if a json file with the same name as the texture set record's EDID is found in 'data\PBRTextureSets'. For 'LandscapeDirt02 [TXST:00000C0F]' it would be 'LandscapeDirt02.json' The texture paths are defined in the texture set record:
- TX00: 'PBR\Landscape\Dirt02.dds' Base color in RGB (assumed to be in SRGB format), transparency in A.
- TX01: 'PBR\Landscape\Dirt02_n.dds' Normal in RGB, A unused.
- TX02: 'PBR\Landscape\Dirt02_rmaos.dds' RMAOS - Roughness in R, metallic in G, AO in B, specular in A.
- TX03: 'PBR\Landscape\Dirt02_g.dds' Glow in RGB, A unused. (assumed to be in SRGB format) (unused for landscape)
- TX04: 'PBR\Landscape\Dirt02_p.dds' Displacement in R, GBA unused. (use a greyscale image and save as BC4)
- TX05: Unused
- TX06: 'PBR\Landscape\Dirt02_crn.dds' Coat normal in RGB, coat roughness in A. (only used for multilayer parallax - not used for landscape)
- TX07: 'PBR\Landscape\Dirt02_s.dds' Subsurface colour in RGB, subsurface opacity in A (assumed to be in SRGB format); OR coat colour in RBG, coat strength in A (assumed to be in SRGB format) (both unused for landscape)
Usually, your record will look like this for landscape:
- TX00: 'PBR\Landscape\Dirt02.dds'
- TX01: 'PBR\Landscape\Dirt02_n.dds'
- TX02: 'PBR\Landscape\Dirt02_rmaos.dds'
- TX03: -
- TX04: 'PBR\Landscape\Dirt02_p.dds'
The json file contains the values that are normally defined in the mesh:
{
'"roughnessScale" : 1.0,'
'"displacementScale" : 0.25,'
'"specularLevel" : 0.04,'
'"subsurfaceColor" : [1.0, 1.0, 1.0],' (currently unused)
'"subsurfaceOpacity" : "0.1"' (currently unused)
}
You can tweak the values to your needs, but be aware that landscape textures get also applied to a lot of meshes via texture set swaps - dirtcliffs, for example. In those cases, the settings in the mesh are used (and it also needs to be set up for PBR). But because many different textures are used on these meshes, your landscape textures should use similar values for parallax scale for your landscape textures. A texture that's made for a scale of 0.1 being applied to a mesh with a scale of 0.25 will have much stronger parallax than you intended.
If any of the textures in a quad is PBR, then the entire quad is rendered as PBR. So in order to avoid issues with blending between PBR and non-PBR textures, all landscape textures in a worldspace need to be converted to PBR together. That is to be okay since mods replacing land textures usually replace them all. Also, landscape LOD will not be rendered as PBR (blends together in the distance).
Preparing Meshes
For a mesh to be recognized as PBR, it must have in BSLightingShaderProperty:
- Default shader type
- In Shader Flags 2 have Unused01 (or PBR) flag set
For texture slot setup and additional settings scroll down to Reference.
To set up PBR meshes in batch, you can use PbrNifPatcher. It is useful especially when remaking vanilla textures that are used in many meshes.
To get descriptions for PBR properties and correct rendering of PBR in Nifscope, add these files into your Nifscope folder: TODO insert link
Texture Creation Workflow
Many programs can be used to work with PBR textures. To generate textures from scratch, you can use for example Substance Designer or Material Maker (free). To edit, mix and apply materials to meshes, you can use Quixel Mixer (free), ArmorPaint (free) or Substance Painter. In this short guide I will show the workflow I use to retexture vanilla meshes.
- When installing, you can select the sample packs, which contain textures you can freely use. Do NOT select the Unlimited Megascans option - it is only free if your end product is in Unreal Engine. Though do inform yourself, I am not a lawyer.
- Get some free PBR textures for example from polyhaven.com or ambientcg.com, or make your own. Import them using Library -> Import Custom Asset.
- Make sure to fill out the correct albedo - one is for specular and one for metalness workflow. Most available textures use metalness workflow.
- Make sure to use the correct normal map - Mixer uses the OpenGL variant. If you use the DirectX variant, normals may look wrong in Mixer.
- You can add texture names to autofil in Edit -> Configure Autoload Map Names
- Edit and mix textures however you want. Mixer has official tutorials on Youtube.
- Export the PBR textures. You can create a preset that exports according to your needs.
- Pick image format according to preference. I use PNG.
- I usually export albedo, RMAOS, normal, and displacement textures.
- Take note if you export albedo in Gamma or Linear space. This will be important later.
- You can directly export a RMAOS (roughness, metallic, ambient occlusion, specular) texture. In most cases you won't need specular and can save as RGB.
- If you indeed worked with opengl normal maps, set Normal Y (green channel) to be inverted. This transforms it into DirectX format which Skyrim uses.
- Use another program to convert the exported files to DDS format. This is the node setup to do it in Chainner (TODO link):
- Add a Directory node for selection of the exported textures directory
- Add Load Images nodes for each of your texture types, use expressions to select the file based on suffix set in Mixer, normal could be *_n.png
- Add Save Image node for each of your texture types, pick DDS format and pick a fitting compression based on the next chapter (About Texture Compression)
- If you exported your albedo as Gamma, you need to select compression with sRGB, if you exported Linear, select linear. Other textures than albedo should be always linear.
- Optionally add Resize nodes or similar to downscale or edit your textures before saving.
About Texture Compression
There is a number of compression format for DDS textures with various properties such as number of channels, quality and file size. Not all of them are supported by Skyrim. The following list should be sufficient in most situations:- BC1: RGB + 1bit alpha (fully opaque or fully transparent). It has reasonable file size and quality. Use for opaque or cutout albedo textures, and RMAOS textures if you don't need specular. In case of visible banding or squarish artifacts, use BC7.
- BC4: One channel (grayscale). Has the same file size as BC1, but only one channel with better quality. Use for parallax textures.
- BC7: RGBA. Has good quality and twice the file size of BC1. Use for normal maps and albedo with full transparency.
- BC3: RGBA. The RGB part uses BC1, alpha uses BC4. The file size is the same as BC7. This can be useful when you need to preserve a quality alpha channel, for example in complex materials or landscape textures with parallax in alpha channel.
For more details I recommend this article.
Linear vs sRGB because it bears repeating
- You can find discussions online about linear, sRGB, non-color data etc. The details are above my paygrade, here we just hope that stuff works.
- Extremely simplified: Math is easier with linear data, but using sRGB files allows them to store more detail human eyes can actually see (this only makes sense for colors).
- All non-color data such as normals or roughness should be flagged as linear when saving to dds.
- Color data is more complicated - you need to know whether the data (the colors) itself is in sRGB or linear space. AFAIK, albedo/diffuse textures from sites like polyhaven are in sRGB and it is more common on general. If this is the case, you should use the sRGB flag when saving to dds. The flag will allow to the texture to be converted to linear automatically on the gpu. If your data (the colors) is already in linear space, use the linear flag when saving to dds. As you can imagine, if you use the wrong flag, the texture will either be superfluously transformed to linear or not transformed when it should be, which will cause the texture to look wrong.
- BUT WAIT! That applies to True PBR. If you are making textures for vanilla Skyrim... make sure your data is sRGB and use the linear flag. WHAT? Skyrim uses linear-flagged dds that actually contain sRGB data. I'm not sure if they convert the colors to linear manually in shaders or just calculate lighting in sRGB space. So yes, it is weird but it works this way (blame Bethesda).