The Authenticity Tax
About This Sketch
Visualizing the authenticity spectrum Left: Genuine authenticity - rough, unfiltered, sometimes rejected Right: Performed authenticity - smooth, curated, widely accepted Shows particles representing "authentic moments" being filtered through different approaches
This sketch accompanies the blog post "The Authenticity Tax" and visualizes its core concepts through generative art.
Algorithm
Visualizing the authenticity spectrum Left: Genuine authenticity - rough, unfiltered, sometimes rejected Right: Performed authenticity - smooth, curated, widely accepted Shows particles representing "authentic moments" being filtered through different approaches
This sketch was originally created as a visual companion to the blog post "The Authenticity Tax" and explores its themes through generative art.
Pseudocode
SETUP:
Initialize canvas (400x300)
Set up drawing parameters
DRAW (every frame):
Get current theme colors
Clear background
Draw generative visualization
Update animation state
Source Code
let sketch = function(p) {
// Visualizing the authenticity spectrum
// Left: Genuine authenticity - rough, unfiltered, sometimes rejected
// Right: Performed authenticity - smooth, curated, widely accepted
// Shows particles representing "authentic moments" being filtered through different approaches
let time = 0;
let genuineParticles = [];
let performedParticles = [];
class AuthenticityParticle {
constructor(x, y, isGenuine) {
this.x = x;
this.y = y;
this.isGenuine = isGenuine;
this.vx = p.random(-1, 1);
this.vy = p.random(-2, -0.5);
this.alpha = 255;
this.size = p.random(4, 8);
this.life = 255;
this.rejected = false;
this.accepted = false;
if (isGenuine) {
// Genuine particles have a chance of being rejected
this.rejectionChance = 0.4;
}
}
update() {
this.vy += 0.02; // gravity
this.x += this.vx;
this.y += this.vy;
if (this.isGenuine) {
// Genuine authenticity - some get rejected, some accepted
if (!this.rejected && !this.accepted && this.y > 150) {
if (p.random() < this.rejectionChance) {
this.rejected = true;
this.vx = p.random(2, 4); // bounce away
this.vy = p.random(-1, 1);
} else {
this.accepted = true;
}
}
if (this.rejected) {
this.life -= 8;
this.alpha = this.life;
} else if (this.accepted) {
// Slow down and settle
this.vx *= 0.95;
this.vy *= 0.95;
}
} else {
// Performed authenticity - smooth path down, mostly accepted
this.vx *= 0.98;
if (this.y > 200) {
this.accepted = true;
this.vy *= 0.9;
}
}
// Fade at bottom
if (this.y > 280) {
this.life -= 5;
this.alpha = this.life;
}
}
display(colors) {
if (this.life <= 0) return;
p.noStroke();
if (this.isGenuine) {
if (this.rejected) {
// Rejected - fading red
p.fill(...colors.accent2, this.alpha * 0.6);
} else if (this.accepted) {
// Accepted genuine - bright
p.fill(...colors.accent1, this.alpha * 0.8);
} else {
// In transit
p.fill(...colors.accent1, this.alpha * 0.6);
}
// Rough edges
p.circle(this.x, this.y, this.size);
p.circle(this.x + 2, this.y + 1, this.size * 0.5);
} else {
if (this.accepted) {
// Performed and accepted - very bright
p.fill(...colors.accent1, this.alpha);
} else {
// In transit
p.fill(...colors.accent1, this.alpha * 0.7);
}
// Smooth, polished
p.circle(this.x, this.y, this.size * 1.2);
}
}
isDead() {
return this.life <= 0 || this.y > 300;
}
}
p.setup = function() {
p.createCanvas(400, 300);
p.colorMode(p.RGB);
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
// Dividing line
p.stroke(...colors.accent3, 60);
p.strokeWeight(1);
p.line(200, 0, 200, 300);
// Labels at top
p.noStroke();
p.fill(...colors.accent3, 200);
p.textAlign(p.CENTER, p.TOP);
p.textSize(11);
p.text("Genuine Authenticity", 100, 15);
p.text("Performed Authenticity", 300, 15);
// Descriptions
p.textSize(8);
p.fill(...colors.accent3, 150);
p.text("Unfiltered", 100, 32);
p.text("Some rejected", 100, 43);
p.text("Curated", 300, 32);
p.text("Mostly accepted", 300, 43);
// Sources (where authenticity originates)
if (time % 15 === 0) {
// Spawn genuine particle
genuineParticles.push(new AuthenticityParticle(
p.random(40, 160),
60,
true
));
}
if (time % 15 === 7) {
// Spawn performed particle
performedParticles.push(new AuthenticityParticle(
p.random(240, 360),
60,
false
));
}
// Filter zones (mid-section)
p.noStroke();
p.fill(...colors.accent3, 20);
p.rect(20, 140, 160, 60);
p.rect(220, 140, 160, 60);
p.fill(...colors.accent3, 100);
p.textSize(7);
p.textAlign(p.CENTER);
p.text("Social Filter", 100, 165);
p.text("(high rejection rate)", 100, 178);
p.text("Strategic Filter", 300, 165);
p.text("(careful curation)", 300, 178);
// Acceptance zones (bottom)
p.fill(...colors.accent3, 30);
p.rect(20, 220, 160, 60);
p.rect(220, 220, 160, 60);
p.fill(...colors.accent3, 120);
p.textSize(8);
p.text("Fewer connections", 100, 245);
p.text("More real", 100, 258);
p.text("More connections", 300, 245);
p.text("Less costly", 300, 258);
// Update and display particles
for (let i = genuineParticles.length - 1; i >= 0; i--) {
genuineParticles[i].update();
genuineParticles[i].display(colors);
if (genuineParticles[i].isDead()) {
genuineParticles.splice(i, 1);
}
}
for (let i = performedParticles.length - 1; i >= 0; i--) {
performedParticles[i].update();
performedParticles[i].display(colors);
if (performedParticles[i].isDead()) {
performedParticles.splice(i, 1);
}
}
// Bottom message
if (time > 100) {
p.textAlign(p.CENTER, p.BOTTOM);
p.textSize(9);
let msgAlpha = p.min((time - 100) * 2, 160);
p.fill(...colors.accent3, msgAlpha);
p.text("The authenticity tax: Reality charges for honesty, but the gospel pretends it's free", 200, 295);
}
time++;
};
};