SlideShare a Scribd company logo
In a Galaxy Far, Far Away
Shay Davidson
- Shay Davidson

- @ShayHDavidson

- Developer at 

- #hobby-game-dev
In a Galaxy Far, Far Away
A Procedural Generation Tale
Procedural Generation
???
"procedural generation is a method of creating data
algorithmically as opposed to manually."
wikipedia
🙄 ‫יופי‬
"procedural generation is the process of 

generating random data or graphics 

using algorithms, heuristics and math."
me
const testUser1 = {
name: fantasyGenerator.name(), // Edwin Long-Shnekel
city: fantasyGenerator.place() // Glimmerwood
};
const testUser2 = {
name: fantasyGenerator.name(), // Minsc, Hamsterbane
city: fantasyGenerator.place() // Randomwood
};
Image from Minecraft
Images by Amit Patel, Red Blob Games
Voronoi Diagram
Images by Amit Patel, Red Blob Games
Images by Amit Patel, Red Blob Games
Images by Amit Patel, Red Blob Games
Images by Amit Patel, Red Blob Games
Animations by @TheRujiK
"it is used to automatically create large
amounts of content and randomness for a
less predictable result."
wikipedia again
Roguelikes
The Pinewheel Galaxy (M101)
# gamedev
The Pinewheel Galaxy (M101)
# gamedev
## TODO
- draw some stars in a spiral 🌀
The Pinewheel Galaxy (M101)
# gamedev
## TODO
- draw some stars in a spiral 🌀
- spread them around 💫
# gamedev
## TODO
- draw some stars in a spiral 🌀
- spread them around 💫
- make them glow, blurry and nice ✨
The Pinewheel Galaxy (M101)
%
The Tale
Math.random();
0 1
t
Math.random();
// a random uniform float in [0..1)
🎲
🎲
🎲
0 1
Math.random();
// a random uniform float in [0..1)
🎲
🎲
🎲
0 1
Math.random();
// a random uniform float in [0..1)
100 100 100 100 100 100 100 100 100 100 100
0 1
t
Math.random();
// a random uniform float in [0..1)
// what about other ranges?
// for example: [0..10)
Math.random();
// a random uniform float in [0..1)
0 10
// what about other ranges?
// for example: [0..10)
Math.random() * 10;
x10t
0 20
x20t
// and negatives?
// for example: [-10..10)
Math.random() * 20
Math.random();
// a random uniform float in [0..1)
// what about other ranges?
// for example: [0..10)
Math.random() * 10;
20
x20t
0
// and negatives?
// for example: [-10..10)
Math.random() * 20
Math.random();
// a random uniform float in [0..1)
// what about other ranges?
// for example: [0..10)
Math.random() * 10;
x20t- 10;
10-10
- 10
// and negatives?
// for example: [-10..10)
Math.random() * 20
Math.random();
// a random uniform float in [0..1)
// what about other ranges?
// for example: [0..10)
Math.random() * 10;
x20t
- 10;
10-10
- 10
// and other, more "complex" ranges?
// for example: uniform in [-14..6)
Math.random() * ??? - ?!? + !?!;
- 10;
// and negatives?
// for example: [-10..10)
Math.random() * 20
Math.random();
// a random uniform float in [0..1)
// what about other ranges?
// for example: [0..10)
Math.random() * 10;
x20t
10-10
- 10
// lerp = linear interpolation
// 0 < t <= 1
function lerp(min, max, t) {
return min + (max - min) * t;
}
- 10;
// and other, more "complex" ranges?
// for example: uniform in [-14..6)
Math.random() * ??? - ?!? + !?!;
- 10;
// and negatives?
// for example: [-10..10)
Math.random() * 20
Math.random();
// a random uniform float in [0..1)
// what about other ranges?
// for example: [0..10)
Math.random() * 10;
x20t
6-14
- 14
lerp(-14, 6, Math.random());
- 10;
// and other, more "complex" ranges?
// for example: uniform in [-14..6)
Math.random() * ??? - ?!? + !?!;
- 10;
// and negatives?
// for example: [-10..10)
Math.random() * 20
Math.random();
// a random uniform float in [0..1)
// what about other ranges?
// for example: [0..10)
Math.random() * 10;
// lerp = linear interpolation
// 0 < t <= 1
function lerp(min, max, t) {
return min + (max - min) * t;
}
‫ָס‬‫ב‬ְ‫נ‬‫ָקא‬ ‫ָה‬‫י‬ָ‫ה‬ ‫ִית‬‫ׁש‬‫ְֵרא‬‫ּב‬
// so we got a random function!
// let's create some stars ⭐
// so we got a random function!
// let's create some stars ⭐
const starCount = 1000;
// so we got a random function!
// let's create some stars ⭐
const starCount = 1000;
for (let i = 0; i < starCount; i++) {
}
// so we got a random function!
// let's create some stars ⭐
const starCount = 1000;
for (let i = 0; i < starCount; i++) {
let x = lerp(0, size, Math.random());
let y = lerp(0, size, Math.random());
drawStar(x, y);
}
// so we got a random function!
// let's create some stars ⭐
const starCount = 1000;
for (let i = 0; i < starCount; i++) {
let x = lerp(0, size, Math.random());
let y = lerp(0, size, Math.random());
drawStar(x, y);
}
// so we got a random function!
// let's create some stars ⭐
const starCount = 1000;
for (let i = 0; i < starCount; i++) {
let x = lerp(0, size, Math.random());
let y = lerp(0, size, Math.random());
drawStar(x, y);
}
// so we got a random function!
// let's create some stars ⭐
const starCount = 1000;
for (let i = 0; i < starCount; i++) {
let x = lerp(0, size, Math.random());
let y = lerp(0, size, Math.random());
drawStar(x, y);
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
for (let i = 0; i < starCount; i++) {
let x = lerp(0, size, Math.random());
let y = lerp(0, size, Math.random());
drawStar(x, y);
}
RNG
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
rng.random(); // 0.1
rng.random(); // 0.5
rng.random(); // 0.2
rng.random(); // 0.8
const rng2 = new RandomNumberGenerator(seed);
rng2.random(); // 0.1
rng2.random(); // 0.5
rng2.random(); // 0.2
rng2.random(); // 0.8 RNG
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
for (let i = 0; i < starCount; i++) {
let x = lerp(0, size, rng.random());
let y = lerp(0, size, rng.random());
drawStar(x, y);
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
for (let i = 0; i < starCount; i++) {
let x = lerp(0, size, rng.random());
let y = lerp(0, size, rng.random());
drawStar(x, y);
}
(0,0)
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
for (let i = 0; i < starCount; i++) {
let x = lerp(0, size, rng.random());
let y = lerp(0, size, rng.random());
drawStar(x, y);
}
(0,0)
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let x = lerp(0, size, Math.random());
let y = lerp(0, size, Math.random());
drawStar(x, y);
}
(0,0)
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let x = lerp(-radius, radius, rng.random());
let y = lerp(-radius, radius, rng.random());
drawStar(x + radius, y + radius);
}
(0,0)
y
x
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = canvasSize / 2;
for (let i = 0; i < starCount; i++) {
const x = lerp(-radius, radius, rng.random());
const y = lerp(-radius, radius, rng.random());
drawStar(x + radius, y + radius);
}
y
x
Cartesian Coordinates
(x, y)
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = canvasSize / 2;
for (let i = 0; i < starCount; i++) {
const x = lerp(-radius, radius, rng.random());
const y = lerp(-radius, radius, rng.random());
drawStar(x + radius, y + radius);
}
Polar Coordinates
(r, θ)
r
θ
r
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = canvasSize / 2;
for (let i = 0; i < starCount; i++) {
const x = lerp(-radius, radius, rng.random());
const y = lerp(-radius, radius, rng.random());
drawStar(x + radius, y + radius);
}
Polar Coordinates
(r, θ)
r
rr
θ
rx
y
rrr
θ
rx
y
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let x = lerp(-radius, radius, rng.random());
let y = lerp(-radius, radius, rng.random());
drawStar(x + radius, y + radius);
}
r
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(0, radius, rng.random());
let t = lerp(0, 360deg, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
r
θ
r
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(0, radius, rng.random());
let t = lerp(0, 360deg, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
r
θ
r
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(0, radius, rng.random());
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
r
θ
r
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(0, radius, rng.random());
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
r
θ
r
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(0, radius, rng.random());
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
🤔
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
rng.random()
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
rng.random()
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
rng.random()
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
100 100 100 100 100 100 100 100 100 100
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Math.sqrt(rng.random()) // <-----
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
100 100 100 100 100 100 100 100 100 100
❌
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 1000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Math.sqrt(rng.random())
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
👍
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 5000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Math.sqrt(rng.random())
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Math.sqrt(rng.random())
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius);
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Math.sqrt(rng.random())
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random())
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Math.sqrt(rng.random())
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
Taking it Easing
#sorry
.selector {
animation: fade 1s ease-out;
}
Animation by @LucasVB
linear
y(t) = t
1
1
0
easeOutQuad
y(t) = t(2 - t)
1
1
0
easeInQuad
y(t) = t
1
1
0
2
Image from easings.net
0 1
linear
1
1
0
100
t = Math.random()

