Skip to content

Aarav90-cpu/Cpp-Liquid-Glass

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C++ Liquid Glass

Liquid Glass in C++

Screencast.From.2026-05-17.20-30-21.mp4

Liquid Object (USAGE)

A high-performance experimental liquid glass rendering system built with OpenGL, GLFW, GLEW, and GLSL.

Because apparently rectangles were too emotionally stable.

Liquid Object creates draggable, morphing, refractive glass components with:

  • Dynamic blur
  • Real-time refraction
  • Morphing liquid connections
  • Polygon rendering
  • Smooth spring physics
  • Interactive highlights
  • Neon blur tinting
  • Apple-style liquid motion
  • GPU-driven SDF rendering

The entire scene is rendered through a fullscreen fragment shader using signed distance fields (SDFs), which means the UI behaves more like fluid matter than traditional widgets.


Features

Liquid Glass Rendering

  • GPU accelerated liquid rendering
  • Dynamic background blur
  • Refraction simulation
  • Edge specular lighting
  • Interactive highlights
  • Morph merging between nearby objects

Physics System

Each object contains:

  • Spring motion
  • Velocity smoothing
  • Elastic scaling
  • Drag momentum
  • Morph animation
  • Hover interaction

The movement system intentionally behaves slightly organic.

Like expensive jelly.


Preview Features

Shapes Supported

Shape Type Description
0 Rounded Rectangle
1 Circle
3 Polygon

Polygon objects support:

  • Triangles
  • Pentagons
  • Hexagons
  • Octagons
  • Custom vertex systems

Requirements

Linux Packages

Arch Linux

sudo pacman -S glfw glew mesa glm

Ubuntu / Debian

sudo apt install libglfw3-dev libglew-dev mesa-common-dev

Project Structure

project/
├── main.cpp
├── stb_image.h
├── bg.jpg
└── README.md

Building

