Performance and compatibility
Optimization
Tune density, distance, chunking, culling, memory, and runtime quality.
Measure the Player
Use a Development Player at a fixed resolution, camera, quality level, density, lighting mode, and graphics API. Warm the renderer before sampling. Report CPU frame time, GPU frame time, grass-stage CPU markers, visible blades, visible chunks, indirect commands, GPU memory, and steady-state managed allocation separately.
Editor Game-view FPS is useful for interaction checks but is not a release benchmark. Use the benchmarks and validation page for controlled Development Player evidence and its current release boundary.
Select the quality budget
| target | package profile | runtime level | intended use |
|---|---|---|---|
| cinematic desktop | Cinematic | High | hero shots and the 60 FPS reference scene |
| balanced desktop | Desktop High | Medium | the replacement for the old planned Desktop Balanced preset |
| high mobile | Mobile High | High | compute-capable mobile targets after device validation |
| low mobile | Mobile Low | Low | reduced distance, survivors, and cameras |
| disabled | any | Off | no culling, upload, stomp, or draw work |
High, Medium, and Low reuse the same packed 24-byte blade allocation. Normal Off retains it for instant reactivation. Release Resources While Off is a separate delayed memory policy and can add a reload or regeneration cost later.
Tune the real bottleneck
- If GPU time rises with stable CPU time, reduce survivor density, maximum distance, shadows, procedural motion vectors, semantic field resolution, or overdraw-heavy far width.
- If CPU grass stages rise with species count, inspect visible commands. Species share one blade budget but require material and geometry command ranges.
- If memory is high, lower the total blade cap or author a smaller field. Do not create one blade allocation per runtime quality level.
- If dirty painting stalls, increase chunk size only after measuring the tradeoff between command count and patch granularity.
- If a distant field is open and automatic Hi-Z has no profitable occlusion, its backoff path is expected. Do not force Hi-Z merely because it exists.
Locked regression budgets
The feature-free 26.8.0 candidate inherits the accepted pre-alignment 0.9.4 runtime measurements on Windows 11 build 26200, Intel Core i9-14900KF, NVIDIA GeForce RTX 2080 Ti driver 610.47, Unity 6000.4.0f1, URP 17.4.0, and 1920 x 1080. This result advertises only that measured configuration. 0.9.4-validation.md records the final Metal comparison and physical Windows rerun; the later 26.8.0 change is metadata-only.
The final GrassDemo300 Metal ABBA measured 0.9.2 at 4.6222 ms CPU and 5.3956 ms GPU versus 4.6254 / 5.3860 ms for 0.9.1. Identical 505,113 visible blades, 64 chunks, 78 commands, and 0 B steady allocation make this parity evidence; the sub-0.2% deltas are measurement noise.
The final physical Vulkan pair measured GrassDemo300 Automatic at 4.2205 / 3.4894 ms CPU/GPU and forced Off at 4.2179 / 3.4860 ms, each with 505,113 visible blades, 64 chunks, 78 commands, and 0 B steady allocation. GrassDemo1000 Automatic measured 6.0344 / 5.9518 ms with 1,335,777 visible blades, 484 chunks, and 89 commands; forced Off measured 6.0430 / 5.9479 ms with 1,338,501 blades, 490 chunks, 89 commands, and 0 B. Automatic safely backed off in the open GrassDemo300 view and applied a stable mean of 11 culled chunks in GrassDemo1000. Controlled motion runs culled 59 and 605 chunks respectively and recovered after the camera move in one rendered frame.
Still stuck?
Bring the renderer status with you.
Include the Kiwi Grass version, Unity and URP versions, operating system, graphics API, renderer status, Player log, and a minimal reproduction.