Skip to content
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

Expose shadow texture size for directional lighting in SDF #1034

Merged
merged 15 commits into from
Aug 16, 2024

Conversation

athenaz2
Copy link
Contributor

@athenaz2 athenaz2 commented Aug 12, 2024

🎉 New feature

Summary

Shadows appear jagged in some scenes. It would be nice for them to look smoother and sharper. Investigated increasing shadow texture size - it seems that as long as there isn't too many lights, it does not have a significant impact on VRAM.

Thus, added ability to set shadow texture size (currently, only for directional lights) within the MinimalScene plugin, and for Ogre2. The default shadow texture size is 2K, but setting it to a higher value (4K, 8K, etc.) allows for sharper shadows.

Currently supporting 1K, 2K, 4K, 8K, and 16K. So in SDF file, the respective values 1024, 2048, 4096, 8192, and 16384. In the future, can look to enable setting shadow texture size for other light types (spot, point lights).

Also, if using OpenGL, ensured that max shadow texture size can use GL_MAX_TEXTURE_SIZE instead of hardcoding it to 8K.

Depot scene from Edifice demo (SDF attached below). Note that scene has 1 directional light (darker shadow) and 1 point light (lighter shadow).

Shadow texture size of 2K for directional light
depot 2k

Shadow texture size of 16K for directional light
depot 16k

Test it

depot_twolights.sdf.txt
shapes.sdf.txt

Modify the param in the SDF.

<shadows>
  <texture_size light_type="directional">8192</texture_size>
</shadows>

Checklist

  • Signed all commits for DCO
  • Added tests
  • Added example and/or tutorial
  • Updated documentation (as needed)
  • Updated migration guide (as needed)
  • Consider updating Python bindings (if the library has them)
  • codecheck passed (See contributing)
  • All tests passed (See test coverage)
  • While waiting for a review on your PR, please help review another open pull request to support the maintainers

Note to maintainers: Remember to use Squash-Merge and edit the commit message to match the pull request summary while retaining Signed-off-by messages.

@athenaz2 athenaz2 requested a review from iche033 as a code owner August 12, 2024 23:03
@github-actions github-actions bot added the 🎵 harmonic Gazebo Harmonic label Aug 12, 2024
@athenaz2
Copy link
Contributor Author

Shapes demo (only 1 directional light).

Shadow texture size of 2K for directional light
shapes 2k

Shadow texture size of 8K for directional light
shapes 8k

@@ -15,6 +15,8 @@
*
*/

#include <GL/gl.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you'll need to use ifdef here as the file path is different on different platforms, see

#ifdef __APPLE__
#define GL_SILENCE_DEPRECATION
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#else
#ifndef _WIN32
#include <GL/gl.h>
#endif
#endif

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added it here - 3b1bc7a

include/gz/rendering/Light.hh Outdated Show resolved Hide resolved
unsigned int _textureSize) = 0;

