[ForgeLab] SeaForge: Now with More Realistic Ocean Surfaces and Underwater Worlds

Plugins + Scripts [ForgeLab] SeaForge: Now with More Realistic Ocean Surfaces and Underwater Worlds

Download [40.68 MB]

ForgeLab
Things VAM did not have, built so that dropping them on an atom is the whole setup.​

🧩 What the line is for: building the things that are not there

Or maybe some of these things did exist before, but even for me, they were simply too complicated to actually use.

Which is also why nothing here is a prop pack, and nothing here is a simplified version of something else: there was nothing to simplify. These are capabilities added to VAM, generated in code at runtime, with no Unity in the loop and nothing extra for you to install.

The design philosophy: two halves, and the whole point is that you never have to pick one

Plugins usually choose. Either it is simple and you find its ceiling in an afternoon, or it is powerful and you spend that afternoon reading before anything appears on screen. Refusing that choice is the shape of this entire line.

  • 🔌 If you just want to play, it is already done. The test we hold ourselves to is specific: load the plugin, do nothing else, and the right thing is on screen. No asset to find, nothing to model, nothing to point at anything. If you have to configure it before it works, we got the defaults wrong, and that is a bug on our side rather than a step on yours.
  • 🎛️ If you are building something serious, the ceiling is a long way up. Nothing is hidden to keep a panel tidy, and no control gets deleted because the list got long. Every parameter is an ordinary VAM storable, so all of it is drivable from Timeline, from triggers, and from other plugins.

A player never meets the complexity. A creator never has to fight the simplicity.



🧰 The line so far

PluginWhat it is
💡 Lumen ForgeVolumetric light you can see. Nine plugins across whole-sky shafts, window god rays, follow spots, full stage rigs and cold pyro, generated in code, spending none of VAM's six pixel lights unless you ask.
🦊 Tail ForgeEvery kind of tail, in one plugin, with real physics. Drop it on a Person and it is already moving.
💧 Steam ForgeSteam off her skin, water running down it, and room-scale volumetric fog that takes the shape of anything already in your scene.
🔷 Glass ForgeGlass that reflects the actual room, bends what is behind it, fogs over so you can wipe it with a hand, and breaks when you hit it. Flat, curved, or a tube around her.
🏖️ Sea ForgeA beach that remembers. Sand that takes her weight and keeps the shape, a sea that wets it, foams on it and comes back for the prints, and sand on her skin that falls when she moves and comes off under your hand. Generated from one Empty atom, no asset.

More in the line. Each one ships finished, plug and play, and measured.​

🏖️ SEAFORGE 🏖️
V1.2
Every beach so far has looked like one. This one feels like one.
Sand that takes her weight and keeps the shape. A sea that comes back for it.
Sand on her skin that falls when she moves and comes off under your hand.
And now the sea goes under: two underwater stages, with fish that know she is there, and a sea that mirrors your sky.
Five plugins. Drop them in and it is already happening.

❤️ Made for the VAM community
Part of ForgeLab by Shadow Venom.
​

Hero.jpg

Env_Aqua 01.jpg

Env_Deepsea 01.jpg




🆕 v1.2 : EnvAqua · EnvDeepSea · PropNet · the sea mirrors your sky
The update notes, with every price, the charts and the three factory nights behind them : SeaForge v1.2 — the sea goes under​


🌅 Late in the day. The light has gone low and gold, and the sand is still warm from the afternoon in a way you can feel through your palms.

She comes up out of the water toward you, unhurried. The sea does not want to let her go: it runs off her in sheets, it climbs her calves one last time, the surface behind her is still ringed where she pushed through it. Every step she takes up the beach leaves a print, and the prints change as she comes: sharp and shallow in the wet band, then deeper and softer where the sand is dry and loose and gives under her.

She lies down beside you and the sand takes her. Not on top of it, into it: the beach sinks under her hips and her shoulders, the edge of the hollow slumps a little as it settles, and the shape she makes is the shape of her.

When she rolls toward you the sand comes with her. It is on her back, the backs of her thighs, packed dark and heavy where her skin is still wet, dusted fine and pale where she has dried. You reach over and brush her shoulder. Where your hand goes, the sand goes. She laughs and shakes it out of her hair, and for a second the air between you is full of it, catching the light.

Then a wave you did not see coming reaches all the way up. It slides under her feet and stops, lace-edged, and when it pulls back it takes half of her footprints with it and leaves a line of foam on the sand that will be gone by the time the sun is.

Tomorrow the beach will be smooth again. Tonight it remembers.

Now count how much of that we could never do before. The ground did not move: lie down on a CUA beach and you lay on stone with a sand texture. The sea never came up the beach and never took anything back. Nothing stuck to her, nothing fell off her, and your hand had never once changed what was on her skin.

The scene looks like a beach. It never feels like one.


SeaForge is the sand, the sea, and what her body leaves in both.

Five plugins now. Two go on the beach and on her. Two build an underwater stage, sunlit or deep, around one Empty. One is a net that gives when she hits it. None of them asks you to model anything, bake anything, or find a single asset. Add them and it is already happening.

And every part of it can be switched off independently, including all of it.
​



🏖️ THE SAND
It takes her weight, and it keeps the shape
EnvBeach · goes on an Empty atom. The atom is the middle of the beach.​

SF01.jpg


Sand, until now, was a CUA: a texture on a floor. This is a field: a layer of sand with a thickness, sitting on your scene's floor, that every part of a body pushes into.

  • 🦶 Prints where she touches, as deep as she pushes. Feet, shins, hips, the length of a thigh or a forearm. Dry sand gives about 7 cm under a foot; wet sand, packed by the sea, gives about 1.5 cm and holds a sharper edge. Nothing is stamped from a library. The mark is the body, where the body was.
  • ⏳ Then the sand does what sand does. The rim of a print slumps to the angle of repose, dry and wet at different angles; loose edges creep; the sharp shape she left goes soft the way it does on a real beach after a minute. Settling runs on its own clock, so a print an hour old and a print a minute old do not look the same.
  • 🛏️ Lie down and the beach takes you. The whole body prints, not just the feet. Get up and the hollow stays, edges settling, until the sea reaches it.
  • 🏔️ A beach, not a plane. It rises inland, falls seaward, undulates a little, and every one of those is a slider. Terrain relief off gives you a perfectly flat one if that is the shot.
  • ✨ It reads as sand at every distance. Grain, glitter, the dark minerals, the broad wet sheen: the surface is built so that a close-up and a wide shot are both the same sand. Colour it, dry and wet, with two pickers.

💡 The Empty atom is the beach. Put it where the action is rather than stretching the beach to reach the action: the sand is finest, and the prints sharpest, near its centre.



💧 WET AND DRY
The line the sea draws on the sand
EnvBeach, same plugin. One band of beach that is not the same sand as the rest.​

SF06.jpg


Look at any beach and the first thing you read is not the sea. It is the line where the sand changes: dark and packed and shining below it, pale and loose above it. That line is what tells you where the water has been, and it is the thing a sand texture can never have, because it moves.

  • 🌊 The sea writes it. Every wave that runs up the beach leaves a band of wet sand behind it, and the wet climbs a little above where the water stopped, the way it does when sand draws water up into itself. The band is wherever the sea has actually reached, wave by wave, not a stripe you painted.
  • 🕰️ And the sand remembers it. Wet sand dries out over the minutes after the water leaves, from the top of the band down, so a beach that the sea has pulled back from shows exactly how long ago it was there. Wetness memory is a switch; off, the band snaps to the water and forgets.
  • 🪞 Wet sand looks like wet sand. Darker, glossier, smoother: the grains pack, the surface loses its fine ripple, and it takes a sheen off the sky and your lights. Dry sand next to it stays matte and loose and paler. Two colours, two speculars, and the boundary is where the water decided it is.
  • 🦶 It changes what a body does to it. A foot sinks about 7 cm into dry sand and holds a soft edge; the same foot in the wet band goes in about 1.5 cm and holds a crisp one. Walk from the water up the beach and your own trail shows the change.
  • 🧴 And what it does to her. Sand from the wet band packs onto her skin dark and heavy; sand from the dry beach dusts on pale. SkinBeach reads the same wetness the beach does.



🌊 THE SEA
It comes back for everything
EnvBeach, same plugin. Draw the sea is one switch.​

SF05.jpg