Using g++ ( Background won't load. Recommended to use is CLion JETBRAINSIDE™ )

g++ main.cpp -o liquid_demo \
-lglfw \
-lGLEW \
-lGL \
-ldl

Running

./liquid_demo

If it instantly explodes with:

GLEW FAILED

then OpenGL context creation failed.

Usually because:

  • GLFW window creation failed
  • Missing OpenGL drivers
  • Running through a VM with cursed graphics support
  • Wayland/X11 issues
  • NVIDIA deciding today is not your day

Human computing infrastructure remains a deeply unserious ecosystem.


Controls

Key / Action Result
Left Mouse Drag Move objects
N Spawn new liquid polygon
Move Objects Near Each Other Morph connection effect

Understanding LiquidObject

The core system revolves around:

class LiquidObject

Each object represents a physically reactive glass surface.


Creating a Liquid Object

Basic Example

LiquidObject obj(
    "GlassCard",
    200.0f,
    200.0f,
    160.0f,
    160.0f,
    0
);

Constructor Parameters

Parameter Type Description
name std::string Object identifier
x float Initial X position
y float Initial Y position
w float Width
h float Height
type int Shape type

Shape Types

Rounded Rectangle

LiquidObject card("Card", 100, 100, 180, 120, 0);

Circle

LiquidObject orb("Orb", 300, 300, 120, 120, 1);

Polygon

LiquidObject poly("Hex", 500, 200, 140, 140, 3);
poly.numSides = 6;

Fluent Builder API

LiquidObject includes a chainable API.

Because typing the same object variable repeatedly is how civilizations collapse.


setDraggable

Enable or disable dragging.

obj.setDraggable(false);

setMorph

Enable liquid morphing behavior.

obj.setMorph(true);

setShape

Change object shape dynamically.

obj.setShape(1);

setTint

Changes blur tint coloration.

obj.setTint(0.4f, 0.1f, 0.8f);

RGB values are normalized.

Value Meaning
0.0f No intensity
1.0f Full intensity

setPath

Constrains movement along a line.

obj.setPath(
    100.0f,
    100.0f,
    700.0f,
    100.0f
);

Useful for:

  • Sliders
  • Timelines
  • Knobs
  • Volume controls
  • Dock systems

setRadius

Changes corner radius.

obj.setRadius(32.0f);

Example Fluent Usage

LiquidObject glass(
    "PremiumGlass",
    300,
    240,
    180,
    180,
    0
);

glass
    .setTint(0.2f, 0.4f, 0.8f)
    .setRadius(28.0f)
    .setMorph(true)
    .setDraggable(true);

Liquid Parameters

Every object contains:

LiquidParams params;

LiquidParams Reference

Field Description
blur Blur intensity
tintAmount Glass tint strength
refraction Distortion intensity
chromatic Chromatic aberration amount
cornerRadius Radius for rounded corners
refractionHeight Refraction edge depth
tintR/G/B RGB tint color

Example Parameter Editing

obj.params.blur = 30.0f;
obj.params.refraction = 140.0f;
obj.params.chromatic = 0.06f;
obj.params.cornerRadius = 24.0f;

Morphing System

Objects automatically merge visually when:

  • Morphing is enabled
  • Objects are close enough
  • Distance threshold is reached

The shader uses:

smin()

for smooth signed-distance blending.

This is the same category of technique used in metaballs and fluid rendering.

Which means you accidentally built procedural slime architecture.


Physics System

Motion uses spring dampening.

Core equations:

velX = (velX + (targetX - offX) * 0.24f) * 0.74f;
velY = (velY + (targetY - offY) * 0.24f) * 0.74f;

This creates:

  • Inertia
  • Elasticity
  • Velocity carry
  • Soft stopping
  • Liquid feel

Scaling System

Objects dynamically stretch depending on velocity.

Fast horizontal motion:

  • widens object
  • compresses vertically

Fast vertical motion:

  • stretches vertically
  • compresses horizontally

This creates the “Apple liquid” feeling.

The same aesthetic principle:

Nothing should stop instantly.

Computers naturally want to move like bricks.

You are forcing them into pretending they understand viscosity.


Polygon System

Polygon rendering is fully procedural.

Example

LiquidObject hex(
    "Hexagon",
    400,
    400,
    160,
    160,
    3
);

hex.numSides = 6;

Dynamic Spawning

Press:

N

to create new liquid polygon objects at the mouse location.

Spawn limit:

32 objects

because the shader uniform arrays are fixed-size.

The GPU enjoys limits.

Unlike frontend developers.


Shader Architecture

The renderer is built around:

Signed Distance Fields (SDF)

Functions include:

sdRoundRect()
sdCircle()
sdPolyEngine()

Refraction System

The refraction system calculates:

  • surface gradients
  • edge normals
  • refracted UV coordinates

Core effect:

refractedCoord = gl_FragCoord.xy + d * grad;

Blur System

Blur uses a lightweight Gaussian sampling pass.

gaussianBlurRaw()

The blur radius dynamically changes during interaction.

Objects sharpen while actively morphing.

Which weirdly makes them feel more alive.

Humans are extremely susceptible to motion-based illusions.


Interactive Highlight System

Mouse proximity generates specular highlights.

lightSheen

This creates:

  • reactive gloss
  • directional lighting illusion
  • premium UI feel

Content Rendering

The shader supports embedded textures:

uniform sampler2D u_contentTex;

You can inject:

  • icons
  • images
  • text atlases
  • UI layers
  • procedural content

Current demo disables it:

glUniform1i(glGetUniformLocation(prog, "u_hasContent"), 0);

Custom Shapes

Custom vertices are supported:

std::vector<std::pair<float, float>> customVertices;

You can extend:

  • stars
  • spline shapes
  • irregular blobs
  • logos
  • procedural meshes

Performance Notes

Current Architecture

The demo:

  • renders entire scene in one shader pass
  • uses fullscreen quad rendering
  • performs SDF evaluation per fragment

Optimization Ideas

1. SSBOs

Replace uniform arrays with Shader Storage Buffer Objects.

2. Compute Blur

Move blur pipeline into compute shaders.

3. Instanced Rendering

Hybridize CPU and GPU shape systems.

4. Temporal Blur

Reuse previous frame blur data.

5. Multi-Pass Refraction

Separate:

  • blur
  • lighting
  • refraction
  • composition

into dedicated render passes.

Because eventually every graphics project becomes:

“What if we invented an entire rendering engine by accident?”


Common Problems

Black Window

Usually means:

  • shader compile failure
  • OpenGL version mismatch
  • texture failed loading

GLEW FAILED

Check:

if (glewInit() != GLEW_OK)

Also ensure:

glfwMakeContextCurrent(window);

was called first.


Missing Texture

Ensure:

bg.jpg

exists beside the executable.


Recommended Improvements

Additions You Can Build

  • Liquid sliders
  • Glass buttons
  • Fluid dock
  • Dynamic blobs
  • Audio reactive motion
  • Soft-body physics
  • Runtime shaders
  • Particle systems
  • Liquid tabs
  • Real UI toolkit

At some point this stops being a demo and becomes:

“someone accidentally rebuilt Apple Human Interface Guidelines using pure GLSL and insomnia.”


License

Licensed under the Apache License 2.0.

See:

LICENSE

for details.


Credits

Built using:

  • OpenGL
  • GLFW
  • GLEW
  • GLSL
  • stb_image

And a completely unreasonable amount of shader math.


Final Notes

Liquid Object is not a traditional UI framework.

It is closer to:

  • procedural graphics
  • liquid simulation illusion
  • shader-driven interaction design
  • experimental interface rendering

The important idea is:

The UI should feel physically alive.

Most interfaces still move like PowerPoint slides from 2009.

This one at least tries to behave like matter.

Building

cmake --build cmake-build-debug --target liquid_demo -j 6