# 7. Compute and Instancing Pitfalls Part of [[Compute Shaders and GPU Instancing]]. Prev: [[6. GPU Frustum Culling with Append Buffers]]. | Symptom | Cause | Fix | |---|---|---| | Whole swarm/field vanishes at certain camera angles | `RenderParams.worldBounds` too small; Unity culls the entire call as one object | Generous bounds; contain agents in a known radius ([[5. Worked Example Compute Swarm]]) | | `InvalidOperationException` from `RenderMeshInstanced` | Material lacks Enable GPU Instancing, or platform lacks instancing | Tick it on the material; check `SystemInfo.supportsInstancing` | | Only part of a big instanced array draws, or errors | Over the per-call limit (1023 max; 511 with default matrices) | Batch at 511 ([[2. RenderMeshInstanced Batches]]) | | Garbage positions, exploding meshes | C# stride does not match the HLSL struct | One shared struct, `StructLayout(Sequential)`, stride from field sizes | | Flock jitters / "teleporting" agents | Reading and writing the same buffer in one dispatch | Ping-pong buffers (Double Buffer) | | GPU hang or random results with groupshared | A thread returned before a `GroupMemoryBarrierWithGroupSync` | Use an `active` flag; no early return before barriers | | Frame time spikes when debugging | `GraphicsBuffer.GetData` stalls until the GPU finishes | `AsyncGPUReadback.Request`, accept 1-3 frames of latency | | "GarbageCollector disposing of GraphicsBuffer" warnings | Buffers not released | `Release()` in `OnDisable`; also on domain reload | | Culling has no effect | `CopyCount` offset wrong for the platform, or culler ran before the swarm overwrote the count | Verify the offset by readback; execution order 100 ([[6. GPU Frustum Culling with Append Buffers]]) | | `CopyCount` errors on DX11/12 | Destination not `Raw`/`IndirectArguments` | Create args with `Target.IndirectArguments` | | Swarm missing from SSAO/depth effects | No `DepthOnly` pass | Keep the pass from [[4. Indirect Draws with GraphicsBuffer]] | | No shadows from the swarm | No `ShadowCaster` pass, or `shadowCastingMode` Off | Add the pass, set the mode, and keep bounds right | | Shader compiles in Editor, pink in a build | Keyword variant stripped | `multi_compile_local` (not `shader_feature`) for runtime-toggled keywords | | Indirect shader will not compile in URP | `UnityIndirect.cginc` incompatibility (unverified) | Use `SV_InstanceID` directly with one command and `startInstance = 0` | | Nothing renders on a laptop/older API | No compute support | Check `SystemInfo.supportsComputeShaders`; fall back to `RenderMeshInstanced` | | SRP Batcher vs instancing confusion | Expecting the material checkbox to instance GameObjects in URP | GameObjects use the SRP Batcher; explicit calls use instancing ([[1. Instancing Paths and When to Use Each]]) | ## Platform notes - **Web.** Compute shaders are not available on WebGL 2; any WebGPU path is a separate, newer backend to check against your Unity version ([[Web and WebGL Builds]]). Always ship a `RenderMeshInstanced` fallback for web builds. - **Quest 2 / XR.** Quest 2 can run compute shaders, but its mobile GPU has far less bandwidth and thermal headroom than a desktop ([[5.Quest 2 Performance and Rendering]], [[Profiling and Optimization]]). VR work targets **Unity 6.3 LTS (6000.3.27f2+)**, not 6000.5. Single Pass Instanced stereo rendering doubles instances per draw and requires stereo macros (`UNITY_VERTEX_INPUT_INSTANCE_ID`, `UNITY_VERTEX_OUTPUT_STEREO` and friends) plus doubled instance counts in custom indirect shaders. That is **not covered or verified here**; prototype on desktop, then follow Unity's single-pass instanced custom-shader guidance for your exact URP/XR version. - **Mac/Metal.** Threadgroup limits and some atomic behaviours differ; query `SystemInfo.maxComputeWorkGroupSize`. ## Design pitfalls (Level Up!) - **Spectacle without readability.** Ten thousand agents are noise unless the player can read intent. Give the swarm a clear target and a telegraph before it changes behaviour (Level 11, [[Level Up! (Review)]]). - **Performance as design.** If the swarm costs 6 ms, it is a level-design constraint: fewer, larger agents may read better anyway. ## Patterns recap Flyweight, Data Locality, Double Buffer, Spatial Partition, Update Method ([[Game Programming Patterns (Review)]]).