The sea, until now, was a CUA surface you placed next to the sand and hoped nobody walked to the edge. This one is part of the same field. It knows where the sand is, the sand knows where it is, and the two of them keep a running account of who was where.

  • 🌊 The swash comes up the beach on its own rhythm, cusped along the shore the way real run-up is, reaching further on some waves than on others, and every wave leaves the wet band above described a little higher or a little lower than the last.
  • 🧹 It erases. Prints inside the wet band are worn down a little by every wave that crosses them. Walk along the waterline and watch the sea take your trail back, one wave at a time.
  • 🫧 Foam is a field, not a sticker. It is born where the wave breaks, carried in on the bore, left behind as lace when the water drains, and it dries on the sand or is picked up again by the next wave. It piles up where the water slows, exactly where foam piles up on a beach, and the front of it is never a hard line.
  • 💧 When she is in the water, the water answers. Bubbles stream off her limbs and cling to her for a while, rings spread from wherever she moves, and a fast move throws a sheet of spray. Each is its own switch, and each is free when it is off.
  • 🌅 Swell, breakers, glitter, a horizon. The surface itself: rolling swell with a direction and a spread, breaker foam on the crests, sun glitter you can tighten or loosen, three colours from the shallows to the horizon, and a render queue slider for when it has to sort against glass.
  • 🪞 v1.2 : it mirrors your sky. The sea reflects the skybox that is actually in your scene, the sun on the water is the sun in that sky, and under the swell runs a wind sea : short chop with a wind speed and a direction, so the reflection breaks the way it does on real water. Physical optics is the default now; Classic, the v1.1 look, is one chooser away on the SEA page. +0.17 ms at 8K, mid framing.

Sea_01.jpg



💡 Turn the sea off and no water reaches the sand: the surf stops, nothing new gets wet, and what was wet dries at the drying rate you set. Your waterline and swash settings are kept and come back with the sea.



🧴 ON HER SKIN
The beach comes with her
SkinBeach · goes on a Person atom. Finds the beach by itself.​

SF07.jpg


Sand does not stay on the beach. It gets on her, and it gets on her where she touched it.

  • 🫳 Contact is what sticks it. Wherever her skin goes below the surface of the sand, sand comes back up with it. The longer she stays, the more she carries. Nothing is painted on; it is the beach's own height field read against her body, so a shoulder that never touched the ground stays clean and the hip that took her weight does not.
  • 💦 Wet skin holds it darker and heavier. Where she is still wet from the sea the sand packs into clumps and darkens; where she has dried it sits as a fine pale dust. The wet look is hers to tune: darkening, colour, how much it clumps.
  • 🔬 It is sand up close. Grains with a size and a relief, clumps with a scale, dust between them, lit by your scene's lights. Coverage is one slider if you want less of it.
  • 👙 Clothing keeps it off. Scan what she is wearing once and covered skin stays clean, per item and per part, with a soft edge at the hem. Untick a wet T-shirt and it collects sand like skin does.



🖐️ OFF HER SKIN
It falls when she moves. It comes off under your hand.
SkinBeach, same plugin. Three switches, all off until you want them.​


This is the part you will keep coming back to, because it is the part that answers you.

  • 🖐️ Wipe-off. Her hands, or yours, sliding over her skin take the sand with them. Brush her shoulder and the shoulder is clean where the hand went and sandy where it did not. In VR that hand can be your own. It is the first thing in this line where somebody else's touch changes what is on her.
  • 💃 Shake-off. Motion sheds sand: a fast rise, a turn, a shake of the hair, and it leaves her, more from dry skin than from wet, which holds on. Leave it off while she lies in the sand collecting it, then switch it on the moment she gets up. That is a shot, and the switch is on the panel for exactly that reason.
  • 🌬️ Airborne sand. What comes off her does not vanish. It becomes grains in the air, with weight and drag and the light through them, thrown in the direction the limb was moving.

🎬 The switches that are really directing handles

Everything above is an ordinary VAM storable, so all of it is a Timeline cue. The ones worth knowing by name:

  • 🎯 Shake-off ON at the frame she rises. Everything she gathered leaves her at once.
  • 🧹 Clear all marks (EnvBeach) between takes; Clear the sand off the skin (SkinBeach) likewise.
  • 🦶 Stamp the whole body now: she was posed onto the sand already lying there, and you want the beach to know it without her moving.
  • 📐 Level the sand under the person: she lies on a slope and you want the beach flat where she works, and free to rise beyond her.
  • 🌇 Time of day: day, night, or your own. One dropdown moves the built-in light, the sky and the exposure together.



🏄 PUT THEM TOGETHER
The five-minute beach.​

  1. 🏖️ Empty atom where the beach should be → EnvBeach. Sand, sea and surf are there. Rotate the Empty so +Z points inland; the shoreline follows.
  2. 🚶 Walk her onto it. Prints appear. Lie her down. The hollow appears.
  3. 🧴 SkinBeach on her. It finds the beach by itself. Sand is on her where she touched it.
  4. 🌇 Time of day on the LIGHT page, or leave it on custom and light it yourself. Name one or two of your scene's lights as Accepted light A/B and the sand takes their colour and their shadow.
  5. 🖐️ Switch on Shake-off and Wipe-off when the scene has motion in it. They ship off because a beach where nothing has happened yet has nothing to shed.

Then wait for a wave. The beach is at its best after the sea has been over it once.



☀️ WORKS WITH THE REST OF THE LINE​

  • ☀️ LumenForge SkyRay puts the sun over it: full-screen shafts cut by your palms and rocks, and cloud shadows drifting across the sand. The shot at the top of this page is the two of them together. EnvBeach's own built-in light and SkyRay's direction are set by eye to match, and a beach is where that takes ten seconds.
  • 💦 SteamForge SkinWater on the same Person: water running down her, sand packing where it is wet. Two Skin plugins, one body, and both carry a Render queue slider for the order they draw in.



🐠 BELOW THE WATERLINE
The sunlit shallows, and the fish that live there
EnvAqua. One Empty, its own plugin, its own bundle.​

Env_Aqua 02.jpg

Env_Aqua 03.jpg



v1.1 said where the sea was going next, and this is it. Add an Empty, load EnvAqua.cslist, and a sunlit underwater stage builds around it : a sand bed that takes impressions and lets them settle, a coral reef with its opening toward you, seaweed and seagrass in the current, suspended motes, light curtains falling from a surface overhead that carries the same wind sea the beach has, seen from below.

  • 🏖️ The sand is the beach's sand. Press into it and it keeps the shape; the edges round off and slump on their own; lift a limb out and it sheds a soft cloud of haze and heavier grains that settle back. Recovery is a half-life you set, up to a day, and it ships off so a mark stays until you clear it.
  • ✨ Caustics on her. A caustic light aimed at the performance area, natural patterns or crossed bands, in a colour you choose, moving with the water. The seabed gets its own. And one native scene light of yours can shadow the sand : pick it, and the sand and every impression in it receive that light's real shadows.
  • 🐟 The nearby school knows she is there. A bounded, independent group that lives in the water where she performs. Every fish keeps its distance : walk toward them and the school parts and closes behind you; stand still and it drifts back. Behaviour → Dance along makes it pick up her movement and swim with it, which is one trigger in a choreography and one trigger back. Three species on one chooser : silver reef fish, clownfish, or jellyfish, and the jellyfish come with their own locomotion, a power stroke, a recovery, a coast.
  • 🫧 A breath from her lips is one action, placed from the mouth with a positioning aid you switch on to set it and off when you are done.
  • 🐠 The distant schools are the backdrop : small shoals in the middle distance that turn and glint, and cost almost nothing.
  • 🙅 None of it asks her for anything. The school reads her body and never pushes on it; the sand applies no force to her. Her physics are exactly what they were before you added the plugin.

💡 The reef opening faces the Empty's +Z. Cameras that pull back should pull back through it; that is what it is for.



🌑 THE DEEP
Where the colour of the water is the whole mood
EnvDeepSea. One Empty, its own plugin, its own bundle.​

Env_Deepsea 02.jpg


