hadronized / quaazar

Realtime 3D engine
BSD 3-Clause "New" or "Revised" License
6 stars 2 forks source link

Shadows #76

Closed hadronized closed 9 years ago

hadronized commented 9 years ago

Shadows

Everything gets implemented in the shadows branch.

ShadowLOD

When a light casts shadows, it has to provide a ShadowLOD object. That object selects the level of detail needed by the cast shadows. There’re three possible values:

If a light mustn’t cast shadow, there’s no ShadowLOD object to pass. Then, the interface is obviously Maybe ShadowLOD, with Nothing for… no cast shadows.

ShadowConf

ShadowConf is an object of the render side. It defines, for each level of detail, the configuration used in the renderer. That objects defines three parts – i.e. for low, medium and high shadows – which are each composed of two information:

For instance, ShadowConf 512 10 1024 5 2048 2 will spawn ten 512x512 low shadowmaps, five 1024x1024 medium shadowmaps and two 2048x2048 high shadowmaps.

Light data

Currently, lights have several information stored on the render side – in a SSBO:

We are to add two new values to the list. The first one is the level of detail of the shadows to cast. That is a simple uint and choices are encoded that way:

The second value is the index of the shadowmap. Because we’ll have several shadows at the same time, we’ll need to know which one to sample from when dealing with a given light. That’s stored as a uint as well. If the LOD is 0, the shadowmap index is set to 0 and shouldn’t be read anyway to prevent fucks to happen.

Shader

The lighting shader will now have two additional information in the structure defining a light and three samplerCubeArray, for low, medium and high shadowmaps, respectively. Along with the above two information, we’ll be able to perform a correct lookup of the right shadowmap.

Shadowmap generation

Before sampling the shadowmaps, we’ll need the shadowmaps themselves. To generate them, we need to be able to bind the correct one. That can be done very easily be reading the Maybe ShadowLOD object. If we got Nothing, we won’t do anything and go on. If we got Just lod, depending on the lod, we’ll bind the corresponding cubemap array, and get in some kinda state the shadowmap index (then increment it in the state). That index will have to be passed to the depthmap generator shader to write to the correct layer-face. Pretty simple right.