0xb558906a…7ebasent to0x294fed5f…bc6d·#17,862,883·view on Etherscan
let REF_CANVAS_SIZE = 1024;
let REF_BUFFER_SIZE = 512;
let REF_STROKE_HALF = 0.5;
let REF_STROKE_FULL = 1.0;
let STROKE_QUART = 0.0;
let STROKE_HALF = 0.0;
let STROKE_FULL = 0.0;
let CANVAS_SIZE = 0;
let BUFFER_SIZE = 0;
let BG = "#090809";
let BLACK = "#000000";
let LIME = "#cccc66";
let TURQ = "#04edcd";
let WHITE = "#FFFFFF";
let ORANGE = "#FF9900";
let ORANGE_RED = "#cc6600";
let RED_ORANGE = "#ff4800"
let MID_GREY = "#CCCCCC";
let DRK_GREY = "#333333";
let RED_PINK = "#ff003c";
let GREEN = "#c5cd7a";
let PINK = "#c90a48";
let FRAME_COL = MID_GREY;
let SYSTEM_COL = WHITE;
let SEED;
let RES_MULTI;
let RES_REDUC;
let ROOT_DATA = [];
let HASH_DATA = [];
let BLUR;
let palettes_start =
[
["#cccc66", "#999933", "#999966", "#04edcd"],
["#3d2ba5", "#2b53a5", "#2b4ba5", "#04edcd"],
["#cc3300", "#cc6600", "#cc9933", "#04edcd"],
["#ff003c", "#89223b", "#93237d", "#04edcd"]
];
let palettes_stop =
[
["#cdb966", "#9a8637", "#8d8371", "#88b4a1"],
["#773f61", "#5c5286", "#8d4b4d", "#88b4a1"],
["#cd4a28", "#b36347", "#cd6a31", "#88b4a1"],
["#ed3c34", "#7e264a", "#5c358a", "#88b4a1"]
];
function setup()
{
SEED = parseInt(tokenData.hash.slice(0, 16), 16);
randomSeed(SEED);
noiseSeed(SEED);
noiseDetail(8);
let ss = min(windowWidth, windowHeight);
RES_MULTI = ss / REF_CANVAS_SIZE;
RES_REDUC = REF_CANVAS_SIZE / ss;
CANVAS_SIZE = rm(REF_CANVAS_SIZE);
BUFFER_SIZE = rm(REF_BUFFER_SIZE);
STROKE_HALF = rm(REF_STROKE_HALF);
STROKE_FULL = rm(REF_STROKE_FULL);
STROKE_QUART = STROKE_HALF / 2.0;
createCanvas(CANVAS_SIZE, CANVAS_SIZE, WEBGL);
BLUR = new p5.Shader(this._renderer, blur_vertex, blur_fragment);
shader(BLUR);
set_relicdata();
let MAIN_BUFFER = comp();
fill("#FF9900");
BLUR.setUniform('tex0', MAIN_BUFFER);
BLUR.setUniform('blur_amount', rm(8));
BLUR.setUniform('blur_curve', 1);
BLUR.setUniform('texelSize', [1 / width, 1 / height]);
rect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
}
function set_relicdata()
{
function lerp(start, end, amt)
{
return (1 - amt) * start + amt * end
}
let hashdata = [];
for (let j = 0; j < 32; j++)
{
let pair = tokenData.hash.slice(2 + (j * 2), 4 + (j * 2));
let npair = parseInt(pair, 16) / 255.0;
hashdata.push(npair);
}
let val_count = hashdata[0];
let val_age = hashdata[1];
let val_pallete = hashdata[2];
let val_creep = hashdata[3];
let val_chaos = hashdata[4];
let val_size = hashdata[5];
let min_core_radius = 30;
let max_core_radius = 60;
let min_root_radius = 30;
let max_root_radius = 30;
let min_root_count = 3;
let max_root_count = 8;
let min_age = 10.0;
let max_age = 30.0;
let min_taper = 0.0;
let min_chaos = 1.0;
let max_chaos = 1.5;
let min_creep = 0.0;
let max_creep = max_core_radius;
let min_offset = min_core_radius;
let max_offset = max_core_radius;
let environment_buffer = 10;
let relic_origin = createVector(REF_BUFFER_SIZE / 2, REF_BUFFER_SIZE / 2);
let core_radius = round(lerp(min_core_radius, max_core_radius, val_size));
let root_count = Math.round(lerp(min_root_count, max_root_count, val_count));
let root_nodes = root_count - 2;
let chaos = round(lerp(min_chaos, max_chaos, val_chaos));
let creep = round(lerp(min_creep, max_creep, val_creep));
let greatest_root_radius = 0;
let greatest_offset = 0;
let pallete = Math.round(lerp(0, 3, val_pallete));
for (let i = root_count - 1; i >= 0; i--)
{
let col = rint(2);
let angle = TWO_PI / root_nodes;
let offset = round(lerp(min_offset, max_offset, random(1.0)));
let overlaps = BLACK;
let root_radius = round(lerp(min_root_radius, max_root_radius, random(1.0)));
greatest_root_radius = (root_radius > greatest_root_radius) ? root_radius : greatest_root_radius;
greatest_offset = (offset > greatest_offset) ? offset : greatest_offset;
let max_taper = (root_radius / 2);
let taper = round(lerp(min_taper, max_taper, random(1.0)));
let env_radius = (greatest_root_radius + core_radius + greatest_offset + environment_buffer);
let colour_index = col;
let strength = 120;
let age = round(lerp(min_age, max_age, val_age));
let env_root = (i == 0);
let core_root = (i == 1);
if (env_root)
{
offset = 0.0;
overlaps = -1;
colour_index = 3;
strength = 20;
age = 50;
root_radius = env_radius;
creep = 0;
}
if (core_root)
{
offset = 0.0;
root_radius = core_radius;
strength = 120;
}
ROOT_DATA[i] = get_rootdata(relic_origin, root_radius, angle * (i - 2), age, taper, chaos, creep, offset, overlaps, strength, pallete, colour_index, i);
}
}
function get_rootdata(relic_origin, root_radius, angle, age, taper, chaos, creep, offset, overlaps, strength, pallete, colour_index, no)
{
let root_data =
{
relic_origin: relic_origin,
root_radius: root_radius,
angle: angle,
age: age,
taper: taper,
chaos: chaos,
creep: creep,
offset: offset,
overlaps: overlaps,
pallete: pallete,
colour_index: colour_index,
strength: strength,
no: no
};
return root_data;
}
function comp()
{
let layer_composite = create_layer(CANVAS_SIZE);
layer_composite.background(BG);
let layer_gradient = create_layer(CANVAS_SIZE);
gradient(layer_gradient, 0, 0, CANVAS_SIZE, CANVAS_SIZE, color(BLACK), color(PINK), Axis.y);
render_layer(layer_gradient, layer_composite, ADD, 10, Axis.none);
let layer_holo = create_layer(CANVAS_SIZE);
let layer_basesystem = generate(systems_arrays, Axis.y, BUFFER_SIZE);
render_layer(layer_basesystem, layer_holo, ADD, 40, Axis.y);
render_layer(layer_basesystem, layer_holo, ADD, 10, Axis.x);
render_layer(layer_basesystem, layer_holo, ADD, 10, Axis.z);
let layer_relics = generate(draw_relics, Axis.y, rm(1));
render_layer(layer_relics, layer_holo, ADD, 100, Axis.y, false);
render_layer(layer_relics, layer_holo, ADD, 100, Axis.y, false);
let layer_frame = generate(frame, Axis.x, BUFFER_SIZE / 8);
render_layer(layer_frame, layer_holo, ADD, 80, Axis.x);
render_layer(layer_frame, layer_holo, ADD, 40, Axis.y);
let layer_gradients = generate(grads, Axis.x, BUFFER_SIZE);
render_layer(layer_gradients, layer_holo, ADD, 60, Axis.x);
render_layer(layer_gradients, layer_holo, ADD, 60, Axis.y);
render_layer(layer_gradients, layer_holo, ADD, 60, Axis.z);
render_layer(layer_holo, layer_composite, ADD, 100, Axis.none, CANVAS_SIZE / 2, CANVAS_SIZE / 2, CANVAS_SIZE * 0.9, CANVAS_SIZE * 0.9, CENTER);
render_layer(layer_holo, layer_composite, ADD, 20, Axis.none, CANVAS_SIZE / 2, CANVAS_SIZE / 2, CANVAS_SIZE * 0.9, CANVAS_SIZE * 0.9, CENTER, true, BUFFER_SIZE * 0.9);
return layer_composite;
}
function draw_indicator(surface, x, y, rad, strk)
{
surface.strokeWeight(STROKE_QUART);
surface.stroke(strk);
surface.noFill();
surface.circle(x, y, rad);
let s = rad / 4;
surface.line(x - (s), y, x + s, y);
surface.line(x, y - (s), x, y + (s));
}
function draw_relics(graphics, surface, i, axis)
{
surface.push();
let norm_inc = i / BUFFER_SIZE;
let inc = (axis == Axis.none) ? 0 : i;
surface.translate(inc, inc);
graphics.background("#000000");
graphics.fill(0);
let overall_rotational_increment = PI / BUFFER_SIZE;
let vertex_arrays = [];
let drawn = 0;
for (let j = 0; j < ROOT_DATA.length; j++)
{
let root = ROOT_DATA[j];
let overall_rotation = overall_rotational_increment * i;
let radial_offset = (root.offset + (-1.0 * root.creep * norm_inc) * root.chaos);
let root_angle = root.angle * root.chaos;
let root_origin_x = root.relic_origin.x + (sin(root_angle + overall_rotation) * radial_offset);
let root_origin_y = root.relic_origin.y + (cos(root_angle + overall_rotation) * radial_offset);
let root_origin = createVector(root_origin_x, root_origin_y);
let root_age = root.age;
let root_radius = (root.root_radius - (norm_inc * root.taper) * root.chaos);
let color_start = color(palettes_start[root.pallete][root.colour_index]);
let color_stop = color(palettes_stop[root.pallete][root.colour_index]);
let root_colour = lerpColor(color_start, color_stop, norm_inc);
root_colour.setAlpha(root.strength);
if (noise(rr(i)) > 0.875 && (j % 3 == 0) && (j > 1))
{
draw_indicator(surface, rm(root_origin_x), rm(root_origin_y), rm(root_radius + root_age), 150);
}
vertex_arrays[j] = contour_plot(i, root_origin, root_age, root_radius, root.no);
contour_draw(graphics, vertex_arrays[j], STROKE_HALF, root_colour);
if (i == BUFFER_SIZE)
{
surface.noFill();
surface.strokeWeight(rm(0.05));
surface.stroke(DRK_GREY);
surface.circle(BUFFER_SIZE / 2, BUFFER_SIZE / 2, (ROOT_DATA[0].root_radius * 2 + 20));
}
}
for (let j = 0; j < ROOT_DATA.length; j++)
{
let root = ROOT_DATA[j];
contour_draw(graphics, vertex_arrays[j], STROKE_HALF, -1, root.overlaps);
}
commit(surface, ADD, graphics, axis, 100);
surface.pop();
return surface;
}
function contour_plot(i, origin, age, radius, root_no)
{
let reduced_i = rr(i);
let radial_steps = 50;
let points = [];
let ang = TWO_PI / radial_steps;
let frequency = 0.015;
let affected_radius = radius - abs(sin(reduced_i * 0.01) * radius / 8);
for (let j = 0; j <= radial_steps; j++)
{
let theta = ang * j;
let ct = cos(theta);
let st = sin(theta);
let sample_x = (ct);
let sample_y = (st);
let sample_z = reduced_i * frequency;
let ken = noise(sample_x, sample_y, sample_z);
let noise_offset = ken * age;
let final_radius = ((affected_radius - noise_offset) + noise(reduced_i * 0.1) * 3.0);
let x = rm(origin.x + (final_radius * ct));
let y = rm(origin.y + (final_radius * st));
points.push(createVector(x, y));
}
return points;
}
function contour_draw(surface, vert_array, stroke_weight, stroke_colour = -1, fill_color = -1)
{
if (fill_color == -1) surface.noFill();
else
{
surface.fill(fill_color);
}
if (stroke_colour == -1) surface.noStroke();
else
{
surface.stroke(stroke_colour);
surface.strokeWeight(stroke_weight);
}
surface.beginShape();
for (let k = 1; k < vert_array.length; k++)
{
let x = (vert_array[k].x);
let y = (vert_array[k].y);
surface.vertex(x, y);
}
surface.endShape(CLOSE);
}
function grads(graphics, surface, i, axis)
{
surface.push();
let offset = get_offset_for_axis(axis);
surface.translate(offset.x * i, offset.y * i);
graphics.background("#000000");
graphics.noFill();
gradient(graphics, 0, graphics.height / 2, graphics.width, graphics.height / 2, color(BLACK), color(GREEN), Axis.y);
commit(surface, ADD, graphics, axis, 7);
surface.pop();
return surface;
}
function gradient(surface, x, y, w, h, col_start, col_finish, axis)
{
let col = 0;
surface.strokeWeight(STROKE_FULL);
surface.noFill();
if (axis == Axis.x)
{
for (let i = 0; i < w; i++)
{
col = lerpColor(col_start, col_finish, i / w);
surface.stroke(col);
surface.line(x + i, y, x + i, y + h);
}
} else
{
for (let i = 0; i < h; i++)
{
col = lerpColor(col_start, col_finish, i / h);
surface.stroke(col);
surface.line(x, y + i, x + w, y + i);
}
}
}
function systems_arrays(graphics, surface, i, axis)
{
surface.push();
let offset = get_offset_for_axis(axis);
surface.translate(offset.x * i, offset.y * i);
graphics.background("#000000");
graphics.noFill();
system(graphics)
commit(surface, ADD, graphics, axis, 100);
surface.pop();
return surface;
}
function system(srf)
{
let w = srf.width / 2;
let h = ((srf.width - w) / 2);
srf.background(BLACK);
let cell_size = rm(16);
for (let y = h; y < (BUFFER_SIZE - h); y += cell_size)
{
srf.stroke(64);
srf.strokeWeight(STROKE_FULL);
for (let x = h; x < (BUFFER_SIZE - h); x += cell_size)
{
srf.noStroke();
srf.fill(MID_GREY);
srf.circle(x, y, rm(2));
}
}
let s = subsystem(w, h);
srf.push();
srf.translate(srf.width / 2, srf.height / 2);
for (let i = 0; i < 4; i++)
{
srf.rotate(i * HALF_PI);
srf.imageMode(CORNER);
srf.image(s, -(s.width / 2), -(srf.height / 2));
}
srf.pop();
}
function subsystem(w, h)
{
let surf = createGraphics(w, h);
let remains = surf.height;
function draw_row(row_width, cell_y, cell_h)
{
let divisions = rint(5) + 1;
let row = row_width;
for (let i = 0; i < divisions; i++) row /= 2;
let cell_width = row;
let count = row_width / cell_width;
let stroke_color = color(SYSTEM_COL);
stroke_color.setAlpha(rint(255));
for (let i = 0; i < count; i++)
{
draw_cell(i * cell_width, cell_y, cell_width, cell_h, stroke_color)
}
}
function draw_cell(cx, cy, cw, ch, strk)
{
surf.stroke(strk);
surf.strokeWeight(STROKE_HALF);
surf.fill(BLACK);
surf.rect(cx, cy, cw, ch);
}
while (true)
{
let remove = (128 >> rint(5));
if ((remains - remove) < 0)
{
let r = remains;
remove = r;
remains = 0;
draw_row(surf.width, remains, remove);
break;
}
else
{
remains -= remove;
draw_row(surf.width, remains, remove);
if (remains == 0) break;
}
}
return surf;
}
function generate(draw_function, axis, step_size, iterations = BUFFER_SIZE, surface_size = CANVAS_SIZE, buffer_size = BUFFER_SIZE)
{
let surface = create_layer(surface_size);
let graphics = create_layer(buffer_size);
for (let i = 0; i <= iterations; i += step_size)
{
draw_function(graphics, surface, i, axis);
}
return surface;
}
function get_offset_for_axis(axis)
{
return (axis == Axis.none) ? createVector(0, 0) : createVector(1, 1);
}
function create_layer(dim)
{
let layer = createGraphics(dim, dim);
layer.imageMode(CORNERS);
return layer;
}
function commit(surface, blend_mode, image, axis, opacity_percentage)
{
surface.blendMode(blend_mode);
let opacity = map(opacity_percentage, 0, 100, 0, 255);
if (axis == Axis.x)
{
surface.push();
surface.scale(-0.5, 1);
surface.translate(-image.width, 0);
surface.tint(255, opacity);
surface.image(image, -image.width, 0);
surface.pop();
}
else
{
surface.tint(255, opacity);
surface.image(image, 0, 0);
}
}
function frame(graphics, surface, i, axis)
{
surface.push();
let offset = get_offset_for_axis(axis);
surface.translate(offset.x * i, offset.y * i);
graphics.background("#000000");
graphics.noFill();
graphics.strokeWeight(STROKE_HALF);
graphics.stroke(FRAME_COL);
let b = rm(6);
let s = BUFFER_SIZE;
graphics.line(0, 0, b, 0);
graphics.line(0, 0, 0, b);
graphics.line(s, 0, s, b);
graphics.line(s, 0, s - b, 0);
graphics.line(s, s, s, s - b);
graphics.line(s, s, s - b, s);
graphics.line(0, s, b, s);
graphics.line(0, s, 0, s - b);
graphics.stroke(FRAME_COL);
graphics.strokeWeight(STROKE_HALF);
graphics.rect(0, 0, s, s);
commit(surface, ADD, graphics, axis, rint(75) + 25);
surface.pop();
return surface;
}
function orth(index, layer)
{
let base_x = createVector(rm(1024 - 68), rm(259));
let base_y = createVector(rm(509), rm(1));
let base_z = createVector(rm(68), rm(259));
switch (index)
{
case 0:
layer.translate(base_x.x, base_x.y);
layer.rotate(radians(30.0));
layer.shearX(radians(30.0));
layer.scale(-1.0, 0.86062);
break;
case 1:
layer.translate(base_y.x, base_y.y);
layer.rotate(radians(30.0));
layer.shearX(radians(-30.0));
layer.scale(1.0, 0.86062);
break;
case 2:
layer.translate(base_z.x, base_z.y);
layer.rotate(radians(-30.0));
layer.shearX(radians(-30.0));
layer.scale(1.0, 0.86062);
break;
}
}
function rint(x)
{
return round(random(x));
}
function render_layer(layer, target, blend_mode, opacity_percentage, axis, x = 0, y = 0, w = CANVAS_SIZE, h = CANVAS_SIZE, mode = CORNER, reflect = false, offset_y = 0)
{
target.push();
if (axis != Axis.none) orth(axis, target);
if (reflect)
{
target.scale(1, -1);
target.translate(0, -(CANVAS_SIZE + offset_y));
}
target.imageMode(mode);
target.blendMode(blend_mode);
target.tint(255, map(opacity_percentage, 0, 100, 0, 255));
target.image(layer, x, y, w, h);
target.pop();
}
const Axis =
{
x: 0,
y: 1,
z: 2,
none: 3
};
let blur_vertex =
`
attribute vec3 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
void main() {
vTexCoord = aTexCoord;
vec4 positionVec4 = vec4(aPosition, 1.0);
positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
gl_Position = positionVec4;
}
`;
let blur_fragment =
`
precision mediump float;
varying vec2 vTexCoord;
uniform sampler2D tex0;
uniform float blur_amount;
uniform float blur_curve;
uniform vec2 texelSize;
float gamma = 2.2;
vec3 tone_mapping(vec3 color)
{
color = max(vec3(0.), color - vec3(0.004));
color = (color * (6.2 * color + .5)) / (color * (6.2 * color + 1.7) + 0.06);
return color;
}
void main()
{
vec2 uv = vTexCoord;
uv.y = 1.0 - uv.y;
float x = uv.y;
float curve = (blur_curve==1.0) ? (max(abs( ((x - 0.289) / 0.428 - 0.504) / 0.5 ), (x - 0.289) / 0.428 / 1.085 * -0.056 + 0.5) * 0.533 + -0.247) : 1.0;
float spread = curve * blur_amount;
vec2 offset = texelSize * spread;
vec4 tex = texture2D(tex0, uv);
tex += texture2D(tex0, uv + vec2(-offset.x, -offset.y));
tex += texture2D(tex0, uv + vec2(0.0, -offset.y));
tex += texture2D(tex0, uv + vec2(offset.x, -offset.y));
tex += texture2D(tex0, uv + vec2(-offset.x, 0.0));
tex += texture2D(tex0, uv + vec2(offset.x, 0.0));
tex += texture2D(tex0, uv + vec2(-offset.x, offset.y));
tex += texture2D(tex0, uv + vec2(0.0, offset.y));
tex += texture2D(tex0, uv + vec2(offset.x, offset.y));
tex /= 9.0;
vec3 mapped = tone_mapping(tex.xyz);
float grain = 0.05;
float noise = (fract(sin(dot(uv, vec2(12.9898,78.233)*2.0)) * 43758.5453));
vec3 final = mix(mapped, tex.xyz, 0.71);
vec2 st = vec2(uv.x-0.5, uv.t-0.5) * 2.0;
float vignette = 1.0 - (0.35*length(st));
vec3 col = final - noise * grain;
vec2 bl = step(vec2(0.016),uv);
vec2 tr = step(vec2(0.016),1.0-uv);
vec3 border = vec3(bl.x * bl.y * tr.x * tr.y);
gl_FragColor = vec4(col * vignette * border, 1.0);
}
`;
function rm(value)
{
return RES_MULTI * value;
}
function rr(value)
{
return RES_REDUC * value;
}