-
Notifications
You must be signed in to change notification settings - Fork 432
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
--PBR/IBL Configuration and customization #2155
Conversation
64f7a18
to
5cba1d5
Compare
7ea2f72
to
5189535
Compare
* This class will hold configuration values and utilities for Drawables and the | ||
* shaders that they own. | ||
*/ | ||
class DrawableConfiguration { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was made a class and not a struct because I foresee functionality being added/moved from RM in the future. I am not, however, against making it a struct if it is felt that that is more appropriate.
Due to the size of this PR it may make sense to break it into smaller PRs. Open to suggestions here as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good progress! I left some comments.
@@ -0,0 1,22 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we've had a problem in the past with data files in this folder in the repo, because folks who install via conda won't get this. E.g. they don't get data/default.physics_config.json
, so we made sure that the defaults in that file were also the defaults for the class in code.
What will be the process for a Hab-lab user to utilize these PBR options? It would be nice if we had a tutorial or example project that showed users where to put this file and how to reference it (doesn't have to be part of this PR).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was unaware of this :
E.g. they don't get data/default.physics_config.json
I will make sure that the defaults will match.
The primary mechanism to start will be to modify json configs or directly modify/create shader configs using a similar mechanism to the current attributes. And yes, I completely agree about a tutorial, that is my primary concern now.
// TODO: | ||
// should work with the scene instance config, initialize | ||
// different PBR IBLs at different positions in the scene. | ||
std::shared_ptr<Mn::GL::Texture2D> ResourceManager::loadIBLImageIntoTexture( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we move this IBL stuff including loadAllIBLAssets
into a separate helper class? My motivations:
- we may want to re-use this logic with the upcoming batch renderer, which may not instantiate a ResourceManager.
- ResourceManager is already bloated with 3000 lines, so it's helpful for readability, etc. to isolate new code into separate files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree on both counts. Should I put the class in assets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I defer to you and others on the location.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am going to suggest we postpone this refactor (moving the IBL management code to an external class from RM) until I get the AO attributes/managers and HBAO functionality completed. As it is I think those two tasks should take most of August.
// desired configuration of the PBR shader. | ||
auto mapOfPbrConfigs = metadataMediator_->getAllPbrShaderConfigs(); | ||
|
||
// Only load if rendering is enabled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment doesn't seem to match the if (requiresTextures_) {
code. E.g. that flag will be false if you're doing depth-only rendering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I can modify it to be RGB rendering then.
src/esp/assets/ResourceManager.cpp
Outdated
<< helperKey << "`"; | ||
std::shared_ptr<Mn::GL::Texture2D> blutTexture = nullptr; | ||
std::shared_ptr<Mn::GL::Texture2D> envMapTexture = nullptr; | ||
if (pbrIBLHelpers_.count(helperKey) == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that loadAllIBLAssets
is called from Simulator::createSceneInstance, which is called from Simulator::reconfigure ... Are we generally loading these images whenever we reconfigure to a new scene, or just once at startup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just once per image - once they are loaded they will be retained unless RM is remade as well.
@@ -429,11 431,159 @@ void initAttributesBindings(py::module& m) { | |||
|
|||
// TODO : LightLayoutAttributes | |||
|
|||
// ==== PbrShaderAttributes ==== | |||
py::class_<PbrShaderAttributes, AbstractAttributes, PbrShaderAttributes::ptr>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious, for constructing PbrShaderAttributes, what's the purpose of having both python bindings and a codepath for constructing these from JSON? Are we just trying to give Hab-lab users the flexibility of two options for specifying PbrShaderAttributes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to give folks the ability to modify their own shader configurations, but I also want to have the ability to include these configurations in datasets (like we do with object, stage and scene instance attributes).
0013543
to
bc62d8e
Compare
want to preserve the flags when a material is only being modified so that a new shader is not inadvertently created. Material class ref removed since we're using the material cache instead.
…phong->PBR materials Equalizing brightness between PBR and Phong will now take place via PbrConfig settings.
migrating image load functionality out of this class.
pass a configuration structure to the drawables on creation that will be created beforehand and hold appropriate references to various configuration quantities based on the type of drawable.
PbrShaderAttributes needs to be governed by Scene datasets and MetadataMediator, and IBL status is based on config settings now.
--Remove old lythwood image --Add 4 new 1k hdr envmaps
bc62d8e
to
9fe790b
Compare
--also provide more expansive srgb <--> linear control --The default IBL image has also been changed to one that is not so gold/orange.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good so far! I did a first pass and left some minor comments. I'll have a look at the shader changes tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we store these images in an external repository, along with other assets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I didn't is that we've always included some default IBL assets as resources, and I wanted to provide a bit of a usable variety as compiled resources so folks didn't have to deal with downloading them.
src/esp/gfx/configure.h.cmake
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of this file?
--If a user modifies or adds a new PbrShaderConfig with new IBL assets, while RM exists without re-running sim::reconfigure and tries to instantiate an object using this new PbrShaderConfig, those new assets will not have been loaded yet. This change makes it so that if they haven't been, they will be loaded and cached.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks! Love that IBL is now default, visuals are improving greatly!
A couple of minor comments.
Dont' worry about the JS tests, we can follow up with a solution for that.
@@ -102,7 102,7 @@ void initSimBindings(py::module& m) { | |||
.def_readwrite( | |||
"pbr_image_based_lighting", | |||
&SimulatorConfiguration::pbrImageBasedLighting, | |||
R"(Whether or not to enable image based lighting in the PBR shader.)") | |||
R"(DEPRECATED : Use PbrShaderAttributes to specify whether IBL is enabled or disabled.)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can slate this for full removal in v0.3.0
Let's make a task to search for and remove any downstream uses of this flag in preperation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good idea.
src/esp/gfx/PbrIBLHelper.cpp
Outdated
// using the brdflut from here: | ||
// https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/screenshots/tex_brdflut.png | ||
|
||
// loadBrdfLookUpTable(blutImageData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reason to keep this around?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, oversight on my part. Thanks for finding it.
setTonemapExposure(4.5f); | ||
} | ||
|
||
setGamma({2.2f, 2.2f, 2.2f}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constants set empirically?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually that's a reference gamma value specified by IEC in the sRGB standard (kinda out of date - was supposed to model CRTs :D but still in use). It is specified as a uniform more as a kind of heavy handed brightness control, really, when using the sRGB mapping.
We could probably disable it. We are moving forward with a new web rendering solution using replay rendering instead of simulator rendering. |
Motivation and Context
This PR facilitates the consumption of image-based lighting in PBR-rendered objects and scenes, as well as introducing many customization capabilities for the PBR/IBL shader. These customizations are enabled through the use of a JSON configuration file, using the extension ".pbr_config.json", a default template of which is included in the PR. Among the customizations exposed in this PR are :
A DrawableConfiguration class is also added to serve as the carrier for the various values required by the drawables, including values that are used by one type (i.e. Phong) but not the other (i.e. PBR). This will also make adding, for example, skindata support to the PBR drawables more easily accomplished in the future.
Tests and Python bindings are also a part of this PR for both the PbrShaderAttributes and the PbrShaderAttributesManager. Documentation modifications/additions still WIP.
NOTE : To support some resource functionality requirements, the Corrade package was updated.
Here's a brief overview of how the new PBR/IBL shader support is accomplished :
The metadata setup
The config file format seen here describes the editable configuration values for the PBR shader, including IBL assets and configuration. This json file has the extension "pbr_config.json". These configs are referenced in a Scene Dataset config in the same way as stage and object attributes are (their tag is "pbr_ibl_configs"), and support all the same functionality except that they only allow .json file extensions. They are read into a PbrShaderAttributes object, managed by a PbrShaderAttributesManager. One manager exists for MetadataMediator, and is shared with all SceneDatasets that are loaded (much like PhysicsAttributesManager). Also like PhysicsAttributes, there is a system default PbrShaderAttributes config that is part of this PR, that will always be loaded and available as a fallback. Each Scene Instance specifies (or inherits) a "default_pbr_shader_config", which will be a handle to a PbrShaderAttributes already loaded, as well as an object, "pbr_shader_region_configs", which holds key-value pairs consisting of string ids (called 'regions') pointing to PbrShaderAttributes handles.
The processing
During the reconfigure process, right before we instantiate a stage, a call is made to ResourceManager::loadAllIBLAssets to query all the loaded PbrShaderAttributes in the current Scene Dataset(s), in order to load their requested IBL assets (BRDF lookup table image and Equirectangular Environment map) if they are not already loaded. Once each requested pair of assets are loaded into textures, these are sent to the PbrIBLHelper to derive the IrradianceMap and Prefiltered Environment Map Cubemap objects that will be used by the IBL functionality of the PBR shader. The PbrIBLHelper is in turn stored in a map in ResourceManager, keyed by the file names of the bLUT and the EnvMap. The biggest change from main for this functionality is that all the asset loading from disk/resource file is now happening in ResourceManager, once per asset, and all derived textures are being cached so if they get requested again they will not be reloaded/reprocessed. Also, multiple PbrIBLHelpers are now possible, describing different lighting configurations based on different environment maps. The appropriate PbrIBLHelper is still sent to the drawables, as before, but now as part of a DrawableConfiguration object.
The DrawableConfiguration class
This is currently just a carrier struct to hold the various assets we would like to send to the Drawables, regardless of their specific type (Phong or PBR, for instance). It holds constructs that are shared between the drawables, as well as constructs that are unique to one or the other (like the PbrIBLHelper and the PbrShaderAttributes that is pertinent for the PBR drawable, or the Skindata that is being used by the Phong drawable). It is the responsiblity of the consuming class to access what it does or does not properly use. Future support of PBR skin rendering will be facilitated by this structure.
The Drawable/Shader cpp and fragment shader code.
This process is much like the newly added material handling process - the config values are read from the attributes, flag values are set accordingly, and a small struct holding a few floating point values is instanced to hold uniform values. These values are then passed to the shader if appropriate based on flags settings during each draw. The shader class will specify which shader compiler directives to instantiate based on the flags settings as before, and also processes the various non-boolean values that are served to the fragment shader as uniforms. For it's part, the PBR fragment shader was largely already prepared for these changes.
This PR is considered a "breaking change" only because the IBL flag of SimulatorConfiguration is being deprecated and ignored. Any image-based lighting control for PBR drawables will come from PbrShaderAttributes control from here on.
How Has This Been Tested
All c and python tests pass. Potential problem with javascript test, which may require recapture of test image due to changes in the default Phong material colors.
Types of changes
Checklist