y(t) = t
100 100 100 100 100 100 100 100 100 100
0 1
easeOutQuad
1
1
0
t = Math.random()

y(t) = t(2 - t)
2 5 10 18 30 45 70 100 150 270 400
0 1
easeInQuad
1
1
0
t = Math.random()

y(t) = t
2
251018304570100150270400
0 1
251018304570100150270400
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Math.sqrt(rng.random())
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Math.sqrt(rng.random()) // <---- t
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
linear
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Ease.inQuart(Math.sqrt(rng.random()))
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
easeInQuart
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Ease.outQuart(Math.sqrt(rng.random()))
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
easeOutQuart
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Ease.inOutQuart(Math.sqrt(rng.random()))
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
easeInOutQuart
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Ease.inOutElastic(Math.sqrt(rng.random()))
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
easeInOutElastic
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Ease.inAlot(Math.sqrt(rng.random()))
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
easeInAlot
😓
M80 Globular Cluster
❌
SPIRALS 🌀
Images from Wikipedia
Another Golden Spiral
Another Golden Spiral
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let r = lerp(
0,
radius,
Ease.inAlot(Math.sqrt(rng.random()))
);
let t = lerp(0, Math.PI * 2, rng.random());
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
// let r = lerp(
// 0,
// radius,
// Ease.inAlot(Math.sqrt(rng.random()))
// );
// let t = lerp(0, Math.PI * 2, rng.random..
// const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
function uniformCircle(radius, easing, t)
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
drawStar(x + radius, y + radius, {
size: lerp(0.5, 3, rng.random()),
color: rng.pickOne(FROM_COLORS)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let { x, y } = spiral({
a: 0.02,
b: 0.2,
t: rng.random()
});
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let { x, y } = spiral({
a: 0.02,
b: 0.2,
t: rng.random()
});
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let { x, y } = spiral({
a: 0.02,
b: 0.2,
t: rng.random()
});
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
🧐🔍
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let { x, y } = spiral({
a: 1,
b: 0.5,
t: rng.random() * MULTIPLIER
});
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let { x, y } = spiral({
a: 0.02,
b: 0.2,
t: rng.random() * MULTIPLIER
});
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let { x, y } = spiral({
a: 0.1,
b: 1,
t: rng.random() * MULTIPLIER
});
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
for (let i = 0; i < starCount; i++) {
let { x, y } = spiral({
a: 1,
b: 0.5,
t: rng.random() * MULTIPLIER
});
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
const arms = 2;
for (let i = 0; i < starCount; i++) {
let { x, y } = spiral({
a: 1,
b: 0.5,
t: rng.random() * MULTIPLIER
});
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
const arms = 2;
for (let i = 0; i < starCount; i++) {
let { r, t } = spiral({
a: 1,
b: 0.5,
t: rng.random() * MULTIPLIER
});
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
const arms = 2;
for (let i = 0; i < starCount; i++) {
let { r, t } = spiral({
a: 1,
b: 0.5,
t: rng.random() * MULTIPLIER
});
let arm = rng.lerp(0, arms);
t += 2 * Math.PI * Math.floor(arm / arms);
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
const arms = 2;
for (let i = 0; i < starCount; i++) {
let { r, t } = spiral({
a: 1,
b: 0.5,
t: rng.random() * MULTIPLIER
});
let arm = rng.lerp(0, arms);
t += 2 * Math.PI * Math.floor(arm / arms);
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
const arms = 8;
for (let i = 0; i < starCount; i++) {
let { r, t } = spiral({
a: 1,
b: 0.5,
t: rng.random() * MULTIPLIER
});
let arm = rng.lerp(0, arms);
t += 2 * Math.PI * Math.floor(arm / arms);
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
const arms = 2;
for (let i = 0; i < starCount; i++) {
let { r, t } = spiral({
a: 1,
b: 0.2,
t: rng.random() * MULTIPLIER
});
let arm = rng.lerp(0, arms);
t += 2 * Math.PI * Math.floor(arm / arms);
const { x, y } = polarToCartesian(r, t);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
const arms = 2;
for (let i = 0; i < starCount; i++) {
let { r, t } = spiral({
a: 1,
b: 0.2,
t: rng.random() * MULTIPLIER
});
let arm = rng.lerp(0, arms);
t += 2 * Math.PI * Math.floor(arm / arms);
let { x, y } = polarToCartesian(r, t);
x += rng.uniformCircle(SPREAD, Ease.inQuad);
y += rng.uniformCircle(SPREAD, Ease.inQuad);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 15000;
const radius = size / 2;
const arms = 2;
for (let i = 0; i < starCount; i++) {
let { r, t } = spiral({
a: 1,
b: 0.2,
t: rng.random() * MULTIPLIER
});
let arm = rng.lerp(0, arms);
t += 2 * Math.PI * Math.floor(arm / arms);
let { x, y } = polarToCartesian(r, t);
x += rng.uniformCircle(SPREAD, Ease.inQuad);
y += rng.uniformCircle(SPREAD, Ease.inQuad);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
// so we got a random function!
// let's create some stars ⭐
const seed = 1234;
const rng = new RandomNumberGenerator(seed);
const starCount = 50000;
const radius = size / 2;
const arms = 2;
for (let i = 0; i < starCount; i++) {
let { r, t } = spiral({
a: 1,
b: 0.2,
t: rng.random() * MULTIPLIER
});
let arm = rng.lerp(0, arms);
t += 2 * Math.PI * Math.floor(arm / arms);
let { x, y } = polarToCartesian(r, t);
x += rng.uniformCircle(SPREAD, Ease.inQuad);
y += rng.uniformCircle(SPREAD, Ease.inQuad);
drawStar(x + radius, y + radius, {
size: lerp(0.5, 2, rng.random()),
color: rng.randomFrom(STAR_COLORS_ARRAY)
});
}
Almost There!
/* css */
canvas .galaxy-background-glow {
filter: blur(200px);
}
/* css */
canvas .galaxy-background-glow {
filter: blur(200px);
}
canvas .galaxy-nebula-glow {
filter: blur(20px);
mix-blend-mode: lighten;
}
/* css */
canvas .galaxy-background-glow {
filter: blur(200px);
}
canvas .galaxy-nebula-glow {
filter: blur(20px);
mix-blend-mode: lighten;
}
.galaxy-core {
width: 50%;
height: 50%;
background-color: radial-gradient(...);
border-radius: 50%;
filter: blur(50px);
mix-blend-mode: overlay;
}
creategalaxy.com
#icreatedagalaxy #reversim2019
creategalaxy.com
#icreatedagalaxy #reversim2019
open-source
More?
#procgen #generative
Demo Time?
@ShayHDavidson
Thank You!
@ShayHDavidson

More Related Content

What's hot

Tauheed(Oneness of Allah) presentation by Nayab Siddiqui
Tauheed(Oneness of Allah) presentation by Nayab SiddiquiTauheed(Oneness of Allah) presentation by Nayab Siddiqui
Tauheed(Oneness of Allah) presentation by Nayab Siddiqui
NayabSiddique2
 
The day of judgement and the life in the hereafter
The day of judgement and the life in the hereafterThe day of judgement and the life in the hereafter
The day of judgement and the life in the hereafter
Waleed Liaqat
 
Moral values in islam
Moral values in islamMoral values in islam
Moral values in islam
eishaafzaal
 
Jihad
JihadJihad
Jihad
Sukkur IBA
 
o level islamiat 2058/2
o level islamiat 2058/2o level islamiat 2058/2
o level islamiat 2058/2
saadanashraf
 
Islam Is The Religion Of Peace
Islam Is The Religion Of PeaceIslam Is The Religion Of Peace
Jihad
JihadJihad
Introduction to Islam
Introduction to IslamIntroduction to Islam
Introduction to Islam
Mohammad Yunus, MD, FACP
 
Islamic guidance on leadership
Islamic guidance on leadershipIslamic guidance on leadership
Islamic guidance on leadership
Mohammad Yunus, MD, FACP
 
Muhammad bin qasim
Muhammad bin qasimMuhammad bin qasim
Muhammad bin qasim
Abdullah Mansoor
 
Introduction to islam
Introduction to islamIntroduction to islam
Introduction to islam
aygun9
 
The History of Islam
The History of IslamThe History of Islam
The History of Islamnatashaghica
 
Introduction To Hadith
Introduction To HadithIntroduction To Hadith
Introduction To Hadith
ahlussunnah1
 
Difference beteen-deen-religion
Difference beteen-deen-religionDifference beteen-deen-religion
Difference beteen-deen-religion
AhsanMirza23
 
Presentation Islam
Presentation IslamPresentation Islam
Presentation IslamAzizjonZ
 
Zakat presentations.pptx3
Zakat presentations.pptx3Zakat presentations.pptx3
Zakat presentations.pptx3
Sara Malik
 
Islam a complete code of life
Islam a complete code of lifeIslam a complete code of life
Islam a complete code of life
Muhammad Wasie Fasih Butt
 
Islamic jurisprudence
Islamic jurisprudenceIslamic jurisprudence
Islamic jurisprudence
TaseerBaloch1
 
CSS Islamic studies
CSS Islamic studiesCSS Islamic studies
CSS Islamic studies
Entire Education
 
Introduction belief in allah - belief in angels
Introduction   belief in allah - belief in angelsIntroduction   belief in allah - belief in angels
Introduction belief in allah - belief in angels
Taufiq Majeed
 

What's hot (20)

Tauheed(Oneness of Allah) presentation by Nayab Siddiqui
Tauheed(Oneness of Allah) presentation by Nayab SiddiquiTauheed(Oneness of Allah) presentation by Nayab Siddiqui
Tauheed(Oneness of Allah) presentation by Nayab Siddiqui
 
The day of judgement and the life in the hereafter
The day of judgement and the life in the hereafterThe day of judgement and the life in the hereafter
The day of judgement and the life in the hereafter
 
Moral values in islam
Moral values in islamMoral values in islam
Moral values in islam
 
Jihad
JihadJihad
Jihad
 
o level islamiat 2058/2
o level islamiat 2058/2o level islamiat 2058/2
o level islamiat 2058/2
 
Islam Is The Religion Of Peace
Islam Is The Religion Of PeaceIslam Is The Religion Of Peace
Islam Is The Religion Of Peace
 
Jihad
JihadJihad
Jihad
 
Introduction to Islam
Introduction to IslamIntroduction to Islam
Introduction to Islam
 
Islamic guidance on leadership
Islamic guidance on leadershipIslamic guidance on leadership
Islamic guidance on leadership
 
Muhammad bin qasim
Muhammad bin qasimMuhammad bin qasim
Muhammad bin qasim
 
Introduction to islam
Introduction to islamIntroduction to islam
Introduction to islam
 
The History of Islam
The History of IslamThe History of Islam
The History of Islam
 
Introduction To Hadith
Introduction To HadithIntroduction To Hadith
Introduction To Hadith
 
Difference beteen-deen-religion
Difference beteen-deen-religionDifference beteen-deen-religion
Difference beteen-deen-religion
 
Presentation Islam
Presentation IslamPresentation Islam
Presentation Islam
 
Zakat presentations.pptx3
Zakat presentations.pptx3Zakat presentations.pptx3
Zakat presentations.pptx3
 
Islam a complete code of life
Islam a complete code of lifeIslam a complete code of life
Islam a complete code of life
 
Islamic jurisprudence
Islamic jurisprudenceIslamic jurisprudence
Islamic jurisprudence
 
CSS Islamic studies
CSS Islamic studiesCSS Islamic studies
CSS Islamic studies
 
Introduction belief in allah - belief in angels
Introduction   belief in allah - belief in angelsIntroduction   belief in allah - belief in angels
Introduction belief in allah - belief in angels
 

Similar to In a galaxy far, far away - A procedural generation tale

need help with code I wrote. This code is a maze gui, and i need hel.pdf
need help with code I wrote. This code is a maze gui, and i need hel.pdfneed help with code I wrote. This code is a maze gui, and i need hel.pdf
need help with code I wrote. This code is a maze gui, and i need hel.pdf
arcotstarsports
 
Exploring fractals in CSS, @fronttrends, Warsaw, 2015
Exploring fractals in CSS, @fronttrends, Warsaw, 2015Exploring fractals in CSS, @fronttrends, Warsaw, 2015
Exploring fractals in CSS, @fronttrends, Warsaw, 2015
pixelass
 
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
DevGAMM Conference
 
Code as data as code.
Code as data as code.Code as data as code.
Code as data as code.Mike Fogus
 
Ugly code
Ugly codeUgly code
Ugly codeOdd-e
 
Creating masterpieces with raphael
Creating masterpieces with raphaelCreating masterpieces with raphael
Creating masterpieces with raphael
Pippi Labradoodle
 
SaveI need help with this maze gui that I wrote in java, I am tryi.pdf
SaveI need help with this maze gui that I wrote in java, I am tryi.pdfSaveI need help with this maze gui that I wrote in java, I am tryi.pdf
SaveI need help with this maze gui that I wrote in java, I am tryi.pdf
arihantstoneart
 
What they don't tell you about JavaScript
What they don't tell you about JavaScriptWhat they don't tell you about JavaScript
What they don't tell you about JavaScriptRaphael Cruzeiro
 
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Doris Chen
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
Christian Baranowski
 
Adventures In Data Compilation
Adventures In Data CompilationAdventures In Data Compilation
Adventures In Data CompilationNaughty Dog
 
Write Python for Speed
Write Python for SpeedWrite Python for Speed
Write Python for Speed
Yung-Yu Chen
 
I need help with this maze gui that I wrote in java, I am trying to .pdf
I need help with this maze gui that I wrote in java, I am trying to .pdfI need help with this maze gui that I wrote in java, I am trying to .pdf
I need help with this maze gui that I wrote in java, I am trying to .pdf
arihantgiftgallery
 
The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212
Mahmoud Samir Fayed
 
Using Java, please write the program for the following prompt in the.pdf
Using Java, please write the program for the following prompt in the.pdfUsing Java, please write the program for the following prompt in the.pdf
Using Java, please write the program for the following prompt in the.pdf
forecastfashions
 
Graphics practical lab manual
Graphics practical lab manualGraphics practical lab manual
Graphics practical lab manual
Vivek Kumar Sinha
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
Manoj Kumar
 
The Ring programming language version 1.6 book - Part 55 of 189
The Ring programming language version 1.6 book - Part 55 of 189The Ring programming language version 1.6 book - Part 55 of 189
The Ring programming language version 1.6 book - Part 55 of 189
Mahmoud Samir Fayed
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017
名辰 洪
 

Similar to In a galaxy far, far away - A procedural generation tale (20)

need help with code I wrote. This code is a maze gui, and i need hel.pdf
need help with code I wrote. This code is a maze gui, and i need hel.pdfneed help with code I wrote. This code is a maze gui, and i need hel.pdf
need help with code I wrote. This code is a maze gui, and i need hel.pdf
 
Exploring fractals in CSS, @fronttrends, Warsaw, 2015
Exploring fractals in CSS, @fronttrends, Warsaw, 2015Exploring fractals in CSS, @fronttrends, Warsaw, 2015
Exploring fractals in CSS, @fronttrends, Warsaw, 2015
 
Ssaw08 0624
Ssaw08 0624Ssaw08 0624
Ssaw08 0624
 
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
 
Code as data as code.
Code as data as code.Code as data as code.
Code as data as code.
 
Ugly code
Ugly codeUgly code
Ugly code
 
Creating masterpieces with raphael
Creating masterpieces with raphaelCreating masterpieces with raphael
Creating masterpieces with raphael
 
SaveI need help with this maze gui that I wrote in java, I am tryi.pdf
SaveI need help with this maze gui that I wrote in java, I am tryi.pdfSaveI need help with this maze gui that I wrote in java, I am tryi.pdf
SaveI need help with this maze gui that I wrote in java, I am tryi.pdf
 
What they don't tell you about JavaScript
What they don't tell you about JavaScriptWhat they don't tell you about JavaScript
What they don't tell you about JavaScript
 
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Adventures In Data Compilation
Adventures In Data CompilationAdventures In Data Compilation
Adventures In Data Compilation
 
Write Python for Speed
Write Python for SpeedWrite Python for Speed
Write Python for Speed
 
I need help with this maze gui that I wrote in java, I am trying to .pdf
I need help with this maze gui that I wrote in java, I am trying to .pdfI need help with this maze gui that I wrote in java, I am trying to .pdf
I need help with this maze gui that I wrote in java, I am trying to .pdf
 
The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212
 
Using Java, please write the program for the following prompt in the.pdf
Using Java, please write the program for the following prompt in the.pdfUsing Java, please write the program for the following prompt in the.pdf
Using Java, please write the program for the following prompt in the.pdf
 
Graphics practical lab manual
Graphics practical lab manualGraphics practical lab manual
Graphics practical lab manual
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
The Ring programming language version 1.6 book - Part 55 of 189
The Ring programming language version 1.6 book - Part 55 of 189The Ring programming language version 1.6 book - Part 55 of 189
The Ring programming language version 1.6 book - Part 55 of 189
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017
 

Recently uploaded

Unbalanced Three Phase Systems and circuits.pptx
Unbalanced Three Phase Systems and circuits.pptxUnbalanced Three Phase Systems and circuits.pptx
Unbalanced Three Phase Systems and circuits.pptx
ChristineTorrepenida1
 
bank management system in java and mysql report1.pdf
bank management system in java and mysql report1.pdfbank management system in java and mysql report1.pdf
bank management system in java and mysql report1.pdf
Divyam548318
 
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdf
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdfGoverning Equations for Fundamental Aerodynamics_Anderson2010.pdf
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdf
WENKENLI1
 
AIR POLLUTION lecture EnE203 updated.pdf
AIR POLLUTION lecture EnE203 updated.pdfAIR POLLUTION lecture EnE203 updated.pdf
AIR POLLUTION lecture EnE203 updated.pdf
RicletoEspinosa1
 
Water billing management system project report.pdf
Water billing management system project report.pdfWater billing management system project report.pdf
Water billing management system project report.pdf
Kamal Acharya
 
Recycled Concrete Aggregate in Construction Part III
Recycled Concrete Aggregate in Construction Part IIIRecycled Concrete Aggregate in Construction Part III
Recycled Concrete Aggregate in Construction Part III
Aditya Rajan Patra
 
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressionsKuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
Victor Morales
 
PROJECT FORMAT FOR EVS AMITY UNIVERSITY GWALIOR.ppt
PROJECT FORMAT FOR EVS AMITY UNIVERSITY GWALIOR.pptPROJECT FORMAT FOR EVS AMITY UNIVERSITY GWALIOR.ppt
PROJECT FORMAT FOR EVS AMITY UNIVERSITY GWALIOR.ppt
bhadouriyakaku
 
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
zwunae
 
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming PipelinesHarnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
Christina Lin
 
14 Template Contractual Notice - EOT Application
14 Template Contractual Notice - EOT Application14 Template Contractual Notice - EOT Application
14 Template Contractual Notice - EOT Application
SyedAbiiAzazi1
 
Hierarchical Digital Twin of a Naval Power System
Hierarchical Digital Twin of a Naval Power SystemHierarchical Digital Twin of a Naval Power System
Hierarchical Digital Twin of a Naval Power System
Kerry Sado
 
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
ssuser7dcef0
 
Modelagem de um CSTR com reação endotermica.pdf
Modelagem de um CSTR com reação endotermica.pdfModelagem de um CSTR com reação endotermica.pdf
Modelagem de um CSTR com reação endotermica.pdf
camseq
 
Fundamentals of Electric Drives and its applications.pptx
Fundamentals of Electric Drives and its applications.pptxFundamentals of Electric Drives and its applications.pptx
Fundamentals of Electric Drives and its applications.pptx
manasideore6
 
[JPP-1] - (JEE 3.0) - Kinematics 1D - 14th May..pdf
[JPP-1] - (JEE 3.0) - Kinematics 1D - 14th May..pdf[JPP-1] - (JEE 3.0) - Kinematics 1D - 14th May..pdf
[JPP-1] - (JEE 3.0) - Kinematics 1D - 14th May..pdf
awadeshbabu
 
TOP 10 B TECH COLLEGES IN JAIPUR 2024.pptx
TOP 10 B TECH COLLEGES IN JAIPUR 2024.pptxTOP 10 B TECH COLLEGES IN JAIPUR 2024.pptx
TOP 10 B TECH COLLEGES IN JAIPUR 2024.pptx
nikitacareer3
 
sieving analysis and results interpretation
sieving analysis and results interpretationsieving analysis and results interpretation
sieving analysis and results interpretation
ssuser36d3051
 
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
obonagu
 
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdfBPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
MIGUELANGEL966976
 

Recently uploaded (20)

Unbalanced Three Phase Systems and circuits.pptx
Unbalanced Three Phase Systems and circuits.pptxUnbalanced Three Phase Systems and circuits.pptx
Unbalanced Three Phase Systems and circuits.pptx
 
bank management system in java and mysql report1.pdf
bank management system in java and mysql report1.pdfbank management system in java and mysql report1.pdf
bank management system in java and mysql report1.pdf
 
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdf
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdfGoverning Equations for Fundamental Aerodynamics_Anderson2010.pdf
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdf
 
AIR POLLUTION lecture EnE203 updated.pdf
AIR POLLUTION lecture EnE203 updated.pdfAIR POLLUTION lecture EnE203 updated.pdf
AIR POLLUTION lecture EnE203 updated.pdf
 
Water billing management system project report.pdf
Water billing management system project report.pdfWater billing management system project report.pdf
Water billing management system project report.pdf
 
Recycled Concrete Aggregate in Construction Part III
Recycled Concrete Aggregate in Construction Part IIIRecycled Concrete Aggregate in Construction Part III
Recycled Concrete Aggregate in Construction Part III
 
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressionsKuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
 
PROJECT FORMAT FOR EVS AMITY UNIVERSITY GWALIOR.ppt
PROJECT FORMAT FOR EVS AMITY UNIVERSITY GWALIOR.pptPROJECT FORMAT FOR EVS AMITY UNIVERSITY GWALIOR.ppt
PROJECT FORMAT FOR EVS AMITY UNIVERSITY GWALIOR.ppt
 
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
 
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming PipelinesHarnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
 
14 Template Contractual Notice - EOT Application
14 Template Contractual Notice - EOT Application14 Template Contractual Notice - EOT Application
14 Template Contractual Notice - EOT Application
 
Hierarchical Digital Twin of a Naval Power System
Hierarchical Digital Twin of a Naval Power SystemHierarchical Digital Twin of a Naval Power System
Hierarchical Digital Twin of a Naval Power System
 
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
 
Modelagem de um CSTR com reação endotermica.pdf
Modelagem de um CSTR com reação endotermica.pdfModelagem de um CSTR com reação endotermica.pdf
Modelagem de um CSTR com reação endotermica.pdf
 
Fundamentals of Electric Drives and its applications.pptx
Fundamentals of Electric Drives and its applications.pptxFundamentals of Electric Drives and its applications.pptx
Fundamentals of Electric Drives and its applications.pptx
 
[JPP-1] - (JEE 3.0) - Kinematics 1D - 14th May..pdf
[JPP-1] - (JEE 3.0) - Kinematics 1D - 14th May..pdf[JPP-1] - (JEE 3.0) - Kinematics 1D - 14th May..pdf
[JPP-1] - (JEE 3.0) - Kinematics 1D - 14th May..pdf
 
TOP 10 B TECH COLLEGES IN JAIPUR 2024.pptx
TOP 10 B TECH COLLEGES IN JAIPUR 2024.pptxTOP 10 B TECH COLLEGES IN JAIPUR 2024.pptx
TOP 10 B TECH COLLEGES IN JAIPUR 2024.pptx
 
sieving analysis and results interpretation
sieving analysis and results interpretationsieving analysis and results interpretation
sieving analysis and results interpretation
 
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
 
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdfBPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
 

In a galaxy far, far away - A procedural generation tale

  • 1. In a Galaxy Far, Far Away Shay Davidson
  • 2. - Shay Davidson - @ShayHDavidson - Developer at - #hobby-game-dev
  • 3.
  • 4.
  • 5. In a Galaxy Far, Far Away A Procedural Generation Tale
  • 7. "procedural generation is a method of creating data algorithmically as opposed to manually." wikipedia
  • 9. "procedural generation is the process of generating random data or graphics using algorithms, heuristics and math." me
  • 10. const testUser1 = { name: fantasyGenerator.name(), // Edwin Long-Shnekel city: fantasyGenerator.place() // Glimmerwood }; const testUser2 = { name: fantasyGenerator.name(), // Minsc, Hamsterbane city: fantasyGenerator.place() // Randomwood };
  • 11.
  • 13. Images by Amit Patel, Red Blob Games Voronoi Diagram
  • 14. Images by Amit Patel, Red Blob Games
  • 15. Images by Amit Patel, Red Blob Games
  • 16. Images by Amit Patel, Red Blob Games
  • 17. Images by Amit Patel, Red Blob Games
  • 19. "it is used to automatically create large amounts of content and randomness for a less predictable result." wikipedia again
  • 21. The Pinewheel Galaxy (M101) # gamedev
  • 22. The Pinewheel Galaxy (M101) # gamedev ## TODO - draw some stars in a spiral 🌀
  • 23. The Pinewheel Galaxy (M101) # gamedev ## TODO - draw some stars in a spiral 🌀 - spread them around 💫
  • 24. # gamedev ## TODO - draw some stars in a spiral 🌀 - spread them around 💫 - make them glow, blurry and nice ✨ The Pinewheel Galaxy (M101) %
  • 27. 0 1 t Math.random(); // a random uniform float in [0..1)
  • 28. 🎲 🎲 🎲 0 1 Math.random(); // a random uniform float in [0..1)
  • 29. 🎲 🎲 🎲 0 1 Math.random(); // a random uniform float in [0..1) 100 100 100 100 100 100 100 100 100 100 100
  • 30. 0 1 t Math.random(); // a random uniform float in [0..1) // what about other ranges? // for example: [0..10)
  • 31. Math.random(); // a random uniform float in [0..1) 0 10 // what about other ranges? // for example: [0..10) Math.random() * 10; x10t
  • 32. 0 20 x20t // and negatives? // for example: [-10..10) Math.random() * 20 Math.random(); // a random uniform float in [0..1) // what about other ranges? // for example: [0..10) Math.random() * 10;
  • 33. 20 x20t 0 // and negatives? // for example: [-10..10) Math.random() * 20 Math.random(); // a random uniform float in [0..1) // what about other ranges? // for example: [0..10) Math.random() * 10;
  • 34. x20t- 10; 10-10 - 10 // and negatives? // for example: [-10..10) Math.random() * 20 Math.random(); // a random uniform float in [0..1) // what about other ranges? // for example: [0..10) Math.random() * 10;
  • 35. x20t - 10; 10-10 - 10 // and other, more "complex" ranges? // for example: uniform in [-14..6) Math.random() * ??? - ?!? + !?!; - 10; // and negatives? // for example: [-10..10) Math.random() * 20 Math.random(); // a random uniform float in [0..1) // what about other ranges? // for example: [0..10) Math.random() * 10;
  • 36. x20t 10-10 - 10 // lerp = linear interpolation // 0 < t <= 1 function lerp(min, max, t) { return min + (max - min) * t; } - 10; // and other, more "complex" ranges? // for example: uniform in [-14..6) Math.random() * ??? - ?!? + !?!; - 10; // and negatives? // for example: [-10..10) Math.random() * 20 Math.random(); // a random uniform float in [0..1) // what about other ranges? // for example: [0..10) Math.random() * 10;
  • 37. x20t 6-14 - 14 lerp(-14, 6, Math.random()); - 10; // and other, more "complex" ranges? // for example: uniform in [-14..6) Math.random() * ??? - ?!? + !?!; - 10; // and negatives? // for example: [-10..10) Math.random() * 20 Math.random(); // a random uniform float in [0..1) // what about other ranges? // for example: [0..10) Math.random() * 10; // lerp = linear interpolation // 0 < t <= 1 function lerp(min, max, t) { return min + (max - min) * t; }
  • 39. // so we got a random function! // let's create some stars ⭐
  • 40. // so we got a random function! // let's create some stars ⭐ const starCount = 1000;
  • 41. // so we got a random function! // let's create some stars ⭐ const starCount = 1000; for (let i = 0; i < starCount; i++) { }
  • 42. // so we got a random function! // let's create some stars ⭐ const starCount = 1000; for (let i = 0; i < starCount; i++) { let x = lerp(0, size, Math.random()); let y = lerp(0, size, Math.random()); drawStar(x, y); }
  • 43. // so we got a random function! // let's create some stars ⭐ const starCount = 1000; for (let i = 0; i < starCount; i++) { let x = lerp(0, size, Math.random()); let y = lerp(0, size, Math.random()); drawStar(x, y); }
  • 44. // so we got a random function! // let's create some stars ⭐ const starCount = 1000; for (let i = 0; i < starCount; i++) { let x = lerp(0, size, Math.random()); let y = lerp(0, size, Math.random()); drawStar(x, y); }
  • 45. // so we got a random function! // let's create some stars ⭐ const starCount = 1000; for (let i = 0; i < starCount; i++) { let x = lerp(0, size, Math.random()); let y = lerp(0, size, Math.random()); drawStar(x, y); }
  • 46. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; for (let i = 0; i < starCount; i++) { let x = lerp(0, size, Math.random()); let y = lerp(0, size, Math.random()); drawStar(x, y); } RNG
  • 47. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); rng.random(); // 0.1 rng.random(); // 0.5 rng.random(); // 0.2 rng.random(); // 0.8 const rng2 = new RandomNumberGenerator(seed); rng2.random(); // 0.1 rng2.random(); // 0.5 rng2.random(); // 0.2 rng2.random(); // 0.8 RNG
  • 48. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; for (let i = 0; i < starCount; i++) { let x = lerp(0, size, rng.random()); let y = lerp(0, size, rng.random()); drawStar(x, y); }
  • 49. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; for (let i = 0; i < starCount; i++) { let x = lerp(0, size, rng.random()); let y = lerp(0, size, rng.random()); drawStar(x, y); } (0,0)
  • 50. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; for (let i = 0; i < starCount; i++) { let x = lerp(0, size, rng.random()); let y = lerp(0, size, rng.random()); drawStar(x, y); } (0,0)
  • 51. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let x = lerp(0, size, Math.random()); let y = lerp(0, size, Math.random()); drawStar(x, y); } (0,0)
  • 52. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let x = lerp(-radius, radius, rng.random()); let y = lerp(-radius, radius, rng.random()); drawStar(x + radius, y + radius); } (0,0) y x
  • 53. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = canvasSize / 2; for (let i = 0; i < starCount; i++) { const x = lerp(-radius, radius, rng.random()); const y = lerp(-radius, radius, rng.random()); drawStar(x + radius, y + radius); } y x Cartesian Coordinates (x, y)
  • 54. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = canvasSize / 2; for (let i = 0; i < starCount; i++) { const x = lerp(-radius, radius, rng.random()); const y = lerp(-radius, radius, rng.random()); drawStar(x + radius, y + radius); } Polar Coordinates (r, θ) r θ r
  • 55. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = canvasSize / 2; for (let i = 0; i < starCount; i++) { const x = lerp(-radius, radius, rng.random()); const y = lerp(-radius, radius, rng.random()); drawStar(x + radius, y + radius); } Polar Coordinates (r, θ) r
  • 58. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let x = lerp(-radius, radius, rng.random()); let y = lerp(-radius, radius, rng.random()); drawStar(x + radius, y + radius); } r
  • 59. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp(0, radius, rng.random()); let t = lerp(0, 360deg, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); } r θ r
  • 60. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp(0, radius, rng.random()); let t = lerp(0, 360deg, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); } r θ r
  • 61. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp(0, radius, rng.random()); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); } r θ r
  • 62. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp(0, radius, rng.random()); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); } r θ r
  • 63. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp(0, radius, rng.random()); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); } 🤔
  • 64. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, rng.random() ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); }
  • 65. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, rng.random() ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); }
  • 66. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, rng.random() ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); } 100 100 100 100 100 100 100 100 100 100
  • 67. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Math.sqrt(rng.random()) // <----- ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); } 100 100 100 100 100 100 100 100 100 100 ❌
  • 68. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 1000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Math.sqrt(rng.random()) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); } 👍
  • 69. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 5000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Math.sqrt(rng.random()) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); }
  • 70. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Math.sqrt(rng.random()) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius); }
  • 71. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Math.sqrt(rng.random()) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()) }); }
  • 72. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Math.sqrt(rng.random()) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); }
  • 74. .selector { animation: fade 1s ease-out; }
  • 80. 0 1 linear 1 1 0 100 t = Math.random() y(t) = t 100 100 100 100 100 100 100 100 100 100
  • 81. 0 1 easeOutQuad 1 1 0 t = Math.random() y(t) = t(2 - t) 2 5 10 18 30 45 70 100 150 270 400
  • 82. 0 1 easeInQuad 1 1 0 t = Math.random() y(t) = t 2 251018304570100150270400
  • 84. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Math.sqrt(rng.random()) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); }
  • 85. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Math.sqrt(rng.random()) // <---- t ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); } linear
  • 86. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Ease.inQuart(Math.sqrt(rng.random())) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); } easeInQuart
  • 87. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Ease.outQuart(Math.sqrt(rng.random())) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); } easeOutQuart
  • 88. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Ease.inOutQuart(Math.sqrt(rng.random())) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); } easeInOutQuart
  • 89. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Ease.inOutElastic(Math.sqrt(rng.random())) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); } easeInOutElastic
  • 90. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Ease.inAlot(Math.sqrt(rng.random())) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); } easeInAlot
  • 91. 😓
  • 93.
  • 94.
  • 98.
  • 99.
  • 100. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let r = lerp( 0, radius, Ease.inAlot(Math.sqrt(rng.random())) ); let t = lerp(0, Math.PI * 2, rng.random()); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); }
  • 101. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { // let r = lerp( // 0, // radius, // Ease.inAlot(Math.sqrt(rng.random())) // ); // let t = lerp(0, Math.PI * 2, rng.random.. // const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); } function uniformCircle(radius, easing, t)
  • 102. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { drawStar(x + radius, y + radius, { size: lerp(0.5, 3, rng.random()), color: rng.pickOne(FROM_COLORS) }); }
  • 103. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let { x, y } = spiral({ a: 0.02, b: 0.2, t: rng.random() }); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 104. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let { x, y } = spiral({ a: 0.02, b: 0.2, t: rng.random() }); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 105. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let { x, y } = spiral({ a: 0.02, b: 0.2, t: rng.random() }); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); } 🧐🔍
  • 106. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let { x, y } = spiral({ a: 1, b: 0.5, t: rng.random() * MULTIPLIER }); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 107. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let { x, y } = spiral({ a: 0.02, b: 0.2, t: rng.random() * MULTIPLIER }); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 108. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let { x, y } = spiral({ a: 0.1, b: 1, t: rng.random() * MULTIPLIER }); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 109. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; for (let i = 0; i < starCount; i++) { let { x, y } = spiral({ a: 1, b: 0.5, t: rng.random() * MULTIPLIER }); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 110. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; const arms = 2; for (let i = 0; i < starCount; i++) { let { x, y } = spiral({ a: 1, b: 0.5, t: rng.random() * MULTIPLIER }); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 111. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; const arms = 2; for (let i = 0; i < starCount; i++) { let { r, t } = spiral({ a: 1, b: 0.5, t: rng.random() * MULTIPLIER }); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 112. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; const arms = 2; for (let i = 0; i < starCount; i++) { let { r, t } = spiral({ a: 1, b: 0.5, t: rng.random() * MULTIPLIER }); let arm = rng.lerp(0, arms); t += 2 * Math.PI * Math.floor(arm / arms); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 113. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; const arms = 2; for (let i = 0; i < starCount; i++) { let { r, t } = spiral({ a: 1, b: 0.5, t: rng.random() * MULTIPLIER }); let arm = rng.lerp(0, arms); t += 2 * Math.PI * Math.floor(arm / arms); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 114. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; const arms = 8; for (let i = 0; i < starCount; i++) { let { r, t } = spiral({ a: 1, b: 0.5, t: rng.random() * MULTIPLIER }); let arm = rng.lerp(0, arms); t += 2 * Math.PI * Math.floor(arm / arms); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 115. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; const arms = 2; for (let i = 0; i < starCount; i++) { let { r, t } = spiral({ a: 1, b: 0.2, t: rng.random() * MULTIPLIER }); let arm = rng.lerp(0, arms); t += 2 * Math.PI * Math.floor(arm / arms); const { x, y } = polarToCartesian(r, t); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 116. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; const arms = 2; for (let i = 0; i < starCount; i++) { let { r, t } = spiral({ a: 1, b: 0.2, t: rng.random() * MULTIPLIER }); let arm = rng.lerp(0, arms); t += 2 * Math.PI * Math.floor(arm / arms); let { x, y } = polarToCartesian(r, t); x += rng.uniformCircle(SPREAD, Ease.inQuad); y += rng.uniformCircle(SPREAD, Ease.inQuad); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 117. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 15000; const radius = size / 2; const arms = 2; for (let i = 0; i < starCount; i++) { let { r, t } = spiral({ a: 1, b: 0.2, t: rng.random() * MULTIPLIER }); let arm = rng.lerp(0, arms); t += 2 * Math.PI * Math.floor(arm / arms); let { x, y } = polarToCartesian(r, t); x += rng.uniformCircle(SPREAD, Ease.inQuad); y += rng.uniformCircle(SPREAD, Ease.inQuad); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 118. // so we got a random function! // let's create some stars ⭐ const seed = 1234; const rng = new RandomNumberGenerator(seed); const starCount = 50000; const radius = size / 2; const arms = 2; for (let i = 0; i < starCount; i++) { let { r, t } = spiral({ a: 1, b: 0.2, t: rng.random() * MULTIPLIER }); let arm = rng.lerp(0, arms); t += 2 * Math.PI * Math.floor(arm / arms); let { x, y } = polarToCartesian(r, t); x += rng.uniformCircle(SPREAD, Ease.inQuad); y += rng.uniformCircle(SPREAD, Ease.inQuad); drawStar(x + radius, y + radius, { size: lerp(0.5, 2, rng.random()), color: rng.randomFrom(STAR_COLORS_ARRAY) }); }
  • 120.
  • 121.
  • 122. /* css */ canvas .galaxy-background-glow { filter: blur(200px); }
  • 123. /* css */ canvas .galaxy-background-glow { filter: blur(200px); } canvas .galaxy-nebula-glow { filter: blur(20px); mix-blend-mode: lighten; }
  • 124. /* css */ canvas .galaxy-background-glow { filter: blur(200px); } canvas .galaxy-nebula-glow { filter: blur(20px); mix-blend-mode: lighten; } .galaxy-core { width: 50%; height: 50%; background-color: radial-gradient(...); border-radius: 50%; filter: blur(50px); mix-blend-mode: overlay; }
  • 125.
  • 126.
  • 127.