MGE XE - Prototype
There is now an alpha of MGE XE with normal mapping and physically-based rendering (PBR) support at http://www.nexusmods.com/morrowind/mods/26348/.
PBR is an advancement in lighting and texturing that allows your computer to render a greater variety of more complex and beautiful materials. The physics allows them to be consistently interesting in all lighting conditions.
Examples: http://i.imgur.com/RKNnVBN.gif https://www.youtube.com/watch?v=fBZWejnkB04 (Credit: PeterBitt)
It does not perform as well as the current 0.9.10 beta, so I would not recommend it for normal gameplay. You can start with a https://dl.dropboxusercontent.com/u/99804385/morrowind/MGE%20XE%20PBR%20Example%20Crate.7z for object crate_01 (separate download as I lack permission for the base texture).
This thread is open to artists interested in making PBR materials and for testing and feedback on the prototype. It is nowhere near complete yet.
Usage
There are new lighting shaders which add normal mapping, PBR specular and other improvements. The renderer requires material text files to assign normals and other material data to textures. The lighting itself does work without normals, but is still experimental.
The PBR renderer is not activated by default. You must enable per-pixel lighting, and set the "Toggle lighing mode" macro to a key. Use the macro to advance the lighting features.
"Linear lighting" is where all lighting is modified to work correctly in linear space, which may alter light colouration in exchange for physical correctness where lights overlap, and better light falloff. "PBR rendering" is linear space + normals + specular + environment light.
Textures without an associated material will load a default rough material with a little specular, to test the new lighting system. You can use the "purgetextures" console command to reload all materials and associated textures (except the auto material).
Crate notes
This demonstrates the general ability of the new rendering system. It is about what I could make in one evening. To view, place a crate_01 in front of you, and move it up to head height. It is best viewed in clear weather and at various times of day.
Particular visual features:
- Normal mapping with specular (sun + 1 dynamic light for now).
- Different F0 reflectivity (non-glancing surface sheen or gloss) for wood, rust and metal rivets.
- Metallicity applied to make rivets have a coloured environment reflection. The colour is exaggerated for effect. Some improvement is possible.
- Grazing specular for both sky hemisphere and sunlight.
- Non-grazing specular reveals additional surface texture. Best seen when the sun is 15-45 degrees above the horizon. You may need to place multiple crates at different rotations to observe it easily.
Artists
The new material renderer is controlled by overriding game textures with generated materials. There is a material editor supplied at mge3/XEMaterialEditor.exe along with its readme. All material loading successes and failures will appear in mgeXE.log. Failures typically look like a flat shaded purple mesh.
The textures themselves follow a PBR workflow.
Articles on creating PBR textures:
http://www.marmoset.co/toolbag/learn/pbr-theory
http://www.katsbits.com/tutorials/textures/how-not-to-make-normal-maps-from-photos-or-images.php
https://www.fxguide.com/featured/game-environments-parta-remember-me-rendering/
http://www.marmoset.co/toolbag/learn/pbr-conversion
http://artisaverb.info/PBT.html
Videos:
https://www.youtube.com/watch?v=LNwMJeWFr0U
Extensive reading list:
https://interplayoflight.wordpress.com/2013/12/30/readings-on-physically-based-rendering/
It is very important to read the principles behind this rendering system. The articles will describe the terms and methods used to create new and interesting materials.
Authoring textures
First, you must be familiar with the different material inputs, which are explained in the PBR articles above. Every engine uses a slightly different materials setup, as textures have to be packed with as much information as possible. MGE XE uses albedo, roughness (not gloss/shininess), metallicity (not specular map), F0 (incident Fresnel reflectivity), and specular occlusion (aka cavity map). These terms should be easily researchable by looking up "PBR" + the term.
Here I give my own understandings on the input texture, in case it helps. Please give feedback for improvement.
Albedo
This is a diffuse map, but different. In PBR, the small scale shading is only done through normals and material settings. That means the albedo should not contain lighting information.
In an ideal albedo map you will not be able to see any directional lighting or painted reflections. Localized soft shadows (like ambient occlusion) in cracks and holes are totally fine though.
Normals
Specular reacts strongly to normals variation, and in combination with roughness produces most of the effect of surface texture, in all lighting conditions. Normals should contain surface detail at all scales. What do I mean by this? A high-quality baked normal map can produce curves, ridges and pores across a few flat-looking polygons. It can slightly angle different stones in a pathway, and pick out individual pebble.
An ideal normal map is baked from a high detail mesh, which need not be a million poly model. It could also be made of rough shapes with a displacement map applied. This is also where auto-generated normals are a total failure. A normal map filter only looks within a local window of a few pixels to generate normals, so it can only make small scale deatil. That is not enough for many objects.
Roughness
This is a property of the surface that allows the eye to determine micro-texture. It physically controls the angluar variation how light is reflected. Low values make the reflection bright and the highlight concentrated, high values spread the reflected light out, making it softer and the increases the highlight area. Small scale variations of roughness can imitate surface finish like polished or worn areas, wetness, oily stains, fresh paint or surface dust. It requires a reference image from the engine to judge the values correctly. In this engine, colours 0 (black) = smooth and 255 (white) = rough.
An ideal roughness map has a lot of detail where there are natural or organic materials. It gives the impression of micro-texture at a smaller scale than normal maps. This one you will have to research yourself.
Metallicity
This is a mask that switches the renderer to metal reflection physics. Metals physically are very reflective, but absorb all light that isn't reflected. They can also have strongly coloured reflections, while non-metals have very little coloured reflection. Where metallicity = colour 255 (white), the specular reflection is applied the albedo colour instead of F0, tinting the reflection. For non-metals you must use metallicity = colour 0 (black). The values in the middle of the range are only useful for near-metal materials, like oxidized metal, or metal with a thin layer of dust.
Fresnel reflectance F0
This is a physical property of the material, which is relatively constant over a material of the same type. You have to look up the correct value for your material in a reference, which may be found in one of the articles above. The default of F0 = 0.04 (color 60/255) normally works well until you find the real value. Note that I may change this channel in the future if there are precision issues or another parameter is required. Currently colour 0 (black) maps to F0 = 0 and colour 255 (white) maps to F0 = 0.2.
Specular occlusion
This is the specular version of an ambient occlusion (AO) map. It prevents specular reflections inside creases, holes and at the base of ridges. In all these cases a reflection would be blocked by a piece of the geometry or displacement height (for creases in normals) which is nearby. The renderer has to rely on this map to tell how much reflection would be blocked. In this map black is full occlusion, and white is un-occluded.
You can have this map produced by a normal map baker. If you only have an AO map, it can be approximated by using levels to double the brighteness of the AO map, keeping the same black point.
Resolution and compression
There's no requirement to make the material textures the same size as the albedo texture. If the parameters map has little fine detail, then a half size map will work fine. Parameters source files should be the same size as each other.
MGE XE specific explanation
When testing textures in-game, you can use the "purgetextures" console command to reload all materials and associated textures (except the auto material).
Examine the textures in the crate example, at material-sources/tx_wood_brown_box_01. I'm only a technical artist, so it's a medium quality result from a great base texture and a 15 minute baked normal map. In particular the rivet normals don't match the texture at all, and higher quality normals may improve it a lot.
The most interesting surface texture is contained in the roughness channel. It simulates variation in surface texture at about the same scale as the sense of touch, much smaller than a normal map texel. Not all parameters source textures are 100% required if the texture is a uniform type of material. The most important to produce is going to be roughness.
Other channels need less detail. You can start with only one value per visual material for metallicity and F0. The cavity map is quite important to prevent specular inside creases, pits and overhangs. It can be produced by using levels on the albedo map, or directly if you are baking normals.
F0 is reflectance at a facing angle (0 degrees). This is a physical property that can be researched for each material. The reflectance source texture is sRGB encoded. That means the typical non-metal range of 0.02-0.08 becomes colour value 40-90. Higher values just lead to a washed out appearance as environment light is just being reflected back at you.
Note that alphas do not work very well with specular, until I work on the transmissivity vs reflection part of the renderer. In particular, alphas using z-buffer read only will not use the PBR renderer, because it is hard to detect if it is not a particle or visual effect.
Technical
Technically the PBR beta implements:
- Tangent-space normal reconstruction and normal mapping
- Cook-Torrance BRDF using GGX and height-correlated Smith
- Simple anolytic sky hemisphere environment
- Matching PBR parameters and source textures to Gamebryo engine textures
- Automatic scaling of light intensity towards physical lighting values
- Configurable material specification files
PBR advances three parts of rendering: lighting, materials and imaging. While I rely on you all to make great materials, the lighting in Morrowind is tuned for a simpler era. Trying to use it in a PBR render seriously alters global colouration. That means automatic recalibration of all lighting (and proxies like vertex colours) is required. It is currently imperfect for coloured lights, but will be improved.
e.g. with simple lighting:
a point light fsRGB + an ambient light gsRGB = (fsRGB+gsRGB)sRGB where N.L = 1 and gsRGB where N.L = 0
to get a colour match with linear lighting:
flinear = sRGBtoLinear(fsRGB+gsRGB) - glinear, glinear = sRGBtoLinear(gsRGB)
a point light flinear + an ambient light glinear = sRGBtoLinear(fsRGB+gsRGB) where N.L = 1 and sRGBtoLinear(gsRGB) where N.L = 0
which resolves into the desired values on conversion back to sRGB.
Issues
Note that only sunlight + 1 point light creates specular at the moment. Cook-Torrance with 8 lights is very expensive, and no curent professional engine actually tries to do more than 2-4 dynamic lights. Unfortunately Morrowind is all dynamic lights, everywhere. I'm looking into rendering specular for the two most important lights if it's possible to determine.
Shadow rendering is decoupled from the PBR rendering still, so specular is not correctly occluded fully. Correct rendering would require adding shadow code to all materials instead of rendering it later. Rendering shadows in a separate pass takes advantage of early Z rejection to reduce overdraw, which would also be lost.
There are no light probes, so IBL becomes very difficult. There is currently an integrated sky hemisphere instead. It actually makes the sky colour in interiors important, which should get fixed. I hope to get a dynamic cubemap working.
There may be minor problems rendering multi-texture blending correctly, e.g. land tiles, because of the complexity of blending two materials.
The material loading is logged in mgeXE.log, so you can see if your texture is detected with a line "-- Loading PBR material
Linear / PBR lighting disabled on non-zwrite alphas. There's a very big difference when the pixel shader is linear but the alpha blending with the frame buffer isn't. There was also an issue where the standard sunflare texture was using PBR lighting.