(Case 1227083) Tree Nature/Soft Occlusion shader in URP

So, recently I spend some time to make demo project with massive forest containing millions of trees. It highlights current advantages and limitations of Soft Occlusion vs SpeedTree in Build-In and URP pipelines. I also converted some Book of the Dead trees to work with Unity 2019.3.0f6 Build-In and URP pipelines.

Demo

Demo projects are available here: GitHub - chanfort/Tree-billboards-stress-test. Demo contains two projects. One is to show the forest in Build-In render pipeline, and another to show alternative in Universal render pipeline. Player can move around the world with WASD keys, rotate camera with mouse right button and zoom with mouse scroll wheel. Naming in projects is combined from these shortcuts: B - Build-In render pipeline, FB - camera facing billboards, CB - cross-plane billboards, SO - soft occlusion shader, ST7 - SpeedTree 7 shader, ST8 - SpeedTree 8 shader.

Build-In pipeline project

This project contains 3 scenes in order to show how forest looks like in Build-In render pipeline.

B_FB_SO Scene

Scene named B_FB_SO contains the first example. The demo generates terrain on entering in play mode. There are nearly 2 million trees placed on the terrain. Trees in this demo contains only single LOD and at larger distances trees appear as billboards. Tree shaders are set as Soft Occlusion Bark and Leaves. This allow trees to appear properly in billboard phase. Here is how the scene looks once entered into play mode:

World is generated within 3-5 seconds and afterwards gameplay runs at impressive 300 FPS on my 16-inch MacBook Pro (in Editor). Number of trees is defined in GenerateTerrain.cs script and can be easily changed. Bringing larger number of trees increases initial time to generate the world. But once generated gameplay performance is decreasing not very significantly with growing number of trees. Player can also see nearby trees swinging in wind. More distant trees are rendered in build-in billboard phase.

B_CB_SO Scene

This scene is identical to the previous B_FB_SO Scene except one change, each tree model is set with LOD Group so that the first LOD would appear as model and the second LOD appears as two cross intersecting planes billboard model. This way the camera facing billboards are not used and instead cross-plane billboards are used. Here is how the scene looks:

As we can see, the scene looks similar to the previous one except the catastrophic drop of performance from 300 FPS down to 0.9 FPS! The scene contains slightly less tree instances, around 1.2 million. So the estimate downgrade in performance would be (300 / 0.9) * (2 / 1.2) ~ 555 times. By comparing statistics tab at the top right corner we can also notice this number in this scene Batches: 578433. In the B_CB_SO Scene this number is Batches: 1476. However, Saved by batching: 0 in B_FB_SO Scene. But as we will see from other examples, where instancing is enabled and more are saved by batching, performance increases only slightly.

B_CB_ST8 Scene

This scene contains similar setup as B_CB_SO Scene except that instead of Soft Occlusion shaders, SpeedTree8 shaders are used. This allows us to see how BOTD trees looks with SpeedTree8 shader in Build-In render pipeline. Here is the scene view:

As we can see here, most of the trees appears black with only small areas illuminated by sunlight. However, this might be caused as BOTD trees were not designed to be used as SpeedTree8 models. And it may need a proper SpeedTree8 conversion or even modelling to fix the issue. The performance in this scene improves slightly from 0.9 to 1.2 FPS. But that is incomparably far from what was in B_FB_SO Scene. B_CB_ST8 tree materials are set to use instancing and we can see that Saved by batching: 577132 in this scene.

Universal render pipeline project

The remo contains the second project which is set in a similar fashion to use URP.

U_FB_SO Scene

This scene is set in a similar way like B_FB_SO Scene in the first project except that the project is converted to use URP. Trees in this scene are still using Soft Occlusion shader from Build-In render pipeline as there are no alternative Soft Occlusion shader in the URP. Here is the result:

As we can see trees which are close to camera are rendered in model phase and appears pink. This is not surprising as Soft Occlusion shader selected from Build-In render pipeline can’t support URP. But the interesting part is that billboards appear to be rendered correctly! That could mean one of two: that billboard phase has been already implemented in URP, or that internal camera facing billboard shader is compatible with new SRPs including URP. Looking from performance perspective, the scene runs at solid 300 FPS in the similar was as it was with B_FB_SO Scene. This is because camera facing billboards are used which are capable to render millions of trees at playable framerates.

U_FB_ST8 Scene

The difference introduced in this scene is that instead of Soft Occlusion shaders, URP compatible SpeedTree8 shader is used. Models are left in the same way without LOD Group components in order to use camera facing billboards. Here is the result:

As we can see, distant trees are rendered in billboards but they are more transparent comparing to Soft Occlusion shader ones. As a result, the forest appears more like it would have dead trees. Performance is still very solid, running at 200 FPS. The drop from 300 FPS might be understandable as SpeedTree8 shader is more advanced than Soft Occlusion and may require more GPU power. When generating terrain, this causes console warning to be printed that Soft Occlusion shader must be used as otherwise billboarding/lighting will not work correctly. This is basically what we see in the picture above. This scene was made as a possible workaround solution in URP in order to be able to render large scale forests. But console warnings and too transparent billboards show that there are issues.

U_CB_ST8 Scene

This scene is set in a similar way like BuildInST Scene in the first project except that URP SpeedTree8 materials are used instead. Due to the usage of cross-plane billboards instead of camera facing billboards, we have again catastrophic performance drop down to 1.8 FPS.

Conclusions

Camera facing tree billboards are currently the only way to render large scale forests in Unity. The technique is capable to handle millions of tree instances. However, it is currently not supported in the new Universal Render Pipeline which is a candidate to replace Build-In render pipeline in more distant future. Several years ago, a different way was introduced to render several hundreds of trees in smaller scenes using two cross intersecting plane billboards. This is currently the default way to use trees in the URP using SpeedTree.

Demos were made to show that cross-place billboards can’t fully replace many years existing camera facing billboards. If scenes are small, containing several hundreds of trees, cross-fading billboards can be a good choice. However, large scale forests containing millions of trees requires the old camera facing billboards.

As a result, it would be nice if camera facing billboards would be ported to URP at some time in the future. This would enable us to continue having large scale forests in our games using URP in the future.

7 Likes