Alchemist's Corner - alchemy tables with glowing potions and a bubbling cauldron
← Back to the Cursed Cozy Village series
● Live · Unity Asset Store & Fab
Cursed Cozy Village · 03 - Liquid Shader

Alchemist's Corner

An alchemist's workshop where the shader is the point. A transform-driven liquid: it stays level when you tilt the bottle, sloshes when you yank it, and settles on its own. One material, infinite potions.

Unity 6000.3+URP 17 HLSL3 shaders Role: Solo - art, shaders, simulation, release

// Overview

Alchemist's Corner is systems, not just models. The heart of the pack is the liquid shader: one shared material becomes any number of glowing potions, and the surface behaves like a surface - it stays horizontal when the bottle tips, and rides along when someone picks it up.

The key decision: the fill plane is rebuilt from the object matrix every frame rather than pushed by a script. A bottle can be lifted, parented to a character's hand, thrown or animated - the potion goes with it at zero per-frame cost on the C# side.

// Video

// How it works

/01 - Liquid (Fill + Bubbles)
A cutting plane instead of an animated mesh

The fill level (0..1) maps into the mesh's own object-space Y range, and the shader rebuilds the cutting plane from the object matrix every frame. The Fill Space switch decides how that plane is oriented: World keeps the surface horizontal no matter how the bottle tilts, Local welds it to the mesh - for corked vials and physics props that tumble.

The liquid mesh renders double sided, and its back faces are only ever visible through the hole the plane cuts. The shader shades them as a flat top surface: the view ray is walked back up to the plane, and the result gets the plane's normal, the surface colour and foam. That's what stops the „I look into the bottle and see straight through it" effect.

/02 - Model ruchu
Telling a slow glide from a sharp flick

A transform's position is quantised to frames, so differentiating it twice gives a spike train rather than an acceleration - dragging an object produces frames with no movement next to frames with a big jump. Clamping that makes every motion saturate the same way, and a slow glide comes out identical to a flick.

So the simulator does four things: it filters velocity and acceleration with frame-rate independent time constants, uses soft saturation instead of clamping, derives tilt from acceleration and agitation mostly from jerk (how suddenly the motion changes), and integrates the spring semi-implicitly with sub-steps so stiff settings don't explode when the frame rate drops.

The result is measurable - same 60 fps rig, distance and duration varied:

Motion Peak tilt Peak agitation Agitation 3 s later
slow glide (0.5 m over 1.5 s)0.040.090.03
medium (0.5 m over 0.5 s)0.180.270.10
quick dart (0.3 m over 0.12 s)0.470.640.24
violent yank (0.5 m over 0.08 s)0.710.890.33

// Four classes of motion produce four distinct readings instead of one saturated maximum.

/03 - Foam, bubbles, glow
Procedural by default, textures optional

The foam is a band placed along Y, independent of everything else: you set separately how far below the surface its top edge sits, how tall it is, and how softly both edges fade. A foam texture erodes the band's edge where it is dark - renormalised, so the core keeps full opacity and only the fringe breaks up.

Three crossing sines are added to the cut plane itself, so the line where the liquid meets the glass undulates instead of being ruler-straight, and the top surface tips its normal along the wave and gathers foam on the crests.

Four texture slots (liquid body, foam, bubbles, emission mask) are optional and keyword-gated - an empty slot costs nothing and the shader stays fully procedural. The default mapping is an object-space projection, so it works on any bottle with no UV unwrap and doesn't swim when the object moves.

/04 - Reszta paczki
Glass, cauldron, vapor and a one-click start

Glass (Stylized) - two stylized specular bands, outer and inner fresnel rim, a grime mask. No GrabPass, so it's safe for VR and mobile. Cauldron (Bubbling Brew) shares property names with the liquid shader, so the same component recolours both a potion and a brew.

CCAlc Potion Filler writes per-instance values through a MaterialPropertyBlock - every bottle is its own potion despite one shared material. It ships a potion palette, a right-click randomizer, and live tilt / agitation / speed meters in the inspector. CCAlc Vapor Emitter configures a ParticleSystem from a preset (steam, smoke, magic haze), and a starter-prefab generator drops the whole showcase into the scene in one click - without entering Play mode.

Read the full documentation online

// Gallery

// Design decisions

// Tech Stack

Unity 6000.3URP 17 HLSLMaterialPropertyBlock Custom EditorVFX / Particles BlenderSubstance Painter
// Next product
Crowd Cheer System