Procedurally generated bushes and trees in the engine: Geometry of the trunk is generated through code, each leaf is drawn separately via GPU instancing. Scene has large number of triangles - each tree has 467,856 for trunk and branches and 30,600 leaves with 4 triangles each. There are 101 trees, totaling 59,615,856 triangles. Runs at around 39fps at bird's eye view, 54-70fps in the forest and over 425fps when no trees are on screen.
Building the foliage:
- L-systems: Model plant growth using formal grammar. Starts with an axiom and has production rules. Expands by replacing symbols based on rules for a configurable number of iterations. Interprets generated string using a turtle with commands like F (move forward), + (turn left), - (turn right), [ (begin branch), ] (end branch), & (pitch down), ^ (pitch up), \ (roll left), / (roll right), and L (record transformation matrix).
- Topologizing an L-system: Composes generated structure using 3D parts like conical frustums with angled tops. Configurable top and bottom radius, top cap position and orientation. Turtle state includes location, rotations, radius, etc. and interpretation logic adjusts state and emits parts.
- Rendering a bush: Configured and built an L-system to generate a bush. It has 2,835 leaves. Used geometry instancing to submit all draw calls at once for leaves.
- Rendering a tree: Generated a tree trunk and branch using separate L-systems. Combined them using instancing to save memory.
Improving performance:
- Trace analysis: nSight Graphics shows shadow pass takes long time. Long scoreboard stall in instancing vertex shader due to waiting for instance data. Tree is drawn many times in shadow pass due to large combined mesh.
- Frustum culling: Discards objects outside camera's view frustum. Assigned axis-aligned bounding boxes to objects and performed intersection test. Started drawing branches using instancing and made tweaks in shaders and used meshoptimizer. This improved frame time significantly.
- Culling with directional light shadows: Fit directional light frustum to view frustum to use reduced orthographic projection volume for culling. Causes shimmering artifact at shadow edges which is filtered using large kernel PCF.
- Results: Frustum culling techniques improved performance noticeably. Still optimization to do like reducing instance data buffer size and using meshoptimizer to simplify branches. Overdraw is the biggest performance hog and may need to modify renderer. Can add more varieties of trees and props in a follow-up post.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。