T O P

[Demo 1] Real Time Sponza Scene Rendered In Custom Physically Based Graphics Engine (details & resources in comments)

This is a real time scene captured from a custom graphics engine I’ve been working on. I started working on this as a personal research project to explore 3D graphics programming and this week I felt like it had finally reached a state where I was comfortable putting together a short demo and posting it here.

Running on: * GTX 1060 * AMD Ryzen 5 (first gen)

Built with:

  • OpenGL 4.6
  • C++17

Current supported features:

  • Atmospheric shadowing
  • Cascaded shadow mapping
  • Deferred physically based direct lighting
  • Faked indirect lighting
  • Screen space ambient occlusion
  • Bloom
  • Automatic geometry instancing
  • Async model and texture loading
  • Virtual file system for GLSL (supports #include)
  • Unbounded number of shadow-casting point lights using shadow map cache
  • Normal mapping and parallax mapping
  • Skybox

Resources used for this project:

(general graphics/math)

(overview of graphics, lighting, shadowing, atmospheric effects, ssao, visibility determination, etc.)

(great resource for advanced modern OpenGL and Vulkan)

(bloom implementation)

(some techniques including shadow map caching)

(process of moving Frostbite to PBR) * https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf

' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
JTStephano

This is a real time scene captured from a custom graphics engine I’ve been working on. I started working on this as a personal research project to explore 3D graphics programming and this week I felt like it had finally reached a state where I was comfortable putting together a short demo and posting it here. Running on: * GTX 1060 * AMD Ryzen 5 (first gen) Built with: * OpenGL 4.6 * C++17 Current supported features: * Atmospheric shadowing * Cascaded shadow mapping * Deferred physically based direct lighting * Faked indirect lighting * Screen space ambient occlusion * Bloom * Automatic geometry instancing * Async model and texture loading * Virtual file system for GLSL (supports #include) * Unbounded number of shadow-casting point lights using shadow map cache * Normal mapping and parallax mapping * Skybox Resources used for this project: (general graphics/math) * https://learnopengl.com * [Foundations of Game Engine Development, Volume 1: Mathematics](https://www.amazon.com/Foundations-Game-Engine-Development-Mathematics/dp/0985811749) (overview of graphics, lighting, shadowing, atmospheric effects, ssao, visibility determination, etc.) * [Foundations of Game Engine Development, Volume 2: Rendering](https://www.amazon.com/Foundations-Game-Engine-Development-Rendering-ebook/dp/B084CYLG39?ref_=ast_sto_dp) (great resource for advanced modern OpenGL and Vulkan) * [3D Graphics Rendering Cookbook: A comprehensive guide to exploring rendering algorithms in modern OpenGL and Vulkan](https://www.amazon.com/Graphics-Rendering-Cookbook-comprehensive-algorithms/dp/1838986197/ref=sr_1_1_sspa?crid=DCNCMSFAY6E&keywords=3d+graphics+rendering+cookbook&qid=1673303333&s=digital-text&sprefix=3d+graphics+rendering+cookbook%2Cdigital-text%2C115&sr=1-1-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEzTThWS0I0U1ZRU0QyJmVuY3J5cHRlZElkPUEwMzkxMTE1Rlc2VFpINTg3WVdDJmVuY3J5cHRlZEFkSWQ9QTEwMTgxNThLU0lMRFczVVMzNzgmd2lkZ2V0TmFtZT1zcF9hdGYmYWN0aW9uPWNsaWNrUmVkaXJlY3QmZG9Ob3RMb2dDbGljaz10cnVl) (bloom implementation) * [http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare](http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare) (some techniques including shadow map caching) * [https://www.activision.com/cdn/research/2017\_DD\_Rendering\_of\_COD\_IW.pdf](https://www.activision.com/cdn/research/2017_DD_Rendering_of_COD_IW.pdf) (process of moving Frostbite to PBR) * https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf


voithos

Looks awesome, great work! I've also been working on a personal rendering engine, although I think mine is a bit less advanced, haha. [https://github.com/voithos/quarkGL](https://github.com/voithos/quarkGL) This may sound odd, but actually one thing that caught my eye from the features you mentioned is the GLSL virtual file system! I don't know how similar it is, but I also added what I call a "GLSL preprocessor" with #include support, and have used it to extract out a reusable library of shader functions. The loader is quite simple, but so far seems to work reasonably well: https://github.com/voithos/quarkGL/blob/master/quarkgl/shader\_loader.cc


JTStephano

Thanks, yours does as well! I saw you made a separate post so I left an upvote and comment. That’s awesome. For a while I went without it but it makes everything so much easier with preprocessing support. Shader code reuse allowed me to simplify a lot of the files.


EiffelPower76

Can we have the shaders code ?


JTStephano

I’m planning to clean things up, tie up some loose ends and release the code along with a second demo hopefully soon


waramped

Looks great, nicely done! Care to expand on the "Fake indirect lighting" part?


JTStephano

Thanks! Sure, they’re just special shadow casting lights that only activate when visible to the directional light. In this particular scene there were a little over 40 of them. It’s super fake but it wasn’t too hard to implement and I feel like it improved the visuals a lot.


waramped

Ahh I see. Sort of like Virtual Point Lights / Reflective Shadow Maps then. :)


[deleted]

> special shadow casting lights that only activate when visible to the directional light that sounds very interesting, do you activate them in compute shader?


JTStephano

Compute shader is probably the better way to do it but right now I’m doing it in the fragment shader. I think I’ll experiment with moving it to a compute step. Each light is represented by a point and normal in the fragment shader and I just test it against the shadow map cascades to see if the light is in shadow. If it is it gets thrown out, but if not then the light is kept around to contribute to the local lighting.


[deleted]

That's what I thought. You also call them "shadow casting lights" does it mean you draw shadow maps for all of these 40 lights beforehand?


JTStephano

Yeah that’s done in real-time whenever the engine marks a shadow map as changed such as if a dynamic object moved near it. If unchanged it just reuses previous shadow data to save performance. All the lights pull from a shared shadow map cache so sometimes a far away light gets evicted so its map can be used for a light closer to the camera.


robmaister

Looks great! The camera angle and sun trajectory reminded me of a demo video I took of my hobby engine from about a decade ago. Went back to find it and thought I had parsed materials from the model at that point, but I guess I was so excited to have CSM working that I recorded the video first. https://youtu.be/1utakCjC7Xc


JTStephano

Hey cool I agree, the camera angle and sun movement looks very similar. Did you keep going with OpenGL or did you move to different game or graphics work?


robmaister

I kept working on that project for a while, it died down over time and stopped when I started VR startup with some friends right out of college. That failed after a couple years. I got a job at a AAA game studio after that, where I'm still working. I got pretty lucky with my timing. A few months after I started, a new Unreal project was approved and I was one of the first few engineers moved to it. We're still unannounced ~4 years later, but I got to build some pretty cool stuff and have a big impact on the project. I'm very familiar with most of Unreal's rendering code at this point and have added some features to it. If I had any free time, I'd probably try to toy around with Rust and Vulkan nowadays


JTStephano

Oh wow that’s awesome, so you’re working with production rendering code as part of your job now. That sounds exciting. Plus you probably learned way more doing that than a hobby engine would give.


robmaister

Honestly, the hobby engine helped a lot coming into Unreal. I found that building my own engine gave me a deeper understanding of how things are supposed to fit together. I knew what a basic rendering pipeline should look like and how a GPU works. Unreal has to do all the same basics as any hobby engine, but wraps multiple rendering APIs and abstracts things further than most hobby engines. Having all that context going in made it much quicker for me to become productive in Unreal. I still learned a ton on the job, of course.


JTStephano

That makes sense, I didn’t think of it that way. So the hobby engine was a strong stepping stone for you to be able to understand scaled up Unreal code. That’s really nice! Hopefully I notice the same thing if I decide to start working with industry rendering code since I know some is open source.


theMelonator_

Damn Daniel