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

New shadow volumes based on internal scenes #312

Closed
wants to merge 18 commits into from

Conversation

and3md
Copy link
Contributor

@and3md and3md commented Jun 29, 2021

This PR adds new shadow volumes algorithms compatible wit OpenGL ES (works on mobile phones). Don't merge it now to master (a lot of code duplication for testing).

Current state

We have now four algorithms for testing:

  • old fixed OpenGL algorithm - set InternalUseOldShadowVolumes := true to use it
  • new internal scene based with GL_POLYGON_OFFSET_FILL - set InternalUseOldShadowVolumes and InternalShadowVolumesUseDepth to false
  • new internal scene based with DEPTH approach in cups (V1) - renders cups in OpaqueTrianglesEnd or TransparentTrianglesEnd (set InternalUseOldShadowVolumes and InternalShadowVolumesUseDepthV2 to false and InternalShadowVolumesUseDepth to true)
  • new internal scene based with DEPTH approach in cups (V2) - renders cups in one place - end of RenderSilhouetteShadowVolume (set InternalUseOldShadowVolumes to false and InternalShadowVolumesUseDepth and InternalShadowVolumesUseDepthV2 to true)

I think internal scene based with DEPTH approach in cups (V2) is the most promising.

Algorithms correctness

All algorithms works the same (shadows are the same), with our example models but test that please.

Speed

In base scenario internal scene based algorithm is slower than the old one. It can be faster when we set TCastleViewport.InternalShadowVolumeUpdateFactor to value bigger than 0 (0 = update every frame). What makes shadows are updated less frequently than every frame. New algorithm works faster on desktop when there are more objects and update factor > 0. On mobile rendering slows down the most.

I think old algorithm is faster because graphic card driver can buffer glVertex calls more efficiently (maybe in one VBO) than we switching our VBO it on every internal castle scene. Or maybe that's because we have two scenes per shape.

So we need find a way to speed up internal scenes or maybe we should make only two "global" internal scenes (or internal scenes per TCastleScene) not scenes for each shape.

So there are two things to optimize:

  1. Creating and updating internal scenes for shadow volumes - once we have internal scenes we can update shadows less frequently
  2. Internal scenes rendering - we need choose direction how to optimize that ;)

How to test?

obraz

TGLShadowVolumeRenderer.Render testing

It also can be tested, when InternalShadowVolumesOldRender is true there is the old render with glPushAttrib()/glPushAttrib()

Code style

Code has a lot duplications but will be cleaned after testing/choose new solution.

@michaliskambi
Copy link
Member

We talked about this with @and3md , I'm making a note here too:

  • We of course want to eventually merge this PR to master, this is a desired change. Instead of using old OpenGL fixed-function commands, we want to use internal scenes for rendering, which means that shadow volumes will work also on OpenGLES, and even any future rendering API (like Vulkan) automatically.

  • This PR shows that it already works :)

  • But to make it really efficient, we need more work.

    • The approach with "use internal scenes" loses some efficiency compared to "just directly execute OpenGL commands". We have ideas how to fix it, but they require experimenting. In the future, we generally want to make TCastleScene more lightweight and faster, which should automatically help with this.

    • 4D coordinates rendering should be done in CGE. Right now the PR does a trick in ExtrudeVertex to avoid it.

michaliskambi added a commit that referenced this pull request Jan 10, 2023
@michaliskambi
Copy link
Member

This has been addressed in shadow-volumes-new branch, which was just merged to CGE master.

Shadow volumes now work on OpenGLES! Along with shadow maps, 3D textures, occlusion query and much more -- see CGE news ( https://castle-engine.io/wp/ ) around the coming weekend, I will describe everything that happened.

In the end I used code and ideas from this branch, although I didn't just merge the commits. We've done a lot of code changes since this PR, in particular shadow-volumes-new brought a lot of simplifications, it also added TCastleRenderUnlitMesh utility. TCastleRenderUnlitMesh supports 4D vectors and is efficient (since it maps trivially to a VBO) so this made finishing shadow volumes + OpenGLES easier.

Here's a screenshot from Android (rather low-end 32-bit Android tablet, so don't worry about FPS :) ):

Screenshot_20230207-040536_Shadows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants