Skip to content

msurguy/genuary-boolean-algebra

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Boolean Mask Compositor

A real-time 3D visualization tool that combines procedural patterns using boolean algebra operations, rendered as animated layered sculptures. Created for Genuary 2025 - January 7th prompt: Boolean algebra.

Boolean Mask Compositor

Overview

This project explores boolean algebra through generative art by:

  1. Generating two procedural noise patterns (Pattern A and Pattern B)
  2. Combining them using boolean operations (AND, OR, XOR, NOT)
  3. Rendering the result as a 3D layered sculpture with depth animation

The boolean operations treat pixel brightness as binary values (above/below threshold), creating striking geometric compositions where mathematical logic becomes visual art.

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                              USER INTERFACE                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  Pattern A  β”‚ β”‚  Pattern B  β”‚ β”‚ Operator β”‚ β”‚ Threshold β”‚ β”‚ 3D Settingsβ”‚ β”‚
β”‚  β”‚   Select    β”‚ β”‚   Select    β”‚ β”‚  Select  β”‚ β”‚  Slider   β”‚ β”‚   Panel    β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚               β”‚             β”‚             β”‚             β”‚
          β–Ό               β–Ό             β”‚             β”‚             β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚             β”‚             β”‚
β”‚     PATTERN GENERATION (PixiJS)     β”‚ β”‚             β”‚             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚ β”‚             β”‚             β”‚
β”‚  β”‚   Texture A  β”‚ β”‚   Texture B  β”‚  β”‚ β”‚             β”‚             β”‚
β”‚  β”‚  (1024Γ—1024) β”‚ β”‚  (1024Γ—1024) β”‚  β”‚ β”‚             β”‚             β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β”‚ β”‚             β”‚             β”‚
β”‚         β”‚                 β”‚         β”‚ β”‚             β”‚             β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚ β”‚             β”‚             β”‚
β”‚                  β–Ό                  β”‚ β”‚             β”‚             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚             β”‚             β”‚
β”‚  β”‚    BOOLEAN SHADER (WebGL)      β”‚β—„β”Όβ”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚ β”‚ β”‚                           β”‚
β”‚  β”‚  β”‚  Ab = step(threshold, A) β”‚  β”‚ β”‚ β”‚                           β”‚
β”‚  β”‚  β”‚  Bb = step(threshold, B) β”‚  β”‚ β”‚ β”‚                           β”‚
β”‚  β”‚  β”‚                          β”‚  β”‚β—„β”Όβ”€β”˜                           β”‚
β”‚  β”‚  β”‚  AND:   Ab * Bb          β”‚  β”‚ β”‚                             β”‚
β”‚  β”‚  β”‚  OR:    max(Ab, Bb)      β”‚  β”‚ β”‚                             β”‚
β”‚  β”‚  β”‚  XOR:   abs(Ab - Bb)     β”‚  β”‚ β”‚                             β”‚
β”‚  β”‚  β”‚  NOT_A: 1.0 - Ab         β”‚  β”‚ β”‚                             β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚ β”‚                             β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚                             β”‚
β”‚                 β”‚                   β”‚                             β”‚
β”‚                 β–Ό                   β”‚                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚                             β”‚
β”‚  β”‚     Boolean Result Texture     β”‚ β”‚                             β”‚
β”‚  β”‚         (1024Γ—1024)            β”‚ β”‚                             β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                             β”‚
                  β”‚                                                 β”‚
                  β–Ό                                                 β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚               3D RENDERING (Three.js)                           β”‚ β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚ β”‚
β”‚  β”‚                    LAYER STACK                            β”‚  β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”    β”‚  β”‚ β”‚
β”‚  β”‚  β”‚  0  β”‚ β”‚  1  β”‚ β”‚  2  β”‚ β”‚  3  β”‚ β”‚  4  β”‚ Β·Β·Β·  β”‚  N  β”‚    β”‚  β”‚ β”‚
β”‚  β”‚  β”‚frontβ”‚ β”‚     β”‚ β”‚     β”‚ β”‚     β”‚ β”‚     β”‚      β”‚back β”‚    β”‚  β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”¬β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”˜      β””β”€β”€β”¬β”€β”€β”˜    β”‚β—„β”€β”Όβ”€β”˜
β”‚  β”‚     β”‚       β”‚       β”‚       β”‚       β”‚            β”‚        β”‚  β”‚
β”‚  β”‚     β–Ό       β–Ό       β–Ό       β–Ό       β–Ό            β–Ό        β”‚  β”‚
β”‚  β”‚  Rolling texture update (each frame shifts textures back) β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                              β”‚                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                  ANIMATION ENGINE                          β”‚  β”‚
β”‚  β”‚  Wave | Pulse | Cascade | Breathe | None                   β”‚  β”‚
β”‚  β”‚  - Per-layer Z offset animation                            β”‚  β”‚
β”‚  β”‚  - Alpha/opacity modulation                                β”‚  β”‚
β”‚  β”‚  - Scale pulsing effects                                   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                              β”‚                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚               SHADER MATERIAL (per layer)                  β”‚  β”‚
β”‚  β”‚  - Tint color gradient (start β†’ end)                       β”‚  β”‚
β”‚  β”‚  - Alpha falloff (depth fade)                              β”‚  β”‚
β”‚  β”‚  - Transparent black/white regions                         β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                              β”‚                                   β”‚
β”‚                              β–Ό                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                   OrbitControls                            β”‚  β”‚
β”‚  β”‚         Interactive 3D camera rotation/zoom                β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

How It Works

1. Pattern Generation

Two patterns are generated independently using GPU shaders via PixiJS. Available pattern types:

Category Patterns Description
Classic Noise Perlin, Simplex, Value Traditional noise functions with FBM (fractal brownian motion)
Advanced Noise Ridged, PingPong, Domain Warp Complex noise variations for organic textures
Cellular Voronoi Cell-based patterns with multiple distance functions
Procedural Flow Field, DLA Algorithmic patterns (particle-based)
Input Webcam Live or snapshot camera input

All noise patterns are powered by FastNoiseLite ported to GLSL shaders for real-time performance.

2. Boolean Operations

The core of this project - two grayscale patterns are combined using boolean logic:

// Threshold converts continuous values to binary
float Ab = step(threshold, A.r);  // 1.0 if A >= threshold, else 0.0
float Bb = step(threshold, B.r);

// Boolean operations
AND:   Ab * Bb           // Intersection - only where BOTH are white
OR:    max(Ab, Bb)       // Union - where EITHER is white
XOR:   abs(Ab - Bb)      // Exclusive OR - where ONLY ONE is white
NOT_A: 1.0 - Ab          // Inversion of pattern A

The threshold slider controls the binary cutoff point, dramatically changing the visual output.

3. 3D Layer Extrusion

The boolean result is extruded into 3D space as a stack of textured planes:

  • Rolling Texture Update: Each animation frame, the current pattern is pushed to the front layer, and all other layers shift backward (creating a temporal depth effect)
  • Alpha Falloff: Layers fade in opacity as they recede
  • Tint Gradient: Color can shift from front to back layers
  • Transparency: Black and/or white regions can be made transparent for sculptural effects

4. Animation Modes

Mode Effect
Wave Sinusoidal Z-position oscillation through the stack
Pulse Scale pulsing with phase offsets per layer
Cascade Sequential wave with opacity modulation
Breathe Organic expansion/contraction of layer spacing
None Static layer positions

Project Structure

src/
β”œβ”€β”€ main.js                 # Application entry point & UI orchestration
β”œβ”€β”€ index.html              # UI layout and styling
β”œβ”€β”€ booleanOps.js           # Boolean algebra shader implementation
β”œβ”€β”€ threeScene.js           # Three.js scene setup (camera, lights, controls)
β”œβ”€β”€ threeExtrude.js         # Layer stack creation & animation engine
β”œβ”€β”€ patterns/
β”‚   β”œβ”€β”€ noise.js            # Basic random noise
β”‚   β”œβ”€β”€ perlin.js           # Perlin noise (FastNoiseLite)
β”‚   β”œβ”€β”€ simplex.js          # Simplex noise (OpenSimplex2)
β”‚   β”œβ”€β”€ voronoi.js          # Voronoi/Cellular patterns
β”‚   β”œβ”€β”€ fastnoise.js        # Advanced noise types (Ridged, PingPong, etc.)
β”‚   β”œβ”€β”€ flowfield.js        # Flow field particle system
β”‚   β”œβ”€β”€ dla.js              # Diffusion-limited aggregation
β”‚   └── webcam.js           # Webcam input handling
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ fastnoiseShader.js  # FastNoiseLite GLSL shader wrapper
β”‚   └── fastnoise.glsl      # FastNoiseLite port to GLSL
└── utils/
    └── noiseHelpers.js     # Noise utility functions

Technology Stack

  • PixiJS (v7) - 2D WebGL rendering for pattern generation and boolean shader
  • Three.js (v0.182) - 3D WebGL rendering for layered sculpture
  • FastNoiseLite - Noise generation library (GLSL port)
  • Vite - Development server and build tool

Getting Started

Prerequisites

  • Node.js 18+
  • Modern browser with WebGL2 support

Installation

# Clone the repository
git clone https://github.com/msurguy/genuary-boolean-algebra.git
cd genuary-boolean-algebra

# Install dependencies
npm install

# Start development server
npm run dev

Open http://localhost:5173 in your browser.

Building for Production

npm run build
npm run preview  # Preview the production build

Refreshing Google Fonts List (Font Picker)

The app uses a local font picker package via file:./jsfontpicker. To refresh the bundled Google Fonts catalog (for newly added fonts like Doto):

cd jsfontpicker
npm run update:google-fonts
cd ..
npm install

Then rebuild the app:

npm run build

Usage

  1. Select Pattern A and Pattern B from the dropdowns
  2. Choose a Boolean Operator (AND, OR, XOR, NOT A)
  3. Adjust the Threshold to control the binary cutoff
  4. Tune Pattern Parameters in the expandable sections
  5. Configure 3D Settings:
    • Layer count and spacing
    • Alpha and falloff
    • Transparency for black/white regions
    • Tint colors
  6. Select Animation Mode and adjust speed/amplitude
  7. Interact - drag to rotate, scroll to zoom
  8. Export - save the current view as PNG

About Genuary

Genuary is an annual event where artists create generative art every day in January based on community prompts. This project was created for:

January 7, 2025: Boolean algebra

Boolean algebra - the mathematics of true/false, 1/0, on/off - forms the foundation of digital computation. This project visualizes boolean logic as art, turning abstract mathematical operations into tangible, sculptural forms.

License

MIT License - feel free to use, modify, and share.


Created with PixiJS, Three.js, and a passion for generative art.