Deformable desert sand for URP, simulated on the GPU. Feet, wheels and dropped objects leave marks, oversteep slopes collapse at the angle of repose, and wind slowly reworks the surface.URP only - no Built-in or HDRP variant. Works with default URP asset settings: no Depth Texture, Opaque Texture or custom Renderer Feature needed.Unity 6000.0 or newer. Needs compute shader support (SM 5.0, or GLES 3.1 with compute), so WebGL is out. Mobile runs but is fill-rate bound - test on device.Demos work with either input backend.Sand that remembers what walked across it.SandSim is a deformable desert surface for URP, simulated on the GPU as a height field. Anything you tag with a SandDeformer presses into it - feet, tyres, a dropped crate, a rolling boulder. The displaced sand piles up around the rim rather than vanishing. Slopes that end up too steep collapse on their own, and the wind slowly softens tracks and creeps the dunes.Because it is a texture and not particles, the cost does not change as the ground gets churned up. A desert covered in an hour of footprints renders in the same single draw call as a pristine one.WHAT IT SIMULATESDisplacement - sand pushed out of a footprint ends up around its rim, so marks look pressed in rather than stamped on.Angle of repose - dry sand will not hold a slope past about 34 degrees. Dig a hole and the walls slide back in. Pile sand up and it settles into a cone by itself.Wind transport - sand lifted off one cell lands on the next one downwind. Tracks soften over time, dunes creep. Turn it off entirely if you want marks to stay put.Bedrock - sand sits on rock and is never carved below it, so digging bottoms out instead of going forever. Where the rock rises above the dunes it shows through as a shaded outcrop.TUNINGEvery number is exposed on the component and takes effect live. Four one-click presets cover the usual materials: Dry dunes - loose, slumps easily, wind keeps working on it Packed sand - beach above the tide line, holds a steeper face Fine dust - collapses at the slightest touch, drifts constantly Gravel - coarse and stubborn, steep piles, no wind transportPast the presets you control the angle of repose, flow rate, relaxation passes, wind direction and strength, dune height, scale and direction, and the bedrock shape. The surface material exposes sand and rock colours, slip-face shading, wind ripples, sparkle and roughness.USING IT IN A GAME float y = field.SampleHeight(worldPos); // stand on it Vector3 n = field.SampleNormal(worldPos); // read the slope field.ApplyBrush(worldPos, radius, metresPerSecond, mode);That is most of the API. ApplyBrush is what an in-game shovel, an explosion crater or a vehicle plough calls. Heights are read back to the CPU a few times a second, which is what lets a character walk on dunes it is busy digging out from under itself.WHAT IT SUITSDesert survival and exploration, where footprints and dig sites are the point. Off-road and dune-buggy driving, where tracks matter. Top-down builders and god games - the included sculpting demo is exactly that loop. Excavation and archaeology games. Anywhere a beach, quarry, ash field or gravel pit needs to respond to being walked on.It is not a terrain replacement. Think of it as one patch of responsive ground you place where the player actually is.INCLUDED SandField and SandDeformer - the whole runtime, in an assembly that references nothing but the engine SandSim/Sand surface shader with a matching shadow caster Setup window that wires a field into your scene in one click Custom inspector with presets and live cell-size and memory readouts Two demo scenes - first person walking, digging and boulder throwing, and a top-down sculpting sandbox Full manual: parameters, how the simulation works, performance figures, and the things that will otherwise catch you outPERFORMANCE512 x 512 cells over 120 m, desktop GPU at 1440p, demo running: Simulation ~0.5 ms/frame Memory 5 MB Draw calls 1 Frame rate 170-290 fpsThe fragment shader is the expensive half, not the simulation. Halving the resolution is a 4x saving if you need it.REQUIREMENTS URP. There is no Built-in or HDRP variant. Unity 6000.0 or newer. Compute shader support - Shader Model 5.0, or GLES 3.1 with compute. WebGL cannot run this.No URP asset changes are needed: no Depth Texture, no Opaque Texture, no custom Renderer Feature. It works with whatever Renderer you already have. The demos run on either input backend, and the Input System package is not required.LIMITS, STATED UP FRONT It is a height field. No overhangs, no caves, no sand pouring off a ledge. There is no collider. The surface lives on the GPU, so raycasts pass through it - use SampleHeight instead. The demo character does exactly this. 32 deformers are considered per frame. Wind ripples are shading, not geometry. Two fields can overlap in world space but will not exchange sand.SIMULATION- GPU height field, seven compute kernels: init, carve, spread, repose relaxation, wind, brush, bedrock bake- Displacement with conservation: sand removed from a footprint is piled around its rim- Angle of repose, 20-55 degrees, symmetric cell exchange so the volume holds- Wind transport as paired flux, out of one cell and into the next - no drift or mass loss over long sessions- Bedrock floor: digging bottoms out on rock instead of going forever, and exposed rock is shaded as stone- Resolution 256 / 512 / 1024 cells, field size 20-400 m. 120 m at 512 is a 23 cm cell- Relaxation passes per frame adjustable 0-8; wind can be switched off to skip the pass entirelyRENDERING- Custom URP surface shader with a matching shadow caster, both sharing one height function- One draw call, one mesh, height read in the vertex stage - no CPU mesh work- Wind ripples, slip-face shading and rock grain, with a distance fade so they do not alias- Exposed material properties: sand and rock colours, ripple depth, sparkle, roughness, sand cover depthRUNTIME API- SampleHeight(worldPos) and SampleNormal(worldPos) for standing on the surface and reading slope- ApplyBrush(worldPos, radius, metresPerSecond, mode) - raise/lower, smooth, flatten- Regenerate() and Flatten()- Async GPU readback at ~12 Hz, so height queries never stall the frameDEFORMERS- SandDeformer component: radius, vertical offset, active flag. Registers itself on enable- Up to 32 considered per frame- Sphere-based, so any mesh shape works - use several for a capsule or a boxEDITOR- Setup window: creates and wires a field in one click, adds a low sun, attaches deformers to a selection- Custom inspector with four material presets (dry dunes, packed sand, fine dust, gravel)- Live cell size, memory and deformer count readouts- Startup checks report a missing compute shader, a non-URP pipeline or a GPU without compute supportPERFORMANCE (512 x 512 over 120 m, desktop GPU, 1440p, demo running)- Simulation ~0.5 ms/frame- Height field memory 5 MB- 1 draw call, 262k triangles- 170-290 fpsPACKAGE- Full C# source, no DLLs, no third-party assets, no textures - everything is procedural- Runtime in its own assembly definition that references nothing but the engine- Namespaced throughout; Editor and Demo folders can each be deleted without breaking the runtime- Two demo scenes: first person walking, digging and boulder throwing, and a top-down sculpting sandbox- Demos run on either input backend; the Input System package is not required- Manual and changelog includedREQUIREMENTS- URP only, Unity 6000.0 or newer- Compute shader support: Shader Model 5.0, or GLES 3.1 with compute- No URP asset changes needed - no Depth Texture, no Opaque Texture, no custom Renderer Feature- Not supported: Built-in, HDRP, WebGLLIMITS- Height field: no overhangs, no caves, no sand falling off a ledge- No collider - the surface is a GPU texture, so use SampleHeight rather than raycasts- Wind ripples are shading, not geometry- Two fields can overlap in world space but will not exchange sandThe C# scripts, the compute shader, the surface shader and the documentation in this package were written with an AI coding assistant (Anthropic's Claude, via Claude Code) working inside the Unity project, under my direction.How it was used:- I specified the behaviour I wanted - sand that displaces, holds an angle of repose, and drifts in wind - and the assistant drafted and iterated on the implementation.- Every change was compiled and run in the editor. Behaviour was verified against measurements taken in play mode rather than accepted on description: the pile slope was measured against the configured angle of repose, the total height field mean was tracked over minutes to prove the wind pass conserves mass, and frame timings were captured on the actual demo scene.- Several bugs were found and fixed this way, including a wind term that leaked mass until cells reached -16,000 m, and a deformer interaction that dug a crater around stationary objects. Both were found by looking at the running scene, not by reading the code.- Structure, naming, tuning values and the final call on every design decision were mine.No AI-generated art assets are included, because there are none to generate: this package ships no textures, meshes, audio or models. The rock and sand surfaces, the dune shapes and the boulder geometry are all produced procedurally by the shaders and scripts at runtime.