Deep down there is no surface worth drawing, and what moves is snow. Add an Empty, load EnvDeepSea.cslist : dark water with a visibility you set, marine snow and fines drifting on a current with a heading, a slow upwelling, and a mottled light far overhead : the beach's wind sea seen from a long way below, with a sun glow and glitter in the direction the caustic comes from.

  • 🎨 Colour transition is one slider between two endpoints you can both edit, blue-black at one end and red-black at the other; the jellyfish, the bubbles and the caustic follow the palette or keep their own colour. Artistic colour, not lighting : keep her key light.
  • 🔦 The caustic lights only the performers. A cookie light on a stage would paint every rock and prop with the same ripple. Cookie on performers only keeps it off everything that is not part of a Person atom : rocks stay rocks, she ripples. A name list keeps it on something by name (shark, rays for a stage's animals), and a host that owns render layers for its set can name those layers instead of having anything moved.
  • 〰️ The seabed has a current. Ripples lie across the current heading, 12 cm ripples on 95 cm megaripples, dark detritus in the troughs near the camera, lit from the caustic's direction. The classic sediment look is one chooser away.
  • 🪼 Jellyfish and mouth bubbles, the same creatures as the shallows', in the deep palette, and they run with the sand off.

💡 Aqua and DeepSea are stages, not a dive : each on its own Empty, one at a time, each with its own Master Switch.



🏐 THE NET
It gives when you hit it
PropNet. One Empty.​

Prop_Net.jpg


Add an Empty where the net should stand, load PropNet.cslist. Posts, tape and net appear at regulation beach dimensions, from nothing : no model, no bundle of geometry. Walk a Person into it and the cords stretch around her, hold, and snap back when she steps away; a hard shove makes the cord let go of her rather than dragging the whole net across the court. It settles still on its own and sleeps when nothing is touching it.

💡 It collides with Person bodies. A ball is wired to it by trigger, not simulated by the net.




SF08.jpg


🚀 HOW TO USE​

  • 🏖️ EnvBeach → add an Empty where the middle of the beach should be → Plugins → Add → EnvBeach.cslist. The beach appears around it, sea included.
  • 🧬 There is no beach asset. The whole beach is generated from that one Empty. No mesh to import, no prefab, no CUA to find, nothing to keep in sync: the sand, its relief, the waterline, the sea and the surf are all built in code at load from the sliders on the panel. Which is the point rather than a curiosity. A prefab beach is the shape somebody else chose; this one is whatever you set, and every one of those settings is a storable. Wider, steeper, flatter, a different waterline, a different sea, a different colour, at run time, from a trigger, halfway through a scene. You are not decorating a beach. You are specifying one.
  • 🧴 SkinBeach → select the Person → Plugins → Add → SkinBeach.cslist. It finds EnvBeach on its own. With no EnvBeach in the scene, set Sand height from to the manual slider and give it a floor height.
  • 🐠 EnvAqua → an Empty where the bottom of the sand should be, its +Z toward the camera → Plugins → Add → EnvAqua.cslist. The sunlit stage builds around it, fish included.
  • 🌑 EnvDeepSea → the same, with EnvDeepSea.cslist. Run one underwater stage at a time; each has its own Master Switch.
  • 🏐 PropNet → an Empty where the net should stand, its rotation facing the court → Plugins → Add → PropNet.cslist. Posts, tape and net appear; walk her into it.
  • 🧭 Same grammar as the rest of the line. Env-plugins go on an Empty, Skin-plugins go on a Person, exactly like EnvFog and SkinWater. If you have used SteamForge you already know where everything is.
  • 🔌 Master Switch on every page, and one switch in front of each thing that costs: the sea, the foam, the bubbles, the splash, the ripples, the thrown sand, the relief. Off is off.
  • 👥 Several people? All Person atoms is on out of the box: everyone in the scene leaves prints, up to four. Untick it and it is the one you pick in the dropdown.
  • 🎛️ Everything is a normal VAM storable, so every switch and slider is drivable from Timeline and triggers.
  • 📋 Both plugins have a Copy report button. If something does not appear, paste that into the thread instead of describing it. It prints the version, what is bound, every gate, every control's current value and the live counts, and it usually answers the question in one message.



Reference for scene creators building on top of the plugins. If you only play, nothing below is needed: the panel is the whole interface.

Every control below is an ordinary VAM storable on the plugin: address it from Timeline, triggers or another plugin as plugin#N_ShadowVenom.EnvBeach / plugin#N_ShadowVenom.SkinBeach followed by the id. Floats are sliders, bools are switches, choosers take the option string exactly as written (the leading digit is the part that matters). Shown while is the panel section the control belongs to; the parameter works whether or not it is currently on screen. Ids are frozen: a scene saved today will restore in every later version.

v1.2 additions

EnvBeach · SEA page
idtypedefaultrange / choiceswhat it does
seaOpticschoice1 Physical0 Classic (the V1 look) · 1 Physical (mirrors the scene's sky, as shipped)Which sea : the v1.1 painted sky colour, or a mirror of the scene's own skybox with a wind sea under the swell. The plugin reads the leading digit, so the old option text still works from a trigger.
seaWindSpeedfloat6m/sThe wind sea's wind. Changes the look, not the cost (3 / 6 / 12 measure the same). Physical only.
seaWindDirDegfloat0degrees, 0 = onshoreWhere the wind comes from. Physical only.
seaChopAmountfloat10 … 3How much of the wind sea's chop reaches the surface. Physical only.
seaSkyMirrorViewboolfalseA debug view : the pure mirror, nothing else. For checking which sky it found.
lightSunFollowsSkyboolfalseLIGHT page : aims the beach's built-in sun where the sun in the mirrored sky actually is. The sea does not need it; the sand's glitter does.
seaRebuildSkyactionRe-detect and re-copy the sky now (after swapping skyboxes at run time).
seaCaptureABactionWrites a Classic / Physical pair of screenshots for comparison.

SkinBeach · retired in v1.2 : skinSandSource, skinSandBaseYM, skinSandThicknessM, skinStickMode and the action RescanSand are no longer registered; a scene that still writes them is ignored, not broken, and a trigger wired to one of them shows as missing.

EnvAqua · EnvDeepSea · PropNet : addressed as plugin#N_EnvAqua, plugin#N_EnvDeepSea and plugin#N_ShadowVenom.PropNet. The triggers you will reach for first : interactiveFishBehaviour (Natural swimming · Dance along), interactiveFishAppearance (Silver reef · Clownfish (Nemo) · Jellyfish), AquaJellyfishPreset, AquaExhaleBubbles, AquaClearSandMarks, AquaClearWake, sandShadowLight; deepColourBlend (0 … 1 between deepColourA and deepColourB), deepSeabedStyle, deepOverheadStyle, deepCookieExcludeCUA, deepCookieAlsoLights, DeepClearSand, DeepClearWake.

EnvBeach (on the Empty atom)

SAND
idtypedefaultrange / choiceswhat it does
beachReliefOnbooltrueTerrain relief
sandColourDrycolorDry sand colour
sandColourWetcolorWet sand colour
sandCompactionDarkeningfloat0.320 .. 1Compaction darkening (dry sand)
sandCompactionPalingfloat0.70 .. 2Compaction paling (wet sand) (wet)
sandGrainDetailfloat10 .. 1.5Grain detail (0 = flat)
sandGrainSizeMfloat0.00060.0002 .. 0.004Grain size (m)
sandGrainColourVarfloat0.550 .. 1.6Grain colour variance
sandDarkMineralFracfloat0.050 .. 0.3Dark mineral fraction
sandMicroOcclusionfloat0.120 .. 0.8Micro-occlusion
sandGlitterStrengthfloat40 .. 14Glitter strength (0 = off)
sandGlitterFractionfloat0.30 .. 1Glittering grain fraction
sandGlintSizefloat0.340.05 .. 0.9Glint size (fraction of a grain)
sandGlintThresholdfloat0.860.3 .. 0.995Glint threshold (higher = rarer)
sandFacetTiltSpreadfloat0.550.05 .. 1.5Facet tilt spread
sandDepthMfloat0.120.07 .. 0.2Sand depth (m)
sandDetailWavelengthMfloat0.090.005 .. 1Coarsest detail wavelength (m)
sandDetailSlopefloat0.1350 .. 1.2Detail slope
sandDetailOctavesfloat81 .. 8Detail octaves
sandDetailRollofffloat0.860.4 .. 1Slope roll-off per octave
wetSmoothingfloat0.880 .. 1Wet sand smoothing (0 = off) (wet)
sandSwashMarksfloat00 .. 2Swash marks (0 = off)
sandSwashMarkWavelengthMfloat0.220.03 .. 1.5Swash mark wavelength (m) (swashmarks)
sandSwashMarkStretchfloat91 .. 30Swash mark stretch along the shore (swashmarks)
sandRimPowerfloat30.5 .. 12Rim power
sandRimStrengthfloat0.350 .. 2Rim strength
sandSheenPowerfloat122 .. 80Broad sheen power
sandSheenStrengthfloat0.10 .. 1Broad sheen strength
beachRiseMfloat0.50 .. 3Beach rise inland (m)
beachLevelBandMfloat40 .. 16Level band from the water (m)
beachRiseRunMfloat141 .. 30Rise runs over (m)
beachRiseCurvefloat1.60.5 .. 4Rise curve (higher = flatter near the water)
beachReliefRisefloat0.190 .. 1Relief: rise intensity (relief)
beachReliefDipfloat0.30 .. 1Relief: dip intensity (relief)
beachUndulationWavelengthMfloat2.20.2 .. 12Undulation wavelength (m) (relief)
beachUndulationOnsetMfloat0.70.2 .. 20Undulation reaches full at (m inland) (relief)
fieldCoreSizeMfloat242 .. 32Core size (m)
guideShowCorebooltrueShow the core's edge
fieldBackdropMfloat12024 .. 1000Backdrop: sand reaches (m across)
fieldResolutionfloat1536128 .. 2048Field resolution
fieldMeshResolutionfloat51232 .. 2048Ground mesh resolution
sandMaxAnisotropyfloat121 .. 24Max anisotropy

FOOTPRINTS
idtypedefaultrange / choiceswhat it does
printTraceModechooser1 live0 OFF (no marks) / 1 liveMarks in the sand
bodyAllPersonsbooltrueAll Person atoms
personchooser(atom uids)Person (oneperson)
bodyLeavesPrintsbooltrueBody leaves prints
bodyVRHandsboolfalseVR hands touch the sand
bodyVRHandRadiusMfloat0.0550.01 .. 0.2VR hand radius (m) (vrhands)
bodyVRHandOffsetMfloat0.03-0.1 .. 0.2VR hand contact offset (m) (vrhands)
printRimHeightMfloat0.020 .. 0.2Rim height (m) (trace)
printSinkDryCmfloat70.2 .. 20Sink depth in dry sand (cm) (trace)
printSinkWetCmfloat1.50.2 .. 20Sink depth in wet sand (cm) (trace)
printHalfWidthMfloat0.050.01 .. 0.3Print half-width (m) (trace)
printHalfLengthMfloat0.0750.01 .. 0.4Print half-length (m) (trace)
printFeatherMfloat0.030.001 .. 0.3Print feather (m) (trace)
printRimWidthMfloat0.050 .. 0.4Print rim width (m) (trace)
printEdgeRoughnessMfloat0.020 .. 0.2Print edge roughness (m) (trace)
bodyContactBandMfloat0.050.002 .. 0.15Contact band (m above ground) (trace)
bodyFootPrintHalfLengthMfloat0.0750.01 .. 0.3Foot print half-length (m) (trace)
bodyContactWidthXfloat10.2 .. 3Body contact width (x collider radius) (trace)
settleModechooser3 both0 OFF (raw stamp) / 1 repose / 2 creep / 3 bothSettling (trace)
settleCohesionchooser1 by depth0 uniform / 1 by depthCohesion (settle)
settleReposeDryDegfloat345 .. 85Repose angle, dry sand (deg) (reposedry)
settleReposeWetDegfloat755 .. 88Repose angle, wet sand (deg) (settle)
settleAvalancheRatefloat0.350 .. 0.9Avalanche rate per step (settle)
settleRimSlumpRatefloat0.250 .. 0.9Rim slump rate per step (settle)
settleCreepRatefloat0.150 .. 0.9Creep rate per step (creep)
settleStepsPerSecondfloat1200 .. 480Settle steps per second (settle)
settleCreaseResidualDegfloat530.2 .. 70Crease residual (deg per texel) (trace)
sprayOnbooltrueThrown sand
sprayQueuefloat3001-1 .. 5000Render queue (-1 = shader default, above the sea) (spray)
sprayAmountfloat10 .. 3Amount (spray)
sprayLiftMSfloat0.80 .. 4Lift off the ground (m/s) (spray)
sprayLifeSfloat0.450.1 .. 2Time in the air (s) (spray)
sprayBurstSpreadSfloat0.060 .. 0.3Burst spread (s) (spray)
sprayGrainSizeMfloat0.0040.001 .. 0.02Dry grain size (m) (spray)
sprayClumpSizeMfloat0.0120.002 .. 0.06Wet clump size (m) (spray)
sprayDragGrainfloat90.5 .. 20Air drag, dry grain (1/s) (spray)
sprayDragClumpfloat1.40.2 .. 20Air drag, wet clump (1/s) (spray)
sprayWaterDropsfloat0.220 .. 1Water drops (wet sand only) (spray)
sprayDragWaterfloat30.2 .. 20Air drag, water drop (1/s) (spray)
sprayBrightnessfloat0.750 .. 2Brightness (spray)
sprayClumpSheenfloat0.160 .. 1Wet clump sheen (spray)
sprayGlintFracfloat0.180 .. 1Glittering grain fraction (spray)
sprayGlintStrengthfloat1.40 .. 4Glint strength (spray)

SEA
idtypedefaultrange / choiceswhat it does
seaOnbooltrueDraw the sea
seaReachMfloat4-16 .. 16Water reaches (m inland)
guideShowWaterReachboolfalseShow the high-water line
seaCapillaryFringeMfloat0.50.02 .. 4Capillary fringe (m)
seaSwashRangeMfloat60 .. 20Swash run-up (m)
seaSwashCuspMfloat200.5 .. 60Swash cusp spacing (m)
seaSwashPeriodSfloat905 .. 300Swash period (s)
seaWashErasureMSfloat0.000975250 .. 0.05Wash erases marks (m/s, 0 = off)
wetModechooser1 from the field0 OFF (no wetness) / 1 from the fieldWet sand
wetMemoryModechooser1 remembers (dries over time)0 none (snaps to the band) / 1 remembers (dries over time)Wetness memory (wet)
wetDryingPerSecondfloat0.010 .. 1Drying per second (dry)
wetMemoryBeyondCorebooltrueWet memory beyond the core (wet)
wetFresnelAmountfloat0.550 .. 2Wet fresnel amount (wet)
wetFresnelPowerfloat41 .. 12Wet fresnel power (wet)
wetDirectSpecularfloat0.250 .. 2Wet direct specular (wet)
seabedReliefAmountfloat0.60 .. 0.8Seabed relief (0 = planar bed)
seabedBarHeightMfloat0.70 .. 2Longshore bar height (m)
seabedBarSeawardMfloat305 .. 200Longshore bar distance (m seaward)
seabedFallPer100Mfloat30 .. 15Shoreface slope (m per 100 m)
seaQueuefloat-1-1 .. 5000Render queue (-1 = shader default, 3000) (sea)
seaColShallowcolorrgb 0.42 0.60 0.60Shallow water colour (sea)
seaColDeepcolorrgb 0.0842 0.3249 0.4453Deep water colour (sea)
seaColHorizoncolorrgb 0.55 0.66 0.72Horizon colour (skypick)
seaLevelMfloat0-1 .. 1Water level offset from the shoreline (m) (sea)
seaDepthScalefloat0.80.05 .. 5Water clarity (m of water) (sea)
seaHorizonMfloat7010 .. 400Horizon band begins at (m) (sea)
seaExtentMfloat00 .. 2000Sea reaches (m across, 0 = follow the sand) (sea)
seaEdgeThinfloat0.350.02 .. 2Swash tongue thins over (m) (sea)
seaTongueSlopefloat0.060.005 .. 0.4Swash sheet thickens by (m per m) (sea)
seaDeepAlphafloat10 .. 1Deep water opacity (sea)
seaSwellAmpfloat0.50 .. 1Swell amplitude (m) (sea)
seaSwellLenfloat111 .. 60Swell wavelength (m) (sea)
seaSwellAnglefloat28-60 .. 60Swell approach angle (deg) (sea)
seaSwellSpreadfloat180 .. 45Swell directional spread (deg) (sea)
seaBreakFoamfloat0.850 .. 1Breaker foam (0 = off) (sea)
seaRippleAmpfloat0.550 .. 3Ripple amount (sea)
seaRippleScalefloat0.90.1 .. 6Ripple scale (m) (sea)
seaRippleSpeedfloat0.350 .. 4Ripple speed (m/s) (sea)
seaGlitterPowfloat2204 .. 800Glitter tightness (sea)
seaGlitterfloat2.20 .. 8Glitter strength (sea)
seaSheenfloat0.20 .. 2Broad sheen (sea)
seaMaxBrightfloat0.850.2 .. 8Max brightness (bloom feed) (sea)

SURF
idtypedefaultrange / choiceswhat it does
foamOnbooltrueFoam (waterfx)
foamBirthfloat70 .. 24Born per second at the bore (foam)
foamBirthWfloat0.350.05 .. 3Birth band width (m) (foam)
foamBirthBreakfloat50 .. 200Born at the breakers (foam)
foamBreakPulsefloat10 .. 1Birth pulses with each crest (foam)
foamPerWavefloat0.60 .. 2Deposited per wave (foam)
foamFadeSfloat302 .. 180Deposit fades over (s) (foam)
foamFrontLipMfloat0.50 .. 2Front lip (m) (foam)
foamLifeSfloat120.5 .. 60Life on water (s) (foam)
foamLifeDrySfloat10.1 .. 20Life once drained (s) (foam)
foamInertiaSfloat1.20 .. 6Coasting (s) (foam)
foamInertiaPushfloat0.250 .. 6Pick-up by the water (s) (foam)
foamFrontConfinefloat10 .. 1Tail never retreats (foam)
foamFrontReachfloat240.2 .. 24Swash breathing reach (x the excursion) (foam)
foamArrivalMinfloat120 .. 40Arrivals merge within (m) (foam)
foamBoreGainfloat10 .. 4Conveyor speed (x) (foam)
foamBoreRelieffloat10 .. 2Bore front relief (foam)
foamBoreWidthMfloat0.40.05 .. 1.5Bore roller width (m) (foam)
foamBoreTonguesMfloat0.10 .. 0.5Bore front tongues (m) (foam)
crestWidthMfloat2.50.3 .. 12Crest foam band width (m) (foam)
crestTailfloat0.70 .. 2Crest keeps its foam (the trail) (foam)
crestTailSfloat1.10.1 .. 4Crest foam lingers (s) (foam)
crestGivefloat0.450.05 .. 1Crest hands foam to the swash (1 = instant) (foam)
crestMinAmpMfloat0.060.01 .. 0.6Crest needs a wave this tall (m) (foam)
crestBreakfloat0.550 .. 1Crest line break-up (foam)
foamRagMfloat0.90 .. 4Lobes reach past the front (m) (foam)
foamRagScalefloat2.60.5 .. 12Lobe scale along the shore (m) (foam)
foamNetCellMfloat0.30.1 .. 6Net eye size (m) (foam)
foamNetWarpfloat0.150 .. 1Filament wiggle (m) (foam)
foamNetPullfloat0.60.05 .. 8Net pull limit (m) (foam)
foamLaceCarryfloat240 .. 24Filament aspect ratio (0 = pinned) (foam)
foamMicroSlopefloat0.20 .. 1Surface slope (RMS) (foam)
foamMicroCMfloat0.40.05 .. 12Surface grain (cm) (foam)
foamMicroPullfloat0.30.02 .. 2Surface pull limit (m) (foam)
foamGlossfloat2.50 .. 3Wet gloss and sky mirror (0 = the sand's) (foam)
foamTransfloat0.80 .. 1Translucency (foam)
bubOnbooltrueBubbles (waterfx)
bubAmountfloat10 .. 1Amount (bubbles)
bubSizeMMfloat1.50.2 .. 20Bubble size (mm) (bubbles)
bubRiseMSfloat0.020.005 .. 0.3Rise speed (m/s) (bubbles)
bubLifeSfloat200.5 .. 60Life (s) (bubbles)
bubClingSfloat40 .. 15Clings to the body for (s) (bubbles)
bubRateHzfloat301 .. 120Emission rate (per limb, /s) (bubbles)
bubDriftMSfloat0.550 .. 2Carried by the water (m/s) (bubbles)
splashOnbooltrueSplash (waterfx)
splashAmountfloat0.250 .. 2Amount when the body moves through water (splash)
splashRiseMfloat0.30.05 .. 2.5Splash height (m) (splash)
splashLifeSfloat0.250.1 .. 2Splash life (s) (splash)
ripOnbooltrueRipples (waterfx)
ripAmpfloat0.40 .. 0.6Amount (slope) (ripples)
ripLenMfloat0.250.05 .. 1.5Ripple wavelength (m) (ripples)
ripSpeedMSfloat0.90.2 .. 4Ring speed (m/s) (ripples)
ripLifeSfloat10.3 .. 10Ring life (s) (ripples)

LIGHT
idtypedefaultrange / choiceswhat it does
lightTimeOfDaychooser0 custom0 custom / 1 DAY / 2 NIGHTTime of day
lightSourcechooser1 built-in only (self-lit)0 scene lights only / 1 built-in only (self-lit) / 2 both (built-in as a floor)Light source
lightYawDegfloat1450 .. 360Built-in light yaw (deg) (studio)
lightPitchDegfloat38-10 .. 89Built-in light pitch (deg) (studio)
lightKeyColourcolorBuilt-in key colour (studio)
lightFillColourcolorBuilt-in fill colour (studio)
skyColourSourcechooser0 built-in fill x gain (tracks day/night)0 built-in fill x gain (tracks day/night) / 1 Sea horizon colour pickerSky colour source
skyGainfloat1.90 .. 6Sky brightness (x the built-in fill)
lightExposurefloat10 .. 2Light exposure
lightAmbientBoostfloat10 .. 4Scene ambient boost
lightAcceptAchooser(atom uids)Accepted light A
lightAcceptAColourbooltrueA: take its colour (lighta)
lightAcceptAShadowbooltrueA: take its shadow (lighta)
lightAcceptBchooser(atom uids)Accepted light B
lightAcceptBColourbooltrueB: take its colour (lightb)
lightAcceptBShadowbooltrueB: take its shadow (lightb)
lightShadowOnlyDepthfloat30 .. 8Shadow-only depth (m) (lightany)
lightRejectAtSourcebooltrueReject lights at the source
sandCastsShadowsbooltrueSand casts shadows

Actions (buttons; fire them from a trigger)
actionwhat it does
RescanPersonsRescan for Person atoms
StampBodyNowStamp the whole body now
WalkShorelineWalk the shoreline (wet to dry)
RescanLightsRescan for light atoms
AlignKeyToLightAlign the built-in key to the named light
LevelSandUnderPersonMeasure the bound Person and level the beach profile out to them
Bench SetupPuts the plugin into its measurement configuration (used by the bench tooling)
ClearSandClear every mark from the sand (same as the Clear all marks button)
RebuildSandRebuild ground, field and sea from the current settings (the Rebuild Env button)

Also registered, not on the panel (instruments, kept as API): beachSeawardDropM, beachSeawardDropRunM, foamBoreSharpness, benchPoolBubbles, benchFillBubbles, benchFillSplash, benchFillRipples, devBubbleLadder, devSplashLadder, crestSharp, foamMicroMix, benchFragmentLoad, benchOverdrawCopies, benchOverdrawShadows, benchSandVisible, settleDirtyRect, devShowSpraySpecies, devDepthMode, devDrawVertexGrid, devShowField, devShowWetFlat, devShowTierDiff, devShowAlbedoFlat, devShowNormalFlat, devShowAttenuation, devShowLightTerms, seaShowEdge, seaShowSample, seaShowFlat, foamShowField, foamShowAhead.

SkinBeach (on the Person atom)

SAND SHELL
idtypedefaultrange / choiceswhat it does
skinShellOnbooltrueSand shell
skinRenderQueuefloat23902000 .. 3200Render queue
skinSandColourcolorrgb 0.976 0.908 0.745Sand colour
skinCoveragefloat10 .. 1Coverage
skinClumpSizeCmfloat50.5 .. 40Clump size (cm)
skinClumpContrastfloat1.80.3 .. 4Clump contrast
skinClumpStrengthfloat0.90 .. 1Clump strength
skinGrainSizeMmfloat0.90.1 .. 5Grain size (mm)
skinGrainFatnessfloat0.550.1 .. 1Grain fatness
skinGrainToneSpreadfloat0.550 .. 1Grain tone spread
skinGrainRelieffloat0.850 .. 1Grain relief
skinGrainLayersfloat21 .. 3Grain layers
skinGrainSizeSpreadfloat0.60 .. 1Grain size spread
skinDustfloat0.30 .. 1Dust between grains
skinUseSceneLightbooltrueUse scene light
skinAmbientFloorfloat0.350 .. 1Ambient floor
skinWetDarkeningfloat0.60 .. 1Wet sand darkening (wetlook)
skinWetColourcolorrgb 0.42 0.30 0.20Wet sand colour (wetlook)
skinWetColourAmountfloat0.550 .. 1Wet colour amount (wetlook)
skinWetClumpingfloat0.90 .. 2Wet clumping (wetlook)
skinRampOnboolfalseHeight ramp (bind-pose Y)
skinRampCentreMfloat0.5-1 .. 2Ramp centre (bind Y, m) (ramp)
skinRampWidthMfloat0.250.01 .. 1Ramp width (m) (ramp)
skinShellOffsetMmfloat00 .. 10Shell offset (mm)
skinViewOffsetMmfloat100 .. 50View offset (mm)

STICKING
idtypedefaultrange / choiceswhat it does
skinLedgerOnbooltrueSand sticks to the skin
skinStickRatefloat30.1 .. 20Stick amount per contact (ledger)
skinStickBandMfloat0.030.001 .. 0.2Stick ramp band (m) (ledger)
skinEdgeBreakupfloat0.350 .. 1Edge break-up (ledger)
skinEdgeBreakupCmfloat2.50.3 .. 20Edge break-up size (cm) (ledger)

SHEDDING
idtypedefaultrange / choiceswhat it does
skinShakeOnboolfalseShake-off (motion sheds sand)
skinShakeThresholdMSfloat0.50 .. 8Shake threshold (m/s) (shake)
skinShakeRatefloat0.040 .. 1Shake rate (per m/s per s) (shake)
skinShakeResidueFloorfloat0.20 .. 0.8Shake residue floor (coverage) (shake)
skinWetResistsShakingfloat10 .. 1Wet sand resists shaking (shake)
skinMotionAverageFollowfloat0.150.01 .. 1Motion average follow (per frame) (shake)
skinWipeOnboolfalseWipe-off (hands or colliders sliding over the skin)
skinWipeReachMmfloat120 .. 80Wipe reach (mm) (wipe)
skinWipeMinSlideMSfloat0.050 .. 2Wipe min slide (m/s) (wipe)
skinWipeRatefloat60 .. 40Wipe rate (per m/s per s) (wipe)
skinWipeResidueFloorfloat00 .. 0.5Residue floor (coverage) (wipe)
skinWipeHandsOnlybooltrueWipe source: the person's own hands only (wipe)
skinHandTagRadiusMmfloat101 .. 60Hand-skin tag radius (mm) (hands)
skinEmitOnboolfalseAirborne sand (what comes off)
skinEmitGrainsPerUnitfloat600 .. 400Grains per unit removed (emit)
skinEmitSpreadMfloat0.070.01 .. 0.3Spawn spread (m) (emit)
skinEmitLifeSfloat1.10.2 .. 4Grain life (s) (emit)
skinEmitGrainSizeMfloat0.00220.0005 .. 0.02Dry grain size (m) (emit)
skinEmitClumpSizeMfloat0.0060.0005 .. 0.05Wet clump size (m) (emit)
skinEmitUpKickMSfloat0.50 .. 3Shake upward kick (m/s) (emit)
skinEmitThrowfloat0.450 .. 1Shake throw (fraction of limb speed) (emit)
skinEmitDragFinefloat90 .. 30Drag, fine grains (emit)
skinEmitDragCoarsefloat1.20 .. 30Drag, wet clumps (emit)
skinEmitBrightnessfloat10 .. 3Grain brightness (emit)

CLOTHING MASK
idtypedefaultrange / choiceswhat it does
skinMaskOnboolfalseExclude clothing-covered skin
skinMaskFitMmfloat121 .. 60Clothing fit distance (mm) (mask)
skinMaskFeatherMmfloat40 .. 30Mask edge feather (mm) (mask)
skinMaskNormalDotMinfloat0-1 .. 1Cover normal dot min (mask)

Actions (buttons; fire them from a trigger)
actionwhat it does
ClearLedgerClear the sand off the skin
ScanHandsScan hands (with the hands clear of the body)
ScanRegionsScan body regions
ScanClothingMaskScan the clothing mask (wear it first)
RefreshClothingListRefresh the clothing list
ClearClothingMaskClear the clothing mask
ReportReport
CopyReportCopy report

Also registered, not on the panel (instruments, kept as API): skinEmitThreshold, skinDevMaxVelocityMS, skinMaskSkipList, liveness, skinShowDev, vertsource, skinSkinMaterialsOnly, skinDevDrawTiming, skinDevTwoSided, skinDevZTestAlways, skinDevDepthOffsetFactor, skinDevDepthOffsetUnits, skinDevShowCoverage, skinDevShowWetness, skinDevRainbow, skinDevLagProbe, Bench sand load, Bench sand verts, Bench sand coverage, Bench sand wetness, Bench motion, Bench hand slide (m/s), Bench cost ladder, Bench shell copies, Bench Measure (write a new number).


The same guidance ships inside the package as README files, in English, Traditional Chinese, Japanese and Korean.​




📊 MEASURED, NOT ESTIMATED
The bench, the method, the numbers, and where a number is arithmetic rather than a reading, it says so.​

A beach is a lot of screen. Sand fills the frame from the foreground to the horizon, and the sea fills the rest, so this is the kind of product that is easy to make expensive and easy to lie about. What follows is the data that drove the defaults, including the rows that are not flattering.

Every row below is marked. MEASURED is a reading off the bench. INFERRED is arithmetic on a reading: useful for planning, not a benchmark.

v1.2 : the bench grew a floor. The v1.1 rows were read against a CPU-bound empty scene (3.41 ms). A GPU cost measured against a CPU floor shows only what sticks out above it, so those rows were lower bounds. The v1.2 rows were read against a scene loaded with GPU ballast until the frame was GPU-bound, four passes per row, over three unattended nights, with a reader that judged the run before anyone chose a number. Where a v1.1 number is kept below, it says so. The method, the charts and the night that found a defect are on the v1.2 update page.



The machine

ItemValue
GPUNVIDIA RTX 5090
Render resolution7680 × 4320 (DSR 8K), fullscreen
MSAA4×
Pixel lights6
VSyncoff
SceneOne Person, lying still at the waterline, camera fixed on a mid framing (sand ≈ 80 % of the frame), VAM UI closed
Baseline frame time3.41 ms with every SeaForge switch off

8K is deliberate. Sand and sea are fill-rate, so the stress test is pixels, and 8K is four times 4K and sixteen times 1080p. A number taken at a comfortable resolution says nothing about the resolution somebody else runs.

The method

A measuring tool drives the run unattended: it sets a configuration, lets it settle 4 seconds, samples 10 seconds, writes a row, restores the previous state explicitly, and moves on. Six passes per configuration; the spread between passes is what decides whether a difference is readable at all.

  • 📏 Frame time, never FPS. Frame time is linear, so it can be added and compared.
  • 🧪 Ablation with explicit restore. Each feature off individually, everything else held, every step putting the previous toggle back by name.
  • ✍️ Pass/fail written before the numbers were read. Every "must change" paired with a "must not change".
  • 🎯 The factory configuration is the measured configuration. The overnight matrix ran on a bench pin; a separate three-pass A/B/A then compared that pin against the exact shipping defaults: −0.04 ms, inside ±0.1. The numbers below are for the beach as it loads, not for a tuned-down version of it.
  • 🧯 UI closed, camera parked. VAM's own open panel costs frames.

The honest part

At 8K this bench was GPU-bound for the sand and the sea, which is where their cost lives, and CPU-bound for the body work, which is where its cost lives. That is the useful arrangement, but it means the two families of numbers travel differently to your machine; the next spoiler is about that.

The single most important thing on this page is not a number, it is which way each cost scales.

EffectWhere the cost livesLower resolution helps?Weaker GPU costs more?Basis
Sand (surface, relief, prints)GPU fill-rateYes, roughly with pixel countYesMEASURED
Sea (surface, swash, foam field)GPU fill-rateYesYesMEASURED
Body work (prints, thrown sand, bubbles, splash, ripples)CPU, per PersonNoNoMEASURED
SkinBeach (shell, sticking, shedding)GPU, small and fixedBarelyBarelyMEASURED

Screen coverage is the multiplier, and it was measured rather than assumed

Same scene, same settings, four framings. MEASURED

FramingSand in frameΔ frame time
Far48 %+1.33 ms
Grazing53 %+1.48 ms
Mid (the bench framing)81 %+4.15 ms
Close100 %+5.24 ms

Pull the camera back and the bill drops to a third. Move in and every pixel gets dearer as well as more numerous: 0.028 ms per percent of screen at the far framing, 0.052 at the close one. If you are hunting frames on a beach, framing is the first lever and it is free.

What we are not going to do

Print a 4K or 1080p number for a card we do not have. The fill-rate rows scale with your pixel count and your card's fill-rate, and the body rows do not scale with either. Read the table above for the direction, and the next spoiler for the milliseconds on this machine.

All figures are frame-time increase over the same scene with every SeaForge switch off. Bench conditions as above, mid framing, one Person.

WhatΔ frame timeBasis
The whole beach, factory settings (sand + sea + surf + prints, Physical optics)+6.46 ms over the GPU-bound floor. The v1.1 page printed +4.18 against a CPU floor : a lower bound. The v1.1 package and the current Classic sea were re-measured side by side on the new bench and agree within 0.03 ms; nothing regressed, the old bench could not see the whole bill.MEASURED v1.2
of which Physical optics (the sky mirror + the wind sea) over the Classic sea : mid / far / grazing+0.17 / +0.17 / +0.11 ms (at mid : 0.16 the mirror, 0.02 the wind sea)MEASURED v1.2
Sand only, sea switched off+2.23 msv1.1 bench, CPU floor : a lower bound
The sea itself (surface, swash, foam)+1.93 msv1.1 bench, CPU floor : a lower bound
EnvAqua, shipped settings, her at chest height (looking up 0.92 · at the sand 1.08 · low 1.33 · wide 1.32)+1.31 msMEASURED v1.2
EnvDeepSea, shipped settings, her at chest height (looking up 0.65 · at the sand 1.98 · low 1.50 · wide 1.66)+1.90 msMEASURED v1.2
DeepSea's water column (the depth-aware haze)+0.38 ms (0.34 if your scene already renders a depth texture)MEASURED v1.2
DeepSea's seabed ripples over classic sediment · Aqua's wind-sea surface over classic ripples+0.33 to +0.44 ms · +0.07 to +0.08 msMEASURED v1.2
PropNetNot on the bench this round. Its own Report prints what it costs on your machine.NOT BENCHED
Plugin loaded, Master Switch off+0.01 ms (the noise floor)MEASURED
A person in the water: bubbles, splash, ripples, at a held population of 2048 / 12 / 12+0.085 ms (ripples 0.065, bubbles ≤ 0.02, splash ≤ 0.02)MEASURED
Two more per-pixel scene lights on the sand+0.035 to 0.055 msMEASURED
SkinBeach, factory (shell + sticking)+0.065 msMEASURED
+ Shake-off + Wipe-off (hands, 44 capsules)+0.01 to 0.025 msMEASURED
+ Airborne sand+0.000 ms on the frame; it polls at 9.6 HzMEASURED
Clothing mask0MEASURED
SkinBeach, everything onunder 0.2 ms (v1.2 bench : every row within 0.05 ms of the skin-off row; the table's own 0.2 ms drift over seven minutes is the bound, so that is what we print)MEASURED v1.2

The ranking

Beach (6.5) > DeepSea (1.9) > Aqua (1.3) ≫ everything on her body​

The beach itself is the bill, and both underwater stages are under 2 ms at the shot you will take. Everything that happens on and around a body, the prints, the thrown sand, the bubbles, the splash, the sand on her skin, the fish, adds up to less than a fifth of a millisecond at 8K. Leave all of that on. If a beach scene is heavy, it is the sand and the sea, and both have a give-back list.

Several people

The body work is per Person, so with All Person atoms on it grows with the head count. The bench had one. Four people are four times the body row, which is still under a millisecond, and the sand and sea do not care how many there are. INFERRED from the one-person row; we have not benched a crowd.

Each row is what you save, cumulatively, at the bench framing. MEASURED

StepSavesWhat you give up
1. Ground mesh resolution 512 → 256 (SAND · Field)−0.96 ms (v1.1 bench)Print geometry is softer. Prints still read.
2. Detail octaves 8 → 4 (SAND · Surface detail)−0.64 msThe finest surface ripple. Hard to see past arm's length.
3. Micro relief off−0.45 msThe small-scale sand relief. Flatter close up.
4. Grain detail → 0−0.15 msThe per-grain relief. Close-ups get flatter.
5. The small ones: crest foam, the pools, the sea's surface ripple, glitter, settling−0.12 / −0.12 / ≈0 / ≈0 / ≈0Each is its own look; three of them are free to leave on.
Steps 2 to 5 together−1.5 ms at mid framingThe beach is still there, and still remembers. The ladder never gets dearer : measured in that order, every step saved something or nothing, none cost.

Underwater

StepSavesWhat you give up
DeepSea : Seabed style → Classic sediment−0.33 to −0.44 msThe current ripples and the detritus in their troughs.
DeepSea : Haze off−0.38 msThe depth-aware water column. The colour stays; the distance stops fading.
DeepSea : Overhead style → Classic mottle−0.07 looking up, −0.03 at herThe wind sea overhead becomes the original mottle.
Aqua : Surface style → Classic ripples−0.08 msThe wind sea on the ceiling becomes the original ripples.
Either stage : wind speed03, 6 or 12 m/s cost the same. Set it for the look.

And one you should not touch for frames

Field resolution is free: 1024, 1536 and 2048 measure within ±0.04 ms of each other. It decides how sharp a print's edge is, nothing else. Lowering it buys you nothing and costs you the prints. MEASURED

Ground mesh the other way is not free: 1024 costs +1.73 ms over 512. The factory value is the one on the knee of that curve.

No leak. A 2.7-hour soak with everything on: the heap floor after each collection was flat from the first hour to the last. Nothing accumulates. MEASURED

The part we will say out loud: at factory settings the beach produces about 2 KB of garbage per frame, which is steady state, not growth. That means Mono runs a full collection roughly every 50 minutes in a scene that is doing nothing but the beach. LumenForge's page describes the same VAM-wide hitch at 43 minutes with a heavy scene and none of our plugins in it; ours moves that clock a little. A typical VAM scene does not run 50 minutes without a load, so for almost everyone this never happens, but if it does, that quarter-second hitch is what it was.

Reloading the plugin does not stack. Ten reloads in a row were measured because an earlier build left 23 MB behind on each; the shipping build does not.

v1.2 : three stages in rotation, 90 minutes each, 5.3 hours. The bench walked her through DeepSea, then Aqua, then the beach with SkinBeach, everything on, and counted meshes, materials, textures, render targets and GameObjects every few minutes : identical at the end of each segment to the start of its last two thirds. Frame time drifted under 0.05 ms per segment and p95 tracked the mean. MEASURED The chart is on the update page.

  1. 🎥 Frame it. Sand in frame is the multiplier on everything. A far or grazing shot costs a third of a mid shot, and it is usually the better picture anyway.
  2. 🕸️ Ground mesh 512 → 256. The biggest single saving, and the prints survive it.
  3. 🌊 Detail octaves 8 → 4.
  4. 💎 Leave the surf, the prints and SkinBeach alone. There is nothing to win there.
  5. 👥 Crowds: the body work is per person. Four people is fine. Twelve is a decision, and the plugin stops at four on purpose.
  6. 🐠 Underwater: both stages are under 2 ms at the shot you will take. If you need some of it back, DeepSea's seabed ripples and its haze are about 0.4 ms each; the fish, the jellyfish and the wind speed are free.

VR

Not benchmarked in a headset. The shape of the cost carries over: the sand and the sea are fill-rate, and VR is where fill-rate hurts, so start with Ground mesh at 256 and raise it only if the prints ask for it. The body work is CPU and should behave as it does on the desktop.

Numbers you can check: both plugins print a full state report with a one-press copy button.
If yours disagrees with this page, that report is the fastest way to show us.
​




⚠️ HONEST NOTES & LIMITS
Up front about the edges, so nothing surprises you.

  • 🏖️ The beach is a shore; the underwater products are stages. The beach's sea is a surface with swell on it, not a volume, and its camera stays above the waterline. EnvAqua and EnvDeepSea each build their own stage on their own Empty : you do not swim down into them from the beach, and you run one at a time.
  • 🪞 Physical optics needs a sky to mirror. A skybox CUA, or any large background sphere with a panorama on it. With none, the sea shows the classic colour and the Report says so. A sky that loads late or is switched on later is found within a few seconds.
  • 🔦 DeepSea's performer-only caustic moves non-performer objects to render layer 26 while it is on, and puts them back when it is off; Aqua's scene shadows borrow a free render layer while a source light is selected, the same way the beach's light rejection does. A plugin that reads object layers, or edits culling masks itself, will see those while they run.
  • 🏐 PropNet was not benched this round. It collides with Person bodies only; a ball is wired by trigger.
  • 🦶 Prints come from the body's joints, not from every vertex. Twelve body segments, each a capsule between two controllers, print the sand: torso, head, thighs, shins, upper arms, forearms, feet. That gives a foot, a shin, a thigh, a hip, a forearm; it does not give individual toes or the crease of a palm. Up close the print is the shape of a limb, which is what a real one is.
  • 🫳 Thin sand and thin limbs. The sand is a layer with a thickness, 12 cm by default, on top of your scene's floor. A forearm pressed into 7 cm of sand reaches the floor underneath it, and VAM's floor is whatever collider your scene has there. Thicker sand (SAND · Sand depth) gives deeper prints; that is a slider, not a limit.
  • 👥 Four people, and the body work is per person. All Person atoms tracks up to four; the rest are counted in the report rather than tracked. The bench was one person; see the numbers section.
  • 🥽 VR hands are a switch, and it ships off. With it on, the player's own hands print, throw sand and wipe her. On a desktop it does nothing and the report says so.
  • 🕐 A garbage collection about every 50 minutes in a scene that does nothing else, at a quarter of a second. Steady-state garbage, measured; not a leak, also measured. Most scenes never get there.
  • 💡 Reject lights at the source edits your scene lights' culling masks. It is how the sand keeps every light but the two you named off itself. Do not combine it with another plugin that edits culling masks (Light Atom Excluder, for one); one of them will win and it will not be obvious which. Leave it off and both are fine.
  • 🪟 Transparent against transparent has no correct order. Sea against glass, thrown sand against the sea. Both carry a Render queue slider. Author's call, per scene.
  • 🎯 The Empty is the centre of the beach, and the beach is finest near it. Prints far from the centre, out in the backdrop sand, are coarser than the ones at her feet. Move the atom to the action.

💬 Found something odd? Want something the beach does not do yet? Post in the discussion. This grew out of two whitebox probes and what the measurements said, and it will keep growing on what you report.



🆕 What's new​

v1.2
  • 🐠 EnvAqua. The sunlit underwater stage : responsive sand, caustics, light curtains, a reef, scene shadows on the sand, and a nearby school that keeps its distance, dances along on cue, and comes as reef fish, clownfish or jellyfish.
  • 🌑 EnvDeepSea. The deep stage : colour transition, snow and fines on a current, the overhead wind sea, a caustic that lights only the performers, ripples across the seabed.
  • 🪞 The sea mirrors your sky (EnvBeach). Physical optics is the default : the sea reflects the scene's own skybox, with a wind sea under the swell. Classic is the v1.1 look, one chooser away. New storables : seaOptics, seaWindSpeed, seaWindDirDeg, seaChopAmount, seaSkyMirrorView, lightSunFollowsSky; actions seaRebuildSky, seaCaptureAB.
  • 🏐 PropNet. A volleyball net that gives when she hits it, built from one Empty.
  • 🔧 Fixes. Reject lights at the source gives every light back exactly the bit it had, by every route off (feature off, Master off, plugin disabled, plugin removed), and never touches a light added while it is off. A sky that appears after the beach stopped looking is found again. Unticking the plugin puts the beach to sleep instead of freezing it. Settling no longer runs forever on a flat field. SkinBeach : a submesh hidden by a clothing item's Disable anatomy gets its shell when it is shown again; Master off → on no longer sheds sand for one frame; four retired parameters and one action are no longer registered.
  • 📋 The full changelog, every price, the charts and the three factory nights : the v1.2 update page.

v1.1
  • 🌊 Draw the sea off now means no water on the sand. In v1.0 the sand kept running its surf with the sea hidden: the wet band still climbed the beach and foam still appeared. Now the switch takes the water with it: no swash, no foam, nothing new gets wet, and what was wet dries at the drying rate you set. Your waterline and swash settings are kept and come back the moment the sea does.
  • 👥 All Person atoms ships on. Everyone in the scene leaves prints from the first frame, up to four. Untick it to name one person.
  • 🧹 Clear the sand off the skin moved under the Master Switch (SkinBeach), on every page, so a clean take is one press wherever you are. Same action as before for triggers and Timeline.
  • 🧾 Panels only show what can act. The swash and waterline sliders fold away while the sea is off, with a note saying why; they are back the moment it is on.

v1.0
  • 🎉 Initial release. Two plugins. EnvBeach: sand that prints and settles, a sea that wets, foams and erases, surf that answers a body, day and night. SkinBeach: sand that sticks where she touched the beach, packs where she is wet, falls when she moves and comes off under a hand, with a clothing mask.
  • 🔍 Reviewed before release. Two independent code audits and a third-party read before this went out, an overnight bench at 8K, and a re-measure of the exact factory configuration. What they found is fixed or written above.



🤞 Special Thanks

Thanks to @C&G-STUDIO for the ideas and encouragement!




Made so a beach can finally feel like one,
not just look like one. 🏖️🌊🖐️
​

Share this resource

Latest updates

  1. SEAFORGE v1.2

    🏖️ SEAFORGE v1.2 The sea goes under. Two underwater stages, a sea that mirrors your sky, and a...
  2. SeaForge V1.1 Update

    v1.1 🌊 Draw the sea off now means no water on the sand. In v1.0 the sand kept running its surf...

Latest reviews

Positive
Lox
Version: 1.1
Posted:
It feels like magic to be able to have an interactive and beautiful beach all in a plugin that's less than 1MB. Thanks for making and sharing this!
Shadow Venom
Shadow Venom
Size matters. 😏
Upvote 0
Positive
Mm3
Version: 1.1
Posted:
absolutely amazing😮!! i cant believe you managed to add this to vam!
you should do snow next
Shadow Venom
Shadow Venom
It’s already done. I just haven’t had time to release it yet.
Upvote 0
Positive
Version: 1.1
Posted:
It looks simply fantastic and works right out of the box. What do you want more?! Exciting and wonderful addition to a cozy beach scene. Thank you, I will definitely use it with love <3
Shadow Venom
Shadow Venom
Hope you can find a good use for it someday. XD
Upvote 0
Positive
Version: 1.0
Posted:
That's Awesome Bro~ Amazing!!!
Shadow Venom
Shadow Venom
Thank you bro~
Upvote 0
Positive
Version: 1.0
Posted:
Wow, that looks great. I'm going to try it out right after work today. Thanks for sharing.
Shadow Venom
Shadow Venom
Have fun~
Upvote 0
Positive
Version: 1.0
Posted:
The greatest plugin ever made; it truly brings the real world into 3D space. The creator is a genius!
Shadow Venom
Shadow Venom
In one word: immersion. It’s not perfect, but at least it adds a little more of it.
Upvote 0
Positive
Version: 1.0
Posted:
I really admire you! With such efforts, you can achieve this. You are truly a master in the VAM field!
Shadow Venom
Shadow Venom
Let’s make VaM more fun together!
Upvote 0
Positive
AT5
Version: 1.0
Posted:
This is another great plugin, and the video is absolutely gorgeous!!😍
Shadow Venom
Shadow Venom
The hairstyles you design play a big part in it. I love every single one of your designs.
Upvote 0
Back
Top Bottom