From aa35c0242a0be1db3650b77e44502e2e4bac5835 Mon Sep 17 00:00:00 2001 From: bananu7 Date: Tue, 2 Jul 2024 23:26:14 +0200 Subject: [PATCH 1/2] Prototype implementation of a 1D-noise based map edge --- packages/client/src/gfx/MapBorder.tsx | 89 ++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 9 deletions(-) diff --git a/packages/client/src/gfx/MapBorder.tsx b/packages/client/src/gfx/MapBorder.tsx index 68ca5e3..c7fe39a 100644 --- a/packages/client/src/gfx/MapBorder.tsx +++ b/packages/client/src/gfx/MapBorder.tsx @@ -56,7 +56,7 @@ export function MapBorder(props: MapBorderProps) { const color = tileTypeToColor(tileType, vec3Color); // outline darker - vec3Color.g *= Math.abs(f(x,y)); + vec3Color.g *= Math.min(f(x,y), 1.0); const height = tileTypeToHeight(tileType); @@ -72,22 +72,34 @@ export function MapBorder(props: MapBorderProps) { // TODO this code is pretty unreadable, but at least it's only called once + const noise = new Simple1DNoise(); + noise.setAmplitude(1) + noise.setScale(0.05) + + const fadeoff = (f: number, noiseVar: number) => { + return Math.pow(f, 2) * (1 + Math.pow(noise.getVal(noiseVar), 2)); + } + let off = 0; //top - off += createRectangle(off, 0, -borderSize, w, 0, (x,y) => y/borderSize); + off += createRectangle(off, 0, -borderSize, w, 0, (x,y) => fadeoff(y/borderSize, x)); //bottom - off += createRectangle(off, 0, h, w, h+borderSize, (x,y) => (borderSize-y)/borderSize); + off += createRectangle(off, 0, h, w, h+borderSize, (x,y) => fadeoff((borderSize-y)/borderSize, x)); // left - off += createRectangle(off, -borderSize, 0, 0, h, (x,y) => x/borderSize); + off += createRectangle(off, -borderSize, 0, 0, h, (x,y) => fadeoff(x/borderSize, y)); //right - off += createRectangle(off, w, 0, w+borderSize, h, (x,y) => (borderSize-x)/borderSize); + off += createRectangle(off, w, 0, w+borderSize, h, (x,y) => fadeoff((borderSize-x)/borderSize, y)); // top-left off += createRectangle(off, -borderSize, -borderSize, 0, 0, (x,y) => { const xi = borderSize-x; const yi = borderSize-y; - return Math.max(1 - Math.sqrt(xi*xi+yi*yi)/Math.sqrt(borderSize*borderSize), 0); + + const r = Math.max(1 - Math.sqrt(xi*xi+yi*yi)/Math.sqrt(borderSize*borderSize), 0); + const a = Math.atan2(y, x); + + return fadeoff(r, a); } ); @@ -96,7 +108,11 @@ export function MapBorder(props: MapBorderProps) { (x,y) => { const xi = x; const yi = borderSize-y; - return Math.max(1 - Math.sqrt(xi*xi+yi*yi)/Math.sqrt(borderSize*borderSize), 0); + + const r = Math.max(1 - Math.sqrt(xi*xi+yi*yi)/Math.sqrt(borderSize*borderSize), 0); + const a = Math.atan2(y, x); + + return fadeoff(r, a); } ); @@ -105,7 +121,11 @@ export function MapBorder(props: MapBorderProps) { (x,y) => { const xi = borderSize-x; const yi = y; - return Math.max(1 - Math.sqrt(xi*xi+yi*yi)/Math.sqrt(borderSize*borderSize), 0); + + const r = Math.max(1 - Math.sqrt(xi*xi+yi*yi)/Math.sqrt(borderSize*borderSize), 0); + const a = Math.atan2(y, x); + + return fadeoff(r, a); } ); @@ -114,7 +134,11 @@ export function MapBorder(props: MapBorderProps) { (x,y) => { const xi = x; const yi = y; - return Math.max(1 - Math.sqrt(xi*xi+yi*yi)/Math.sqrt(borderSize*borderSize), 0); + + const r = Math.max(1 - Math.sqrt(xi*xi+yi*yi)/Math.sqrt(borderSize*borderSize), 0); + const a = Math.atan2(y, x); + + return fadeoff(r, a); } ); @@ -134,4 +158,51 @@ export function MapBorder(props: MapBorderProps) { ); +} + + +const MAX_VERTICES = 256; +class Simple1DNoise { + vertices: number; + mask: number; + amplitude = 1; + scale = 1; + + r: number[] = []; + + constructor(vertices: number = MAX_VERTICES) { + this.vertices = vertices; + this.mask = vertices - 1; + + for (let i = 0; i < this.vertices; ++i) { + this.r.push(Math.random()); + } + } + + getVal(x: number): number { + const scaledX = x * this.scale; + const xFloor = Math.floor(scaledX); + const t = scaledX - xFloor; + const tRemapSmoothstep = t * t * ( 3 - 2 * t ); + + /// Modulo using & + const xMin = xFloor & this.mask; + const xMax = ( xMin + 1 ) & this.mask; + + const y = Simple1DNoise.lerp( this.r[ xMin ], this.r[ xMax ], tRemapSmoothstep ); + + return y * this.amplitude; + }; + + private static lerp(a: number, b: number, t: number): number { + return a * ( 1 - t ) + b * t; + }; + + setAmplitude(newAmplitude: number) { + this.amplitude = newAmplitude; + } + + setScale(newScale: number) { + this.scale = newScale; + } } \ No newline at end of file From aad2b4e34ba3db0aefc8d093fa2ed81faf2889a6 Mon Sep 17 00:00:00 2001 From: bananu7 Date: Tue, 2 Jul 2024 23:31:32 +0200 Subject: [PATCH 2/2] Added a todo about corners --- packages/client/src/gfx/MapBorder.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/src/gfx/MapBorder.tsx b/packages/client/src/gfx/MapBorder.tsx index c7fe39a..c01a1b8 100644 --- a/packages/client/src/gfx/MapBorder.tsx +++ b/packages/client/src/gfx/MapBorder.tsx @@ -136,6 +136,7 @@ export function MapBorder(props: MapBorderProps) { const yi = y; const r = Math.max(1 - Math.sqrt(xi*xi+yi*yi)/Math.sqrt(borderSize*borderSize), 0); + // TODO: lerp between w and h const a = Math.atan2(y, x); return fadeoff(r, a);