Skip to content

Commit

Permalink
Add a configurable Voronoi grid
Browse files Browse the repository at this point in the history
  • Loading branch information
vhiribarren committed Dec 13, 2023
1 parent 1d240e0 commit 1e48992
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 7 deletions.
86 changes: 86 additions & 0 deletions src/app/noise/voronoi-grid/fragment.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#pragma glslify: random = require(../../../glsl-modules/random)

uniform uint u_frequence;
uniform float u_line_precision;
uniform float u_luminosity;
uniform int u_distance_type;
uniform int u_draw_type;
uniform int u_display_cell_center;

varying vec2 v_uv;

const float INFINITY = 1.0 / 0.0;
const int DISTANCE_EUCLIDIAN = 0;
const int DISTANCE_MANHATTAN = 1;
const int DRAW_WORLEY = 0;
const int DRAW_AREA = 1;
const int DRAW_LINE = 2;


float voronoi_distance(vec2 left, vec2 right) {
if (u_distance_type == DISTANCE_MANHATTAN) {
vec2 diff = right - left;
return abs(diff.x) + abs(diff.y);
} else {
return distance(left, right);
}
}

float generate_color(vec2 cell) {
return random(vec2(length(cell)));
}

vec2 generate_cell(int x, int y) {
return vec2(float(x)+random(vec2(float(x), float(y))), float(y)+random(vec2(float(y), float(x))));
}

void main() {
vec2 size = gl_FragCoord.xy / v_uv;
float ratio = size.x / size.y;

vec2 uv = (v_uv-0.5) * vec2(ratio, 1.0);
uv *= float(u_frequence); // zoom out
//uv *= uv;

//uv.x = cos(length(uv));
//uv.y = sin(length(uv));

float min_dist = INFINITY;
float snd_min_dist = INFINITY;
vec2 min_vcell = vec2(0.0);

int grid_x = int(floor(uv.x));
int grid_y = int(floor(uv.y));
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
vec2 current_vcell = generate_cell(grid_x + i, grid_y + j);
float vcell_dist = voronoi_distance(uv, current_vcell);
if (vcell_dist < min_dist) {
snd_min_dist = min_dist;
min_dist = vcell_dist;
min_vcell = current_vcell;
}
}
}

float color = 0.0;
switch (u_draw_type) {
case DRAW_LINE:
if (abs(min_dist - snd_min_dist) < u_line_precision) {
color = 1.0;
}
break;
case DRAW_AREA:
color = generate_color(min_vcell);
break;
case DRAW_WORLEY:
default:
color = min_dist * u_luminosity;
}

if (u_display_cell_center == 1) {
color = max(color, 1.0-step(0.05, distance(uv, generate_cell(grid_x, grid_y))));
}

gl_FragColor = vec4(vec3(color), 1.0);
}
67 changes: 67 additions & 0 deletions src/app/noise/voronoi-grid/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"use client";

import { NumberInput, Select, Switch } from "@mantine/core";
import fragmentShader from "./fragment.glsl";
import { FragmentLogic, FragmentView } from "@/components/shaders/FragmentView";
import styles from "../../../styles/shaderControl.module.css";
import { useUniform } from "@/components/shaders/uniforms";


const DISTANCE_TYPE = ["Euclidean Distance", "Manhattan Distance"];
const DRAW_TYPE = ["Worley field", "Voronoi Area", "Lines"];

function VoronoiNoiseControl({controlUiTunnel}: FragmentLogic) {
const [freq, setFreq] = useUniform<number>("u_frequence", 20.0);
const [linePrecision, setLinePrecision] = useUniform("u_line_precision", 0.05);
const [distanceType, setDistanceType] = useUniform("u_distance_type", 0);
const [drawType, setDrawType] = useUniform<number>("u_draw_type", 0);
const [displayCellCenter, setDisplayCellCenter] = useUniform<number>("u_display_cell_center", 0);
const [luminosity, setLuminosity] = useUniform("u_luminosity", 1.0);

const ControlUiTunnel = controlUiTunnel;

return (
<ControlUiTunnel>
<div className={styles.shaderControlWrapper}>
<Select
className={styles.shaderControl}
label="Draw type"
placeholder="Pick value"
data={DRAW_TYPE}
value={DRAW_TYPE[drawType]}
onChange={(e) => setDrawType(DRAW_TYPE.indexOf(e!))}
/>
<NumberInput className={styles.shaderControl} label="Frequence" onChange={setFreq} value={freq} min={1} max={10000} decimalScale={2} />
{drawType === 2 &&
<NumberInput className={styles.shaderControl} label="Line precision" onChange={setLinePrecision} value={linePrecision} min={0.0} max={1.0} step={0.001} decimalScale={4} />
}
{drawType === 0 &&
<NumberInput className={styles.shaderControl} label="Luminosity" onChange={setLuminosity} value={luminosity} min={0.0} max={10.0} step={0.1} decimalScale={2} />
}
<Select
className={styles.shaderControl}
label="Distance algorithm"
placeholder="Pick value"
data={DISTANCE_TYPE}
value={DISTANCE_TYPE[distanceType]}
onChange={(e) => setDistanceType(DISTANCE_TYPE.indexOf(e!))}
/>
<Switch
label="Display centers"
checked={displayCellCenter === 1}
onChange={(e) => setDisplayCellCenter(e.currentTarget.checked ? 1 : 0)}
/>
</div>
</ControlUiTunnel>
);
}

export default function Page() {
return (
<FragmentView
title="Voronoi Grid"
fragmentShader={fragmentShader}
withUi={true}
control={VoronoiNoiseControl} />
);
}
4 changes: 0 additions & 4 deletions src/app/noise/voronoi-lines/fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ vec2 generate_cell(uint id) {
return vec2(random(vec2(float(id), 0.0)), random(vec2(float(id), 1.0)));
}

float generate_color(uint id) {
return random(vec2(id));
}

float voronoi_distance(vec2 left, vec2 right) {
if (u_distance_type == DISTANCE_MANHATTAN) {
vec2 diff = right - left;
Expand Down
10 changes: 7 additions & 3 deletions src/config/menu.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,20 @@
"slug": "/noise/value-noise"
},
{
"title": "Random Worley Noise",
"title": "Worley Random",
"slug": "/noise/worley-random"
},
{
"title": "Voronoi Areas",
"title": "Voronoi Random Areas",
"slug": "/noise/voronoi-areas"
},
{
"title": "Voronoi Lines",
"title": "Voronoi Random Lines",
"slug": "/noise/voronoi-lines"
},
{
"title": "Voronoi Grid",
"slug": "/noise/voronoi-grid"
}
]
}]

0 comments on commit 1e48992

Please sign in to comment.