0/ 1043/ /1


The Unity engine’s handling of tree shadows on Terrain is slightly simpler, which often fails to meet project requirements. When dynamic objects sample Light Probes, Lightmaps are not baked for the tree by default. But we know that even the light probe proxy volume of such large dynamic objects (not supported, it is also stuck if it is changed) is only richer in indirect light and large-scale occlusion, and cannot effectively express the self-shadowing effect. Once out of the real-time shadow distance, the picture is a lot worse. And the “Life and Death Sniper 2” in hand is a large-scale project with an investment of 400 million R&D. As the person in charge of graphics rendering technology, I need to list and compare several technical solutions.


The specific requirement is to use Shadowmap within 50 meters, and there must be parallel light shadows within 50-1500 meters, and the parallel light is static.


Here are 7 options that I’ve tried or learned about that meet this need.

  1. Bakes instance-reusable non-directional indirect light shadows
  2. Baking instance reuse + rotatable directional light shadows
  3. Low precision precomputed static Shadowmap shadows
  4. Sparse octree voxelized static shadows
  5. Screen space contact real-time shadows
  6. Real-time shadows based on low-precision heightmaps
  7. Distance Field Accelerated Ray Marching Shadows

Option 1: Bake instance-reusable non-directional indirect light shadows


This is the simplest and most rude method, which is to use a skylight to bake a shadow similar to AO under 3DsMax, so that the trees are compatible with any angle of sunlight after rotating at any angle, and the resource reuse rate is the highest, but it is not considered the directional light shadows are a bit unreal and unremarkable. Get a baked map like this, acting on the two sets of UVs for the tree. The code is also very simple, you only need to add UV1 transmission in SpeedTreeCommon.cginc, and finally * to Albedo, because the indirect light effect is not big enough just like AO.


Prefab reuse of Max-baked AO map binding tree, Unity baking cannot be reused and with direction


Real-time shadow


Real-time outside shadow


The effect of this option


Advantages: Simple and easy to use, implemented with 4 lines of code, high performance, a low-resolution image is sampled once.


Disadvantages: The directional light is not considered, the shadow can only be improved by itself, and the dynamic objects under the tree cannot be blocked (the static shadow mask can be baked).

Option 2: Baking reusable instances + rotatable parallel light shadows


Similar to the previous scheme, but with the addition of directional considerations, baking such 8 parallel light baking maps.



Different AO maps are set according to the different orientations of the tree instance, however, it is inconvenient to set the tree on the terrain, it can be made into an array or atlas. In the shader, take the Index or Offset according to the orientation, because the effect is similar to the previous one, but with better directionality. Each direction is relatively normal. If you feel that 8 directions are not enough, you can use 2 directions to interpolate or make a map of 16 directions.


The effect of this option


Advantages: Simple and easy to use, high performance, a low-resolution atlas is sampled 1 or 2 times, supports rotation, and has directional shadows.


Disadvantages: Maps with different angles of the sun may require a separate set of textures. You can only improve the shadow yourself, and cannot block dynamic objects under the tree (static shadowmask can be baked).

Option 3: Precomputed static Shadowmap shadows with low precision


First, compare the effects in the real-time shadow. The self-shadow of the leaves is not bad, but the second one is terrible outside the real-time shadow.



With 4M static Shadowmask effect:


Principle: Take a Shadowmap offline to record the depth map and record the matrix_vp of the light camera. But because of this kind of large-scale shooting, the depth accuracy may be insufficient, so I did not use 16-bit, but compressed the depth myself with RGBA32, so it looks striped.


Advantages: Not only does it have shadows, but it can also block dynamic objects such as distant characters, which is simple to implement, saves Draw Calls during runtime, and does not need to repeatedly shoot distant scenes.


Disadvantage: large memory.


Continue to upgrade the scheme: static Shadowmap based on virtual texture or Shadowmap of Texture streaming.

Option 4: Sparse Octree Voxelized Static Shadows


The effect of voxelizing shadows with 0.9M:


Principle: One cube every 0.5 meters, record 0 or 1, indicating whether it is in the shadow or not, as an octree node. Memory is then saved by tree compression.


Advantages: Not only does it have shadows, but it can also block dynamic objects such as dynamic characters. It saves Draw Call when running, and does not need to repeatedly shoot distant scenes. Compared with Shadowmap, it saves video memory.


Disadvantages: The implementation is more complicated, and the precomputing write high concurrency can be fast. Shader needs multiple sampling to query the result.


Project file


Schemes 5, 6, and 7: Each Demo development is more complicated, and it will be updated or a separate article later.

Thanks to the author 偶尔不帅 for offering the article. Welcome to forward and share, please do not reprint without the author’s authorization. If you have any unique insights or discoveries, please contact us and discuss them together.



UWA Website:

UWA Blogs:




Related Topics

Post a Reply

Your email address will not be published.