Quick answer: Connect Position output in Object Space to the Vertex Position master stack block. Verify Active Targets includes URP/HDRP, and that the material’s renderer queue matches the shader pass.
A wind-sway shader displaces vertex positions to make grass wave. In the Shader Graph preview the grass sways beautifully. Applied to grass meshes in scene view, it sways. In game view, the grass is static.
Active Targets
Graph Settings declares which render pipelines and passes the graph compiles for. If “Universal Forward” isn’t active but you’re running URP, the runtime pass is the fallback (no vertex displacement). Open Graph Settings → Active Targets and ensure your pipeline is listed.
Block Space
Master stack blocks have a Space dropdown. The default for Position is Absolute World in some Shader Graph versions. For vertex displacement you want Object Space:
- Click the Vertex Position block in the master stack.
- Inspector → Space → Object.
- Reconnect your Position output, computed in object space.
Mixing spaces silently produces zero displacement when world-position input maps to zero object-position offset.
Verify the Connection
Look at the master stack node. If the Vertex Position block’s input is gray (unconnected), you broke the wire during editing. Reconnect from your final Position output to the block.
Material Render Queue
If the shader is set to Opaque but the material is assigned to a Transparent renderer queue, some pipelines short-circuit the vertex pass for transparent passes. Check material → Render Queue. Match it to the shader’s SurfaceType setting.
GPU Instancing and _Time
If you use _Time for animation and the material has GPU Instancing enabled, all instances share _Time — identical motion, which can read as “static” for a regular pattern. Add a per-instance hash:
// inside Custom Function or via Object position in object space
float hash = frac(dot(WorldPosition, float3(12.9898, 78.233, 37.719)));
float phase = _Time.y + hash * 6.28;
Each instance picks a different phase, breaking the synchronized look.
Diagnosing
Open Window → Analysis → Frame Debugger. Capture a frame while game view is active. Click your grass renderer entry — the shader name and pass should be the one with vertex displacement. If a fallback shader is bound, the active target setup is wrong.
Verifying
Build and run. Grass should sway identically to the editor preview. If still static in builds, switch the URP Renderer asset to one with the same passes active, and confirm Shader Stripping isn’t culling the variant.
“Active Targets, Position Space, and runtime pass selection — all three must agree, or vertex displacement preview-works but ship-fails.”
Build a tiny vertex-shake test scene as a smoke test for new graphs — reveals active-target misconfig instantly.