/// @brief \brief Get the shadow texture size for the given light type.
/// @param _lightType Light type that creates the shadow
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: replace @ with \ for consistency with other doxygen comments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (_lightType == LightType::LT_DIRECTIONAL)
{
this->dataPtr->dirTexSize = _textureSize;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this block to the top of the function so that we just return early if it's not a supported light type. Also add an else block with gzwarn msg if user specifies spot or point lights.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3b1bc7a. I also have a check for it in MinimalScene too

unsigned int Ogre2Scene::ShadowTextureSize(LightType _lightType) const
{
// todo: return based on light type, currently only dir light is supported
if (_lightType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can also make spotPointTexSize a member variable so that you can support returning point and spot light shadow texture size here. The user just won't be able to set them yet.

then you can use switch to check _lightType and return the corresponding texture size.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//////////////////////////////////////////////////
unsigned int BaseScene::ShadowTextureSize(LightType _lightType) const
{
return this->ShadowTextureSize(_lightType);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can just print an error here:

    gzerr << "Shadow texture size not supported by: "
           << this->Engine()->Name() << std::endl;

ogre2 implements this function so the user should not see the error msg since it should call the ShadowTextureSize from the derived class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsigned int _textureSize)
{
// If _textureSize exceeds max possible tex size, then use default
if (_textureSize > this->dataPtr->maxTexSize / 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just checking, what's the reason for the divide by 2?

Copy link
Contributor Author

@athenaz2 athenaz2 Aug 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My maxTexSize is 32K, and I allow texsizes (that are pow of 2 vals) up to 16K. If I set _textureSize to 32K this happens:
depot what happen if go above 16k
The pitch-black shadow here is from the point light. Compared to the images attached to original PR post, the shadow created by directional light is gone. I think this is maybe because the math on atlasResolution went crazy. (doesn't fit within atlas?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I tested with 16K max tex size as that's what my machine supports and it works fine. So how about instead of dividing by 2, we set a hard cap on the max tex size to 16K? I remembered and found this comment mentioning the 16K texture size cap as well.

You can do this above when setting this->dataPtr->maxTexSize, e.g.

this->dataPtr->maxTexSize = std::min(glMaxTexSize, 16384u)

and add a todo note mentioning that there are issues with dir shadows when setting to a number larger than 16K.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capped maxTexSize to 16K in ddde4d9, added TODO comment in a8a3b65

bool validTexSize = std::find(texSizeOptions.begin(),
texSizeOptions.end(), _textureSize)
!= texSizeOptions.end() ? true : false;
if (!validTexSize)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of generating a list of possible tex size options, I think you can simplify this check to

if (_textureSize >= 1024u && math::isPowerOfTwo(_textureSize)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this is a good idea. 3b1bc7a

@iche033
Copy link
Contributor

iche033 commented Aug 13, 2024

you'll need to retarget this to main because the changes break ABI

@athenaz2 athenaz2 changed the base branch from gz-rendering8 to main August 13, 2024 16:47
unsigned int _textureSize)
{
// If _textureSize exceeds max possible tex size, then use default
if (_textureSize > this->dataPtr->maxTexSize / 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I tested with 16K max tex size as that's what my machine supports and it works fine. So how about instead of dividing by 2, we set a hard cap on the max tex size to 16K? I remembered and found this comment mentioning the 16K texture size cap as well.

You can do this above when setting this->dataPtr->maxTexSize, e.g.

this->dataPtr->maxTexSize = std::min(glMaxTexSize, 16384u)

and add a todo note mentioning that there are issues with dir shadows when setting to a number larger than 16K.

ogre2/src/Ogre2Scene.cc Outdated Show resolved Hide resolved
enum class GZ_RENDERING_VISIBLE LightType
{
/// \brief No light type specified
EMPTY = 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was there an issue with what you had before, LT_EMPTY?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing LightType to enum class ensures any usage of it is like rendering::LightType::DIRECTIONAL (or other light type values) as opposed to rendering::LT_DIRECTIONAL, so no need for LT_ in the naming anymore.

}

// if _textureSize is an invalid texture size, then use default
if (_textureSize < 1024u || _textureSize > (this->dataPtr->maxTexSize / 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be fine to set the lower limit to 512?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

athenaz2 and others added 12 commits August 15, 2024 14:49
Signed-off-by: Athena Z <[email protected]>
…exSize can use GL_MAX_TEXTURE_SIZE instead of currently hardcoded val

Signed-off-by: Athena Z <[email protected]>
Signed-off-by: Athena Z <[email protected]>
Co-authored-by: Ian Chen <[email protected]>
Signed-off-by: Athena Z. <[email protected]>
Signed-off-by: Athena Z <[email protected]>
Co-authored-by: Ian Chen <[email protected]>
Signed-off-by: Athena Z. <[email protected]>
Signed-off-by: Athena Z <[email protected]>
Copy link

codecov bot commented Aug 15, 2024

Codecov Report

Attention: Patch coverage is 57.40741% with 23 lines in your changes missing coverage. Please review.

Project coverage is 75.63%. Comparing base (e187f52) to head (a8a3b65).
Report is 52 commits behind head on main.

Files Patch % Lines
ogre2/src/Ogre2Scene.cc 70.45% 13 Missing ⚠️
src/base/BaseScene.cc 0.00% 10 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1034      +/-   ##
==========================================
- Coverage   75.68%   75.63%   -0.06%     
==========================================
  Files         177      177              
  Lines       16959    16998      +39     
==========================================
+ Hits        12835    12856      +21     
- Misses       4124     4142      +18     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@iche033 iche033 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me!

@iche033 iche033 merged commit 8edd14f into gazebosim:main Aug 16, 2024
8 of 9 checks passed
@azeey azeey added beta Targeting beta release of upcoming collection 🏛️ ionic Gazebo Ionic and removed 🎵 harmonic Gazebo Harmonic labels Aug 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beta Targeting beta release of upcoming collection 🏛️ ionic Gazebo Ionic
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants