How do I enable static/dynamic batching for the shadows?

Added on by Gustav Olsson.

The toolkit uses Unity's Graphics.DrawMesh() internally and meshes submitted to the renderer this way are not batched.

To mitigate this problem, the ShadowComponentToGO.cs script is bundled with the toolkit. Attach this script to any game object with a ShadowVolume component and during Play-mode, shadow game objects will be created to take care of the shadow rendering instead of the Graphics.DrawMesh() call. This will enable dynamic batching for the shadow game objects in question.

Keep in mind that the shadow meshes need to have a vertex count of 300 or lower in order to qualify for dynamic batching. See the Unity documentation here.

Unfortunately, it is not possible to easily get static batching to work with the toolkit since it requires the shadow game objects to be instantiated at build-time.

Why do the shadows sometimes disappear when the camera approaches?

Added on by Gustav Olsson.

This is caused by the built-in view frustum culling in Unity. Since the shadow volumes are extruded on the GPU and the view frustum culling happens on the CPU, Unity might choose to not render a shadow volume even though it will actually end up covering the view. (Notice that the shadow will only disappear if the shadow caster is outside the view frustum of the camera?)

To fix the problem, set the Bounds Margin to a large value (~1000) before setting up shadows using the Quick Shadow Setup dialog. The shadow mesh bounds are extended by this value and since the bounds are what determines the size of the mesh during view frustum culling, the mesh will not be culled (as easily).

Ideally, the Bounds Margin value should be set to the maximum length the shadow can reach from the shadow caster. Since this is difficult to determine in practice it's sufficient to just set it to a large value.

Why are there thin shadow lines in mid-air extruding from my model?

Added on by Gustav Olsson.

This artefact is caused by having anti-aliasing enabled when using the "Alpha Channel" backend. To fix the problem, either switch to the "Stencil Buffer" backend (on the ShadowVolumeRenderer component) or disable anti-aliasing.

In Unity, Quality settings above Good all have some form of anti-aliasing enabled by default, so make sure that you double check all of these presets if you let the end-user choose which setting to use.

What is the vertex/triangle count of a shadow mesh?

Added on by Gustav Olsson.

The number of vertices/triangles in the shadow mesh depends on the number of triangles in the source mesh, here are the numbers.

For a two-manifold/closed source mesh:
vertexCount = sourceTriangleCount * 3
triangleCount = sourceTriangleCount * 4
For a non two-manifold/closed source mesh:
vertexCount = sourceTriangleCount * 6
triangleCount = sourceTriangleCount * 6

As you can see, two-manifold source meshes are to be preferred. Two-manifold source meshes result in fewer vertices/triangles and are less fill-rate intensive.

Is it possible to make an object not receive shadows?

Added on by Gustav Olsson.

First of all, shaders that don't write to the depth buffer (transparent shaders among others) will not receive shadows.

Even though there is no checkbox that controls whether a game object receives shadows or not, you can use multiple cameras to selectively shadow the scene. In one of my games, I render all the static geometry and shadows using the first camera, then the dynamic game objects using the second camera (which doesn't clear the display buffer). This way, only the static geometry will receive shadows and there will be no self-shadowing on dynamic objects. The 2 cameras are parented to the same game object so that I can control the view without having to change 2 game objects each time.

Here are the settings I use for each camera:
Main camera: Culling Mask: Everything except the "Dynamic" layer; Depth: -1;
Dynamic camera: Clear flags: Don't clear; Culling Mask: "Dynamic" layer only; Depth: 0;

Because shadows are rendered in the "Default" layer, dynamic game objects will not receive shadows. Note that while the self-shadowing is gone in the game view, it is still present in the editor scene view since it only uses one camera. Also note that while dynamic game objects do not receive shadows in this example, they can still act as shadow casters!

The toolkit lets you choose which layer the shadows are rendered in as well, in case you need to use more complex camera setups.