Light Propagation Volumes

I've finally finished my lab course last week - thanks to my supervisor Matthäus G. Chajdas - you can read his blog here -, it wasn't your usual lab course with work sheets and boring homework, instead I've been allowed to implement a nice paper about a Global Illumination approximation algorithm called (Cascaded) Light Propagation Volumes. It's been developed by Crytek and you can find more information (including some presentations and videos) on their server. (Note: this is an implementation of the I3D paper, not the earlier SIGGRAPH one.)

Sponza scene (direct + indirect lighting w/ occlusion)

Sponza scene (only indirect lighting w/ occlusion)

Sponza scene (ony direct lighting)

Sponza scene (boosted indirect lighting w/ occlusion)

Sponza scene (boosted indirect lighting w/o occlusion)

The algorithm approximates global illumination by rendering the light into a reflective shadow map, injecting it into a volume (using a spherical harmonics representation) and propagates the light flux in this volume (hence the name of the algorithm) and taking into account occlusion as possible extension.

The whole algorithm is physically motivated but corners everywhere, of course, to be more efficient. The paper also contains a few errors and doesn't explain everything needed to implement it in great detail (like eg the solid angles of the side faces), so I've written two documents detailing the mistakes I've found and the additional calculations I've performed.

You can find the mistakes here (including suggested corrections) and the full annotations document here.

Finally I've also uploaded the whole prototype (including my code licensed under the FreeBSD license and the media files) here - it's 68 MB big (and it's been compressed with 7zip with a compression mode that might not be supported by WinZIP. The Sponza model is from Crytek, too. You can download the original model and textures here.
The project uses DirectX 10.1 and by default it won't run in DirectX 10, because it uses a texture format that is deprecated in D3D10 but supported again 10.1 (BGRA). See the comment by FatGarfield for the location that needs to be changed for it work in DX10, too. (However red and blue will be swapped then.)

Update: I've updated the project to support Visual Studio 2012. You can find the full download here (68 MB).

I haven't implemented cascaded LPVs and I also use only one light/RSM and only inject its depth into the occlusion volume, but the results already look very nice in my opinion.

Stay tuned for more :-)

  • Pingback: Tweets that mention Light Propagation Volumes « BlackHC’s Adventures in the Dev World --

  • FatGarfield

    Thank you for sharing your excellent work.
    I've downloaded the source code, but failed to uncompressed them.
    The error message is : "unsupported compression method for '*.*', here, *.* represents for each of the file in

  • BlackHC

    I've compressed it with 7zip. I'm not sure whether I might have chosen some compression setting that is not supported by your decompression tool.
    I'm going to look into it.

  • FatGarfield

    Thank you for the rapid feedback.
    I've solved the problem by downloading the latest version of 7zip.

    Also I encountered a runtime error, by changing the coding in line 608 in MeshLoader10.cpp from "D3D10Texture3DDesc( DXGI_FORMAT_B8G8R8A8_UNORM,..." to "D3D10Texture3DDesc( DXGI_FORMAT_R8G8B8A8_UNORM,...", the app runs well.

    I don't know the reason but I solved it.

  • BlackHC

    Oh thanks for pointing this out. I've totally forgotten about that. DX10 doesn't support BGRA, but DX10.1 does (again). So the code has to be changed to run out of the box on older NV cards. (I'm using an ATI card in my dev machine.)

  • Mathieu


    finnaly someone made light propagation volume available for free ^^ thank you!

    by the way, do ¨Stay tuned for more¨ mean that you will include things like cascaded lpv in the near future? :)

  • xin

    Hi ~ thanks for sharing your great work!

    I got an error in line 608 in MeshLoader10.cpp. I follow the changes, but still not work, I don't know how to fix it... I am not sure is the graphic card cause the error or not? The error is the E_INVALIDARG(0X80070057).

    Thanks for the help~~~

  • Pingback: Project update « Isometric Tiger()

  • Mor An

    Can I find the model files elsewhere?

  • Hummel

    Your annotations document will be quite usefull, thx.

  • mifan

    Thanks for the excellent work!
    It helps me a lot better understand the original paper.

    I also noticed that the textures were upside down, suggesting that the y-component should be reversed in the vertex shader somewhat like:
    output.vTexUV.y = 1 - output.vTexUV.y;

    Just check the lions' faces and you will see 😉

    • BlackHC

      Thanks for pointing that out :-)
      I'm not sure when I'll upload a new revision, but it's good to have it noted here.

  • Louis Castricato

    Great sample, I wish I could implement it in my engine but, the only versions of DirectX that I know how to program in is SlimDX and XNA
    Can someone convert this to SlimDX? I would do it myself but, I don't know C++

    • Edgar

      Hi Louis, I'm trying to migrate the LPV's algorithm to XNA but I've some bugs in the radiance volume. Because DirectX 9.0 can not change the volume for radiance, it should be used as a texture 2d, so any suggestions are welcome!

    • KillAWatt1705

      Hey Louis,

      If you're familiar with C# then adapting to C++ is relatively easy. I was more familiar with C++ but found C# very easy to read and clicked almost immediately. The syntax isn't radically different, just a few coding conventions and structures. Most low-level graphical code is written in C or C++, so its very useful to be able to read. Give it a shot!

      I'm currently trying to port the code to OpenGL myself, although I'm getting alot of shader-based errors, since GLSL and HLSL vary slightly. Its gonna be a long night...

  • jiezh

    Hi,I down load the source code of the sample,And I can't find the difinition of the class EffectGPUInjection,I don't known where to find it,even google can not find this class.

    • BlackHC

      This class is generated using macros by the preprocessor. Look at the header files. One of them contains lots of macro #defines that are used to create this class.

  • Pingback: [I3D'10]Cascaded Light Propagation Volumes for real time indirect illumination « fseraph's space()

  • Tangletail

    The demo does not work for me.