Long post so sorry and excuse my english if is not perfect :P
Hello! the last days I've been working on my own implementation of the HlmsPbs, with various changes/features that might be useful for someone.
Motivation: the current Pbs implementation made by matias (dark_sylinc) is awesome, but it has too much stuffs that we know never going to use, and lack some stuffs that we needed, first I tried to implement those stuffs only by modifying the shader templates, as you can see here http://www.ogre3d.org/forums/viewtopic. ... ic#p517921 and we were using specular workflow for our assets... then we realized that metallic workflow was easier and would help us to reduce video memory because it can be used with less textures =D! and we really needed to reduce memory usage
So I studied the current implementation and gained courage to modify it and extend it for real this time... and let me say it wasn't that hard and the Hlms is awesome and extremely powerful! thanks matias!!!
And I came with this implementation, that has a few...
Considerations:
-Its not heavily tested since we are not finished porting all our assets to metalness.
-I have not compared performance, it seems to be faster that the default, but I am not sure since we now have a cpu bottleneck in our engine xD.
-I removed a LOT of stuffs from the default, since we were not using it, we like KISS, this means is intended to our needs and workflow... but our workflow is not something super rare so it might work for you... in any case I might help you to restore things or implement new ones.
-I removed script things (to create materials from .material files) because we do all our stuffs by C++ code and I didn't care maintaining script stuffs :P
-Only OpenGL
Features:
-renamed pbS to pbR, because it seems to be more used xD.
-Standard Metallic workflow yay!:
-Adjusted selection of mipmaps of cubemap with the roughness to fit UE4 and Marmoset... looks reeeaally close this time
-Parallax Occlusion Mapping (no silhouette correction.. yet) here you can see with POM and without, mesh is a plane:
-Emit map, if you want things to glow (obiously doesnt emit actual light), and to glow you need tho have an HDR workspace with bloom post effect. In other words this map just let you have values over 1. color of the emission comes from the albedo:
-Ambien Occlusion map, this map should not affect metalic materials, since it suppose to occlude diffuse indirect lighting (and metals don't have diffuse), but we didn't like much this (mainly because of the lack of screen space reflections) so in this implementation it does affects metals xD (in any case I included the correct code commented out).
-It uses 3 main textures (+cubemap +4detailAlbedo +4detailNormal):
----Albedo texture: RGB for color, and A for opacity (optional)
----Normal texture: RGB for normal map, and A for height map to be used for Parallax Occlusion Mapping (optional)
----Reflectivity texture (alla UE4): R for roughness, G for metalness, B for AO, and A for emit (all optional, you can omit consideration of one channel if you want to use a value for the whole shader)
----All those textures are intended to be packed in the same "TextureMapType" with "hwGammaCorrection" on false!, since I needed to reduce video memory usage a lot, I just made the shader so every texture can be packed in the same arrays... all can be DXT1, but if you need alpha channel (for opacity, height or emit) DXT5, this reduced enormously video memory usage!! and if you need more quality you can save the texture as RGB8 anyways (remember DXT1 compress a lot, and normal maps looks ugly... but good enough for us)
-some optimizations for completely metal or dielectric materials (no metalness map used, and metalness value on 0 or 1) that I am not really sure if they really increase performance, but I figure that in many cases you will need something to be entirely dielectric or metallic, why not make a simpler shader for those cases.
-Cavity "map" that comes from the AO map (levels adjusted), this is not really accurate but good enough for us.
-"Translucency"... is not as fancy as it sounds, I just needed a way to control how the backfaces behave to light when there's no backface culling, so there's a translucency factor, that does this:
-Integrated unlit, but no fancy features like the default unlit, is just for when you want to see only the albedo color
-Linear Fog
-Still here: transparency modes and 4 detail maps
-I indented the templates so its easier to read, but the output shaders are more messy :P
Added march 6:
-Wind!!! it reads the R channel of vertex color for vertex displacement/animation using a tileable 3D noise texture (included) to simulate wind movement, no bones animation requiered, good for trees, flags, etc.
-Tiplanar mapping!! with correct normals! good for terrains. Tor now only works with albedo, normal, and details albedo/normal. To enable triplanar just use -1 as uv.
-Cubemap is now only one for everything, this is a downgrade for now, but I am working on have multiple reflection probe support.
-Clouds shadows! fake shadows to simulate clouds passing by.
-Fog color now comes from the cubemap.
The necessary files are attached
Usage:
-include the files
-register the implementation
Code: Select all
Ogre::ArchiveVec library;
Ogre::Archive *archiveLibrary = Ogre::ArchiveManager::getSingletonPtr()->load("./yourMedia/Hlms/Common/GLSL", "FileSystem", true );
library.push_back( archiveLibrary
Ogre::Archive *archivePBR = Ogre::ArchiveManager::getSingletonPtr()->load( "./yourMedia/Hlms/PBR/GLSL", "FileSystem", true );
hlmsPBR = OGRE_NEW yHlmsPBR( archivePBR, &library );
root->getHlmsManager()->registerHlms( hlmsPBR );
Code: Select all
Ogre::HlmsManager *hlmsManager = Ogre::Root::getSingletonPtr()->getHlmsManager();
Ogre::HlmsTextureManager *hlmsTextureManager = hlmsManager->getTextureManager();
Ogre::HlmsTextureManager::DefaultTextureParameters *deftexParams = hlmsTextureManager->getDefaultTextureParameters();
deftexParams[Ogre::HlmsTextureManager::TEXTURE_TYPE_DIFFUSE].hwGammaCorrection = false; //this needs to be false or it will look weird
Code: Select all
yHlmsPBRDatablock *datablock = static_cast<yHlmsPBRDatablock*>(hlmsPBR->createDatablock( materialName,
materialName,
Ogre::HlmsMacroblock(),
Ogre::HlmsBlendblock(),
Ogre::HlmsParamVec() ) );
Hlms/Common folder is the same as the default so I didn't attached it
One last thing is that I modified OgreHlmsTextureManager like I mentioned here: http://www.ogre3d.org/forums/viewtopic. ... 03#p518003
so you might want to remove "minLod" in every call of "createOrRetrieveTexture" on yHlmsPBRDatablock.cpp No longer applies
That's it, any question just ask
feel free to use, modify, distribute, eat, show it to your grandma, or do whatever you want with this code... but hopefully any improvement you can make share it here =D! (I am highly interested in runtime performance improvements)
And remember it hasn't been tested much :P
good luck!
EDIT:
Fixed: a problem with uv details, and a problem with lights and AO, and some other minor things
to do: multiple cubemaps! I need to have cubemap arrays working first
EDIT oct 18:
-some minor cleanup
-The shader now is using 2 separated colors for ambient light. Its using the upperHemisphere for "Diffuse Cubemap Scaling", so you can adjust Diffuse Ambient Light (Indirect) contribution. And the lowerHemisphere for "Specular Cubemap Scaling", so you can adjust or tint the reflections... with this you can for example tint your reflections blueish at night or at day you can make your diffuse ambient light darker without darkening your reflections.. etc. (this means "envmapScaling" and "hemisphereDir" of setAmbientLight is not beeing used)
EDIT march 6:
-Various bug fixes
-Wind!!! it reads the R channel of vertex color for vertex displacement/animation using a tileable 3D noise texture (included) to simulate wind movement, no bones animation requiered, good for trees, flags, etc.
-Tiplanar mapping!! with correct normals! good for terrains. Tor now only works with albedo, normal, and details albedo/normal. To enable triplanar just use -1 as uv.
-Cubemap is now only one for everything, this is a downgrade for now, but I am working on have multiple reflection probe support.
-Clouds shadows! fake shadows to simulate clouds passing by (texture included).
-Fog color now comes from the cubemap.
-That minLod thing no longer applies.
-and maybe I am missing something...
new link: https://www.dropbox.com/s/p68jyer78tpmeao/yPBR.zip?dl=0