Ensure all shapes are unique
This commit is contained in:
parent
c2f61a2f7e
commit
4d94fdeec8
7 changed files with 135 additions and 108 deletions
|
|
@ -15,8 +15,6 @@ class CircleBase extends EmptyDrawable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Suffixing the GLSL names with a per-factory-invocation id lets multiple
|
|
||||||
// circle types (e.g. different colors) coexist in one compiled shader.
|
|
||||||
let _id = 0;
|
let _id = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ class DropletBase extends EmptyDrawable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _id = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @category Drawable
|
* @category Drawable
|
||||||
*/
|
*/
|
||||||
|
|
@ -27,28 +29,28 @@ export const DropletFactory = (color: vec3 | vec4 | number): typeof DropletBase
|
||||||
public static descriptor: DrawableDescriptor = {
|
public static descriptor: DrawableDescriptor = {
|
||||||
sdf: {
|
sdf: {
|
||||||
shader: `
|
shader: `
|
||||||
uniform vec2 froms[DROPLET_COUNT];
|
uniform vec2 dropletFroms${_id}[DROPLET_COUNT${_id}];
|
||||||
uniform vec2 toFromDeltas[DROPLET_COUNT];
|
uniform vec2 dropletToFromDeltas${_id}[DROPLET_COUNT${_id}];
|
||||||
uniform float fromRadii[DROPLET_COUNT];
|
uniform float dropletFromRadii${_id}[DROPLET_COUNT${_id}];
|
||||||
uniform float toRadii[DROPLET_COUNT];
|
uniform float dropletToRadii${_id}[DROPLET_COUNT${_id}];
|
||||||
|
|
||||||
float dropletMinDistance(vec2 target, out vec4 color) {
|
float dropletMinDistance${_id}(vec2 target, out vec4 color) {
|
||||||
color = ${codeForColorAccess(color)};
|
color = ${codeForColorAccess(color)};
|
||||||
|
|
||||||
float minDistance = 1000.0;
|
float minDistance = 1000.0;
|
||||||
for (int i = 0; i < DROPLET_COUNT; i++) {
|
for (int i = 0; i < DROPLET_COUNT${_id}; i++) {
|
||||||
vec2 targetFromDelta = target - froms[i];
|
vec2 targetFromDelta = target - dropletFroms${_id}[i];
|
||||||
|
|
||||||
float h = clamp(
|
float h = clamp(
|
||||||
dot(targetFromDelta, toFromDeltas[i])
|
dot(targetFromDelta, dropletToFromDeltas${_id}[i])
|
||||||
/ max(dot(toFromDeltas[i], toFromDeltas[i]), 0.00000001),
|
/ max(dot(dropletToFromDeltas${_id}[i], dropletToFromDeltas${_id}[i]), 0.00000001),
|
||||||
0.0, 1.0
|
0.0, 1.0
|
||||||
);
|
);
|
||||||
|
|
||||||
float currentDistance = -mix(
|
float currentDistance = -mix(
|
||||||
fromRadii[i], toRadii[i], h
|
dropletFromRadii${_id}[i], dropletToRadii${_id}[i], h
|
||||||
) + distance(
|
) + distance(
|
||||||
targetFromDelta, toFromDeltas[i] * h
|
targetFromDelta, dropletToFromDeltas${_id}[i] * h
|
||||||
);
|
);
|
||||||
|
|
||||||
minDistance = min(minDistance, currentDistance);
|
minDistance = min(minDistance, currentDistance);
|
||||||
|
|
@ -57,15 +59,15 @@ export const DropletFactory = (color: vec3 | vec4 | number): typeof DropletBase
|
||||||
return minDistance;
|
return minDistance;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
distanceFunctionName: 'dropletMinDistance',
|
distanceFunctionName: `dropletMinDistance${_id}`,
|
||||||
},
|
},
|
||||||
propertyUniformMapping: {
|
propertyUniformMapping: {
|
||||||
from: 'froms',
|
from: `dropletFroms${_id}`,
|
||||||
toFromDelta: 'toFromDeltas',
|
toFromDelta: `dropletToFromDeltas${_id}`,
|
||||||
fromRadius: 'fromRadii',
|
fromRadius: `dropletFromRadii${_id}`,
|
||||||
toRadius: 'toRadii',
|
toRadius: `dropletToRadii${_id}`,
|
||||||
},
|
},
|
||||||
uniformCountMacroName: 'DROPLET_COUNT',
|
uniformCountMacroName: `DROPLET_COUNT${_id}`,
|
||||||
shaderCombinationSteps: [0, 1, 4, 16, 32],
|
shaderCombinationSteps: [0, 1, 4, 16, 32],
|
||||||
empty: new Droplet(vec2.create(), vec2.create(), 0, 0),
|
empty: new Droplet(vec2.create(), vec2.create(), 0, 0),
|
||||||
};
|
};
|
||||||
|
|
@ -96,5 +98,7 @@ export const DropletFactory = (color: vec3 | vec4 | number): typeof DropletBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_id++;
|
||||||
|
|
||||||
return Droplet;
|
return Droplet;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ class HexagonBase extends EmptyDrawable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _id = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @category Drawable
|
* @category Drawable
|
||||||
*/
|
*/
|
||||||
|
|
@ -23,16 +25,16 @@ export const HexagonFactory = (color: vec3 | vec4 | number): typeof HexagonBase
|
||||||
public static descriptor: DrawableDescriptor = {
|
public static descriptor: DrawableDescriptor = {
|
||||||
sdf: {
|
sdf: {
|
||||||
shader: `
|
shader: `
|
||||||
uniform vec2 hexagonCenters[HEXAGON_COUNT];
|
uniform vec2 hexagonCenters${_id}[HEXAGON_COUNT${_id}];
|
||||||
uniform float hexagonSize[HEXAGON_COUNT];
|
uniform float hexagonSize${_id}[HEXAGON_COUNT${_id}];
|
||||||
|
|
||||||
float hexagonMinDistance(vec2 target, out vec4 color) {
|
float hexagonMinDistance${_id}(vec2 target, out vec4 color) {
|
||||||
color = ${codeForColorAccess(color)};
|
color = ${codeForColorAccess(color)};
|
||||||
float minDistance = 1000.0;
|
float minDistance = 1000.0;
|
||||||
for (int i = 0; i < HEXAGON_COUNT; i++) {
|
for (int i = 0; i < HEXAGON_COUNT${_id}; i++) {
|
||||||
const vec3 k = vec3(-0.866025404,0.5,0.577350269);
|
const vec3 k = vec3(-0.866025404,0.5,0.577350269);
|
||||||
float r = hexagonSize[i];
|
float r = hexagonSize${_id}[i];
|
||||||
vec2 p = abs(target - hexagonCenters[i]);
|
vec2 p = abs(target - hexagonCenters${_id}[i]);
|
||||||
float cosa = 0.8660;
|
float cosa = 0.8660;
|
||||||
float sina = 0.5;
|
float sina = 0.5;
|
||||||
p = vec2(cosa * p.x - sina * p.y, sina * p.x + cosa * p.y);
|
p = vec2(cosa * p.x - sina * p.y, sina * p.x + cosa * p.y);
|
||||||
|
|
@ -45,13 +47,13 @@ export const HexagonFactory = (color: vec3 | vec4 | number): typeof HexagonBase
|
||||||
return minDistance;
|
return minDistance;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
distanceFunctionName: 'hexagonMinDistance',
|
distanceFunctionName: `hexagonMinDistance${_id}`,
|
||||||
},
|
},
|
||||||
propertyUniformMapping: {
|
propertyUniformMapping: {
|
||||||
center: 'hexagonCenters',
|
center: `hexagonCenters${_id}`,
|
||||||
radius: 'hexagonSize',
|
radius: `hexagonSize${_id}`,
|
||||||
},
|
},
|
||||||
uniformCountMacroName: 'HEXAGON_COUNT',
|
uniformCountMacroName: `HEXAGON_COUNT${_id}`,
|
||||||
shaderCombinationSteps: [0, 1, 2, 3, 8, 16],
|
shaderCombinationSteps: [0, 1, 2, 3, 8, 16],
|
||||||
empty: new Hexagon(vec2.create(), 0),
|
empty: new Hexagon(vec2.create(), 0),
|
||||||
};
|
};
|
||||||
|
|
@ -68,5 +70,7 @@ export const HexagonFactory = (color: vec3 | vec4 | number): typeof HexagonBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_id++;
|
||||||
|
|
||||||
return Hexagon;
|
return Hexagon;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ class InvertedTunnelBase extends EmptyDrawable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _id = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Providing a noise texture is required for this drawable.
|
* Providing a noise texture is required for this drawable.
|
||||||
*
|
*
|
||||||
|
|
@ -31,10 +33,10 @@ export const InvertedTunnelFactory = (
|
||||||
public static descriptor: DrawableDescriptor = {
|
public static descriptor: DrawableDescriptor = {
|
||||||
sdf: {
|
sdf: {
|
||||||
shader: `
|
shader: `
|
||||||
uniform vec2 froms[INVERTED_TUNNEL_COUNT];
|
uniform vec2 invertedTunnelFroms${_id}[INVERTED_TUNNEL_COUNT${_id}];
|
||||||
uniform vec2 toFromDeltas[INVERTED_TUNNEL_COUNT];
|
uniform vec2 invertedTunnelToFromDeltas${_id}[INVERTED_TUNNEL_COUNT${_id}];
|
||||||
uniform float fromRadii[INVERTED_TUNNEL_COUNT];
|
uniform float invertedTunnelFromRadii${_id}[INVERTED_TUNNEL_COUNT${_id}];
|
||||||
uniform float toRadii[INVERTED_TUNNEL_COUNT];
|
uniform float invertedTunnelToRadii${_id}[INVERTED_TUNNEL_COUNT${_id}];
|
||||||
|
|
||||||
// Other drawables share this declaration; the include guard keeps
|
// Other drawables share this declaration; the include guard keeps
|
||||||
// the combined shader from declaring it twice.
|
// the combined shader from declaring it twice.
|
||||||
|
|
@ -43,6 +45,10 @@ export const InvertedTunnelFactory = (
|
||||||
uniform sampler2D noiseTexture;
|
uniform sampler2D noiseTexture;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Shared between every inverted-tunnel variant; the include guard
|
||||||
|
// keeps the combined shader from defining it twice.
|
||||||
|
#ifndef INVERTED_TUNNEL_TERRAIN_DECLARED
|
||||||
|
#define INVERTED_TUNNEL_TERRAIN_DECLARED
|
||||||
#ifdef WEBGL2_IS_AVAILABLE
|
#ifdef WEBGL2_IS_AVAILABLE
|
||||||
float invertedTunnelTerrain(float h) {
|
float invertedTunnelTerrain(float h) {
|
||||||
return texture(
|
return texture(
|
||||||
|
|
@ -58,24 +64,25 @@ export const InvertedTunnelFactory = (
|
||||||
)[0] - 0.5;
|
)[0] - 0.5;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
float invertedTunnelMinDistance(vec2 target, out vec4 color) {
|
float invertedTunnelMinDistance${_id}(vec2 target, out vec4 color) {
|
||||||
color = ${codeForColorAccess(color)};
|
color = ${codeForColorAccess(color)};
|
||||||
|
|
||||||
float minDistance = -1000.0;
|
float minDistance = -1000.0;
|
||||||
for (int i = 0; i < INVERTED_TUNNEL_COUNT; i++) {
|
for (int i = 0; i < INVERTED_TUNNEL_COUNT${_id}; i++) {
|
||||||
|
|
||||||
vec2 targetFromDelta = target - froms[i];
|
vec2 targetFromDelta = target - invertedTunnelFroms${_id}[i];
|
||||||
|
|
||||||
float h = dot(targetFromDelta, toFromDeltas[i])
|
float h = dot(targetFromDelta, invertedTunnelToFromDeltas${_id}[i])
|
||||||
/ max(dot(toFromDeltas[i], toFromDeltas[i]), 0.00000001);
|
/ max(dot(invertedTunnelToFromDeltas${_id}[i], invertedTunnelToFromDeltas${_id}[i]), 0.00000001);
|
||||||
|
|
||||||
float clampedH = clamp(h, 0.0, 1.0);
|
float clampedH = clamp(h, 0.0, 1.0);
|
||||||
|
|
||||||
float currentDistance = -mix(
|
float currentDistance = -mix(
|
||||||
fromRadii[i], toRadii[i], clampedH
|
invertedTunnelFromRadii${_id}[i], invertedTunnelToRadii${_id}[i], clampedH
|
||||||
) + distance(
|
) + distance(
|
||||||
targetFromDelta, toFromDeltas[i] * clampedH
|
targetFromDelta, invertedTunnelToFromDeltas${_id}[i] * clampedH
|
||||||
) - invertedTunnelTerrain(h) / 12.0;
|
) - invertedTunnelTerrain(h) / 12.0;
|
||||||
|
|
||||||
minDistance = max(minDistance, -currentDistance);
|
minDistance = max(minDistance, -currentDistance);
|
||||||
|
|
@ -85,15 +92,15 @@ export const InvertedTunnelFactory = (
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
isInverted: true,
|
isInverted: true,
|
||||||
distanceFunctionName: 'invertedTunnelMinDistance',
|
distanceFunctionName: `invertedTunnelMinDistance${_id}`,
|
||||||
},
|
},
|
||||||
propertyUniformMapping: {
|
propertyUniformMapping: {
|
||||||
from: 'froms',
|
from: `invertedTunnelFroms${_id}`,
|
||||||
toFromDelta: 'toFromDeltas',
|
toFromDelta: `invertedTunnelToFromDeltas${_id}`,
|
||||||
fromRadius: 'fromRadii',
|
fromRadius: `invertedTunnelFromRadii${_id}`,
|
||||||
toRadius: 'toRadii',
|
toRadius: `invertedTunnelToRadii${_id}`,
|
||||||
},
|
},
|
||||||
uniformCountMacroName: 'INVERTED_TUNNEL_COUNT',
|
uniformCountMacroName: `INVERTED_TUNNEL_COUNT${_id}`,
|
||||||
shaderCombinationSteps: [0, 1, 4, 16, 32],
|
shaderCombinationSteps: [0, 1, 4, 16, 32],
|
||||||
empty: new InvertedTunnel(vec2.create(), vec2.create(), 0, 0),
|
empty: new InvertedTunnel(vec2.create(), vec2.create(), 0, 0),
|
||||||
};
|
};
|
||||||
|
|
@ -124,5 +131,7 @@ export const InvertedTunnelFactory = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_id++;
|
||||||
|
|
||||||
return InvertedTunnel;
|
return InvertedTunnel;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ interface NoisyPolygonBase extends PolygonBase {
|
||||||
randomOffset: number;
|
randomOffset: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _id = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @category Drawable
|
* @category Drawable
|
||||||
*/
|
*/
|
||||||
|
|
@ -19,10 +21,10 @@ export const NoisyPolygonFactory = (
|
||||||
public static descriptor: DrawableDescriptor = {
|
public static descriptor: DrawableDescriptor = {
|
||||||
sdf: {
|
sdf: {
|
||||||
shader: `
|
shader: `
|
||||||
uniform vec2 noisyPolygon${vertexCount}Vertices[NOISY_POLYGON${vertexCount}_COUNT * ${vertexCount}];
|
uniform vec2 noisyPolygon${vertexCount}Vertices${_id}[NOISY_POLYGON${vertexCount}_COUNT${_id} * ${vertexCount}];
|
||||||
uniform vec2 noisyPolygon${vertexCount}Centers[NOISY_POLYGON${vertexCount}_COUNT];
|
uniform vec2 noisyPolygon${vertexCount}Centers${_id}[NOISY_POLYGON${vertexCount}_COUNT${_id}];
|
||||||
uniform float noisyPolygon${vertexCount}Lengths[NOISY_POLYGON${vertexCount}_COUNT];
|
uniform float noisyPolygon${vertexCount}Lengths${_id}[NOISY_POLYGON${vertexCount}_COUNT${_id}];
|
||||||
uniform float noisyPolygon${vertexCount}Randoms[NOISY_POLYGON${vertexCount}_COUNT];
|
uniform float noisyPolygon${vertexCount}Randoms${_id}[NOISY_POLYGON${vertexCount}_COUNT${_id}];
|
||||||
|
|
||||||
// Other drawables (and other vertex-count variants of this one)
|
// Other drawables (and other vertex-count variants of this one)
|
||||||
// share these declarations; the include guards keep the combined
|
// share these declarations; the include guards keep the combined
|
||||||
|
|
@ -45,7 +47,7 @@ export const NoisyPolygonFactory = (
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec2 noisyPolygon${vertexCount}LineDistance(vec2 target, vec2 from, vec2 to) {
|
vec2 noisyPolygon${vertexCount}LineDistance${_id}(vec2 target, vec2 from, vec2 to) {
|
||||||
vec2 targetFromDelta = target - from;
|
vec2 targetFromDelta = target - from;
|
||||||
vec2 toFromDelta = to - from;
|
vec2 toFromDelta = to - from;
|
||||||
float h = clamp(
|
float h = clamp(
|
||||||
|
|
@ -61,18 +63,18 @@ export const NoisyPolygonFactory = (
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
float noisyPolygon${vertexCount}MinDistance(vec2 target, out vec4 color) {
|
float noisyPolygon${vertexCount}MinDistance${_id}(vec2 target, out vec4 color) {
|
||||||
color = ${codeForColorAccess(color)};
|
color = ${codeForColorAccess(color)};
|
||||||
|
|
||||||
float minDistance = 100.0;
|
float minDistance = 100.0;
|
||||||
|
|
||||||
for (int j = 0; j < NOISY_POLYGON${vertexCount}_COUNT; j++) {
|
for (int j = 0; j < NOISY_POLYGON${vertexCount}_COUNT${_id}; j++) {
|
||||||
vec2 startEnd = noisyPolygon${vertexCount}Vertices[j * ${vertexCount}];
|
vec2 startEnd = noisyPolygon${vertexCount}Vertices${_id}[j * ${vertexCount}];
|
||||||
vec2 vb = startEnd;
|
vec2 vb = startEnd;
|
||||||
|
|
||||||
vec2 center = noisyPolygon${vertexCount}Centers[j];
|
vec2 center = noisyPolygon${vertexCount}Centers${_id}[j];
|
||||||
float l = noisyPolygon${vertexCount}Lengths[j];
|
float l = noisyPolygon${vertexCount}Lengths${_id}[j];
|
||||||
float randomOffset = noisyPolygon${vertexCount}Randoms[j];
|
float randomOffset = noisyPolygon${vertexCount}Randoms${_id}[j];
|
||||||
vec2 targetCenterDelta = target - center;
|
vec2 targetCenterDelta = target - center;
|
||||||
float targetDistance = length(targetCenterDelta);
|
float targetDistance = length(targetCenterDelta);
|
||||||
vec2 targetTangent = targetCenterDelta / clamp(targetDistance, 0.01, 1000.0);
|
vec2 targetTangent = targetCenterDelta / clamp(targetDistance, 0.01, 1000.0);
|
||||||
|
|
@ -88,8 +90,8 @@ export const NoisyPolygonFactory = (
|
||||||
float s = 1.0;
|
float s = 1.0;
|
||||||
for (int k = 1; k < ${vertexCount}; k++) {
|
for (int k = 1; k < ${vertexCount}; k++) {
|
||||||
vec2 va = vb;
|
vec2 va = vb;
|
||||||
vb = noisyPolygon${vertexCount}Vertices[j * ${vertexCount} + k];
|
vb = noisyPolygon${vertexCount}Vertices${_id}[j * ${vertexCount} + k];
|
||||||
vec2 ds = noisyPolygon${vertexCount}LineDistance(noisyTarget, va, vb);
|
vec2 ds = noisyPolygon${vertexCount}LineDistance${_id}(noisyTarget, va, vb);
|
||||||
|
|
||||||
bvec3 cond = bvec3(noisyTarget.y >= va.y, noisyTarget.y < vb.y, ds.y > 0.0);
|
bvec3 cond = bvec3(noisyTarget.y >= va.y, noisyTarget.y < vb.y, ds.y > 0.0);
|
||||||
if (all(cond) || all(not(cond))) {
|
if (all(cond) || all(not(cond))) {
|
||||||
|
|
@ -99,7 +101,7 @@ export const NoisyPolygonFactory = (
|
||||||
d = min(d, ds.x);
|
d = min(d, ds.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 ds = noisyPolygon${vertexCount}LineDistance(noisyTarget, vb, startEnd);
|
vec2 ds = noisyPolygon${vertexCount}LineDistance${_id}(noisyTarget, vb, startEnd);
|
||||||
bvec3 cond = bvec3(noisyTarget.y >= vb.y, noisyTarget.y < startEnd.y, ds.y > 0.0);
|
bvec3 cond = bvec3(noisyTarget.y >= vb.y, noisyTarget.y < startEnd.y, ds.y > 0.0);
|
||||||
if (all(cond) || all(not(cond))) {
|
if (all(cond) || all(not(cond))) {
|
||||||
s *= -1.0;
|
s *= -1.0;
|
||||||
|
|
@ -112,15 +114,15 @@ export const NoisyPolygonFactory = (
|
||||||
return minDistance;
|
return minDistance;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
distanceFunctionName: `noisyPolygon${vertexCount}MinDistance`,
|
distanceFunctionName: `noisyPolygon${vertexCount}MinDistance${_id}`,
|
||||||
},
|
},
|
||||||
propertyUniformMapping: {
|
propertyUniformMapping: {
|
||||||
length: `noisyPolygon${vertexCount}Lengths`,
|
length: `noisyPolygon${vertexCount}Lengths${_id}`,
|
||||||
random: `noisyPolygon${vertexCount}Randoms`,
|
random: `noisyPolygon${vertexCount}Randoms${_id}`,
|
||||||
center: `noisyPolygon${vertexCount}Centers`,
|
center: `noisyPolygon${vertexCount}Centers${_id}`,
|
||||||
vertices: `noisyPolygon${vertexCount}Vertices`,
|
vertices: `noisyPolygon${vertexCount}Vertices${_id}`,
|
||||||
},
|
},
|
||||||
uniformCountMacroName: `NOISY_POLYGON${vertexCount}_COUNT`,
|
uniformCountMacroName: `NOISY_POLYGON${vertexCount}_COUNT${_id}`,
|
||||||
shaderCombinationSteps: [0, 1, 2, 3, 8, 16],
|
shaderCombinationSteps: [0, 1, 2, 3, 8, 16],
|
||||||
empty: new NoisyPolygon(
|
empty: new NoisyPolygon(
|
||||||
new Array(vertexCount).fill(vec2.create())
|
new Array(vertexCount).fill(vec2.create())
|
||||||
|
|
@ -183,5 +185,7 @@ export const NoisyPolygonFactory = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_id++;
|
||||||
|
|
||||||
return NoisyPolygon as any;
|
return NoisyPolygon as any;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ export class PolygonBase extends EmptyDrawable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _id = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @category Drawable
|
* @category Drawable
|
||||||
*/
|
*/
|
||||||
|
|
@ -25,9 +27,9 @@ export const PolygonFactory = (
|
||||||
public static descriptor: DrawableDescriptor = {
|
public static descriptor: DrawableDescriptor = {
|
||||||
sdf: {
|
sdf: {
|
||||||
shader: `
|
shader: `
|
||||||
uniform vec2 polygon${vertexCount}Vertices[POLYGON${vertexCount}_COUNT * ${vertexCount}];
|
uniform vec2 polygon${vertexCount}Vertices${_id}[POLYGON${vertexCount}_COUNT${_id} * ${vertexCount}];
|
||||||
|
|
||||||
vec2 polygon${vertexCount}LineDistance(vec2 target, vec2 from, vec2 to) {
|
vec2 polygon${vertexCount}LineDistance${_id}(vec2 target, vec2 from, vec2 to) {
|
||||||
vec2 targetFromDelta = target - from;
|
vec2 targetFromDelta = target - from;
|
||||||
vec2 toFromDelta = to - from;
|
vec2 toFromDelta = to - from;
|
||||||
float h = clamp(
|
float h = clamp(
|
||||||
|
|
@ -43,21 +45,21 @@ export const PolygonFactory = (
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
float polygon${vertexCount}MinDistance(vec2 target, out vec4 color) {
|
float polygon${vertexCount}MinDistance${_id}(vec2 target, out vec4 color) {
|
||||||
color = ${codeForColorAccess(color)};
|
color = ${codeForColorAccess(color)};
|
||||||
|
|
||||||
float minDistance = 100.0;
|
float minDistance = 100.0;
|
||||||
|
|
||||||
for (int j = 0; j < POLYGON${vertexCount}_COUNT; j++) {
|
for (int j = 0; j < POLYGON${vertexCount}_COUNT${_id}; j++) {
|
||||||
vec2 startEnd = polygon${vertexCount}Vertices[j * ${vertexCount}];
|
vec2 startEnd = polygon${vertexCount}Vertices${_id}[j * ${vertexCount}];
|
||||||
vec2 vb = startEnd;
|
vec2 vb = startEnd;
|
||||||
|
|
||||||
float d = 10000.0;
|
float d = 10000.0;
|
||||||
float s = 1.0;
|
float s = 1.0;
|
||||||
for (int k = 1; k < ${vertexCount}; k++) {
|
for (int k = 1; k < ${vertexCount}; k++) {
|
||||||
vec2 va = vb;
|
vec2 va = vb;
|
||||||
vb = polygon${vertexCount}Vertices[j * ${vertexCount} + k];
|
vb = polygon${vertexCount}Vertices${_id}[j * ${vertexCount} + k];
|
||||||
vec2 ds = polygon${vertexCount}LineDistance(target, va, vb);
|
vec2 ds = polygon${vertexCount}LineDistance${_id}(target, va, vb);
|
||||||
|
|
||||||
bvec3 cond = bvec3(target.y >= va.y, target.y < vb.y, ds.y > 0.0);
|
bvec3 cond = bvec3(target.y >= va.y, target.y < vb.y, ds.y > 0.0);
|
||||||
if (all(cond) || all(not(cond))) {
|
if (all(cond) || all(not(cond))) {
|
||||||
|
|
@ -67,7 +69,7 @@ export const PolygonFactory = (
|
||||||
d = min(d, ds.x);
|
d = min(d, ds.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 ds = polygon${vertexCount}LineDistance(target, vb, startEnd);
|
vec2 ds = polygon${vertexCount}LineDistance${_id}(target, vb, startEnd);
|
||||||
bvec3 cond = bvec3(target.y >= vb.y, target.y < startEnd.y, ds.y > 0.0);
|
bvec3 cond = bvec3(target.y >= vb.y, target.y < startEnd.y, ds.y > 0.0);
|
||||||
if (all(cond) || all(not(cond))) {
|
if (all(cond) || all(not(cond))) {
|
||||||
s *= -1.0;
|
s *= -1.0;
|
||||||
|
|
@ -80,13 +82,13 @@ export const PolygonFactory = (
|
||||||
return minDistance;
|
return minDistance;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
distanceFunctionName: `polygon${vertexCount}MinDistance`,
|
distanceFunctionName: `polygon${vertexCount}MinDistance${_id}`,
|
||||||
},
|
},
|
||||||
propertyUniformMapping: {
|
propertyUniformMapping: {
|
||||||
vertices: `polygon${vertexCount}Vertices`,
|
vertices: `polygon${vertexCount}Vertices${_id}`,
|
||||||
},
|
},
|
||||||
objectCountScaler: 1 / vertexCount,
|
objectCountScaler: 1 / vertexCount,
|
||||||
uniformCountMacroName: `POLYGON${vertexCount}_COUNT`,
|
uniformCountMacroName: `POLYGON${vertexCount}_COUNT${_id}`,
|
||||||
shaderCombinationSteps: [0, 1, 2, 3, 8, 16],
|
shaderCombinationSteps: [0, 1, 2, 3, 8, 16],
|
||||||
empty: new Polygon(new Array(vertexCount).fill(vec2.create())),
|
empty: new Polygon(new Array(vertexCount).fill(vec2.create())),
|
||||||
};
|
};
|
||||||
|
|
@ -178,5 +180,7 @@ export const PolygonFactory = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_id++;
|
||||||
|
|
||||||
return Polygon;
|
return Polygon;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ class RotatedRectangleBase extends EmptyDrawable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _id = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @category Drawable
|
* @category Drawable
|
||||||
*/
|
*/
|
||||||
|
|
@ -27,23 +29,23 @@ export const RotatedRectangleFactory = (
|
||||||
sdf: {
|
sdf: {
|
||||||
// Source: https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
|
// Source: https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
|
||||||
shader: `
|
shader: `
|
||||||
uniform vec2 rotatedRectangleTopCenters[ROTATED_RECTANGLE_COUNT];
|
uniform vec2 rotatedRectangleTopCenters${_id}[ROTATED_RECTANGLE_COUNT${_id}];
|
||||||
uniform vec2 rotatedRectangleBottomCenters[ROTATED_RECTANGLE_COUNT];
|
uniform vec2 rotatedRectangleBottomCenters${_id}[ROTATED_RECTANGLE_COUNT${_id}];
|
||||||
uniform float rotatedRectangleWidths[ROTATED_RECTANGLE_COUNT];
|
uniform float rotatedRectangleWidths${_id}[ROTATED_RECTANGLE_COUNT${_id}];
|
||||||
|
|
||||||
float rotatedRectangleMinDistance(vec2 target, out vec4 color) {
|
float rotatedRectangleMinDistance${_id}(vec2 target, out vec4 color) {
|
||||||
color = ${codeForColorAccess(color)};
|
color = ${codeForColorAccess(color)};
|
||||||
|
|
||||||
float minDistance = 1000.0;
|
float minDistance = 1000.0;
|
||||||
for (int i = 0; i < ROTATED_RECTANGLE_COUNT; i++) {
|
for (int i = 0; i < ROTATED_RECTANGLE_COUNT${_id}; i++) {
|
||||||
vec2 top = rotatedRectangleTopCenters[i];
|
vec2 top = rotatedRectangleTopCenters${_id}[i];
|
||||||
vec2 bottom = rotatedRectangleBottomCenters[i];
|
vec2 bottom = rotatedRectangleBottomCenters${_id}[i];
|
||||||
float height = length(bottom - top);
|
float height = length(bottom - top);
|
||||||
vec2 d = height > 0.00000001 ? (bottom - top) / height : vec2(0.0, 1.0);
|
vec2 d = height > 0.00000001 ? (bottom - top) / height : vec2(0.0, 1.0);
|
||||||
|
|
||||||
vec2 q = (target - (top + bottom) * 0.5);
|
vec2 q = (target - (top + bottom) * 0.5);
|
||||||
q = mat2(d.x, -d.y, d.y, d.x) * q;
|
q = mat2(d.x, -d.y, d.y, d.x) * q;
|
||||||
q = abs(q) - vec2(height, rotatedRectangleWidths[i]) * 0.5;
|
q = abs(q) - vec2(height, rotatedRectangleWidths${_id}[i]) * 0.5;
|
||||||
float dist = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0);
|
float dist = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0);
|
||||||
minDistance = min(minDistance, dist);
|
minDistance = min(minDistance, dist);
|
||||||
}
|
}
|
||||||
|
|
@ -51,20 +53,20 @@ export const RotatedRectangleFactory = (
|
||||||
return minDistance;
|
return minDistance;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
distanceFunctionName: 'rotatedRectangleMinDistance',
|
distanceFunctionName: `rotatedRectangleMinDistance${_id}`,
|
||||||
},
|
},
|
||||||
propertyUniformMapping: {
|
propertyUniformMapping: {
|
||||||
topCenter: 'rotatedRectangleTopCenters',
|
topCenter: `rotatedRectangleTopCenters${_id}`,
|
||||||
bottomCenter: 'rotatedRectangleBottomCenters',
|
bottomCenter: `rotatedRectangleBottomCenters${_id}`,
|
||||||
width: 'rotatedRectangleWidths',
|
width: `rotatedRectangleWidths${_id}`,
|
||||||
},
|
},
|
||||||
uniformCountMacroName: 'ROTATED_RECTANGLE_COUNT',
|
uniformCountMacroName: `ROTATED_RECTANGLE_COUNT${_id}`,
|
||||||
shaderCombinationSteps: [0, 1, 2, 3, 8, 16],
|
shaderCombinationSteps: [0, 1, 2, 3, 8, 16],
|
||||||
empty: new RotatedRectangle(vec2.create(), vec2.create(), 0),
|
empty: new RotatedRectangle(vec2.create(), vec2.create(), 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is just an estimate by calculating a bounding circle
|
* This is only an estimate, computed from a bounding circle.
|
||||||
* @param target
|
* @param target
|
||||||
*/
|
*/
|
||||||
public minDistance(target: vec2): number {
|
public minDistance(target: vec2): number {
|
||||||
|
|
@ -91,5 +93,7 @@ export const RotatedRectangleFactory = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_id++;
|
||||||
|
|
||||||
return RotatedRectangle;
|
return RotatedRectangle;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue