Add WebGL compatibility
This commit is contained in:
parent
3725f56c78
commit
1d4980ae28
29 changed files with 567 additions and 212 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import { Drawable } from './drawable';
|
||||
|
||||
export interface DrawableDescriptor {
|
||||
uniformName: string;
|
||||
propertyUniformMapping: { [property: string]: string };
|
||||
uniformCountMacroName: string;
|
||||
sdf?: {
|
||||
shader: string;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ export abstract class Drawable {
|
|||
public static readonly descriptor: DrawableDescriptor;
|
||||
|
||||
public abstract minDistance(target: vec2): number;
|
||||
|
||||
protected abstract getObjectToSerialize(transform2d: mat2d, transform1d: number): any;
|
||||
|
||||
public serializeToUniforms(
|
||||
|
|
@ -14,12 +13,15 @@ export abstract class Drawable {
|
|||
transform2d: mat2d,
|
||||
transform1d: number
|
||||
): void {
|
||||
const { uniformName } = (this.constructor as typeof Drawable).descriptor;
|
||||
const { propertyUniformMapping } = (this.constructor as typeof Drawable).descriptor;
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(uniforms, uniformName)) {
|
||||
uniforms[uniformName] = [];
|
||||
}
|
||||
const serialized = this.getObjectToSerialize(transform2d, transform1d);
|
||||
Object.entries(propertyUniformMapping).forEach(([k, v]) => {
|
||||
if (!Object.prototype.hasOwnProperty.call(uniforms, v)) {
|
||||
uniforms[v] = [];
|
||||
}
|
||||
|
||||
uniforms[uniformName].push(this.getObjectToSerialize(transform2d, transform1d));
|
||||
uniforms[v].push(serialized[k]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,13 @@ import { LightDrawable } from './light-drawable';
|
|||
|
||||
export class CircleLight extends LightDrawable {
|
||||
public static readonly descriptor: DrawableDescriptor = {
|
||||
uniformName: 'circleLights',
|
||||
propertyUniformMapping: {
|
||||
center: 'circleLightCenters',
|
||||
color: 'circleLightColors',
|
||||
intensity: 'circleLightIntensities',
|
||||
},
|
||||
uniformCountMacroName: 'CIRCLE_LIGHT_COUNT',
|
||||
shaderCombinationSteps: [0, 1, 2, 4, 8],
|
||||
shaderCombinationSteps: [0, 1, 2, 4, 8, 16],
|
||||
empty: new CircleLight(vec2.fromValues(0, 0), vec3.fromValues(0, 0, 0), 0),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,12 @@ import { LightDrawable } from './light-drawable';
|
|||
|
||||
export class Flashlight extends LightDrawable {
|
||||
public static readonly descriptor: DrawableDescriptor = {
|
||||
uniformName: 'flashlights',
|
||||
propertyUniformMapping: {
|
||||
center: 'flashlightCenters',
|
||||
color: 'flashlightColors',
|
||||
intensity: 'flashlightIntensities',
|
||||
direction: 'flashlightDirections',
|
||||
},
|
||||
uniformCountMacroName: 'FLASHLIGHT_COUNT',
|
||||
shaderCombinationSteps: [0, 1, 2, 4],
|
||||
empty: new Flashlight(
|
||||
|
|
|
|||
|
|
@ -6,15 +6,13 @@ export class Circle extends Drawable {
|
|||
public static descriptor: DrawableDescriptor = {
|
||||
sdf: {
|
||||
shader: `
|
||||
uniform struct {
|
||||
vec2 center;
|
||||
float radius;
|
||||
}[CIRCLE_COUNT] circles;
|
||||
uniform vec2 circleCenters[CIRCLE_COUNT];
|
||||
uniform vec2 circleRadii[CIRCLE_COUNT];
|
||||
|
||||
void circleMinDistance(inout float minDistance, inout float color) {
|
||||
float myMinDistance = maxMinDistance;
|
||||
for (int i = 0; i < CIRCLE_COUNT; i++) {
|
||||
float dist = distance(circles[i].center, position) - circles[i].radius;
|
||||
float dist = distance(circleCenters[i], position) - circleRadii[i];
|
||||
myMinDistance = min(myMinDistance, dist);
|
||||
}
|
||||
minDistance = min(minDistance, myMinDistance);
|
||||
|
|
@ -26,9 +24,12 @@ export class Circle extends Drawable {
|
|||
`,
|
||||
distanceFunctionName: 'circleMinDistance',
|
||||
},
|
||||
uniformName: 'circles',
|
||||
propertyUniformMapping: {
|
||||
center: 'circleCenters',
|
||||
radius: 'circleRadii',
|
||||
},
|
||||
uniformCountMacroName: 'CIRCLE_COUNT',
|
||||
shaderCombinationSteps: [0, 1, 2, 3, 16, 32],
|
||||
shaderCombinationSteps: [0, 1, 2, 3, 8, 16],
|
||||
empty: new Circle(vec2.fromValues(0, 0), 0),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,44 +8,46 @@ export class InvertedTunnel extends Drawable {
|
|||
public static descriptor: DrawableDescriptor = {
|
||||
sdf: {
|
||||
shader: `
|
||||
uniform struct InvertedTunnel {
|
||||
vec2 from;
|
||||
vec2 toFromDelta;
|
||||
float fromRadius;
|
||||
float toRadius;
|
||||
}[INVERTED_TUNNEL_COUNT] invertedTunnels;
|
||||
uniform vec2 froms[INVERTED_TUNNEL_COUNT];
|
||||
uniform vec2 toFromDeltas[INVERTED_TUNNEL_COUNT];
|
||||
uniform float fromRadii[INVERTED_TUNNEL_COUNT];
|
||||
uniform float toRadii[INVERTED_TUNNEL_COUNT];
|
||||
|
||||
void invertedTunnelMinDistance(inout float minDistance, inout float color) {
|
||||
float myMinDistance = -minDistance;
|
||||
for (int i = 0; i < INVERTED_TUNNEL_COUNT; i++) {
|
||||
InvertedTunnel tunnel = invertedTunnels[i];
|
||||
vec2 targetFromDelta = position - tunnel.from;
|
||||
|
||||
float h = clamp(
|
||||
dot(targetFromDelta, tunnel.toFromDelta)
|
||||
/ dot(tunnel.toFromDelta, tunnel.toFromDelta),
|
||||
0.0, 1.0
|
||||
);
|
||||
|
||||
float currentDistance = -mix(
|
||||
tunnel.fromRadius, tunnel.toRadius, h
|
||||
) + distance(
|
||||
targetFromDelta, tunnel.toFromDelta * h
|
||||
);
|
||||
|
||||
myMinDistance = min(myMinDistance, currentDistance);
|
||||
}
|
||||
|
||||
color = mix(0.0, color, step(
|
||||
distanceNdcPixelSize + SURFACE_OFFSET,
|
||||
-myMinDistance
|
||||
));
|
||||
minDistance = -myMinDistance;
|
||||
void invertedTunnelMinDistance(inout float minDistance, inout float color) {
|
||||
float myMinDistance = -minDistance;
|
||||
for (int i = 0; i < INVERTED_TUNNEL_COUNT; i++) {
|
||||
vec2 targetFromDelta = position - froms[i];
|
||||
|
||||
float h = clamp(
|
||||
dot(targetFromDelta, toFromDeltas[i])
|
||||
/ dot(toFromDeltas[i], toFromDeltas[i]),
|
||||
0.0, 1.0
|
||||
);
|
||||
|
||||
float currentDistance = -mix(
|
||||
fromRadii[i], toRadii[i], h
|
||||
) + distance(
|
||||
targetFromDelta, toFromDeltas[i] * h
|
||||
);
|
||||
|
||||
myMinDistance = min(myMinDistance, currentDistance);
|
||||
}
|
||||
`,
|
||||
|
||||
color = mix(0.0, color, step(
|
||||
distanceNdcPixelSize + SURFACE_OFFSET,
|
||||
-myMinDistance
|
||||
));
|
||||
minDistance = -myMinDistance;
|
||||
}
|
||||
`,
|
||||
distanceFunctionName: 'invertedTunnelMinDistance',
|
||||
},
|
||||
uniformName: 'invertedTunnels',
|
||||
propertyUniformMapping: {
|
||||
from: 'froms',
|
||||
toFromDelta: 'toFromDeltas',
|
||||
fromRadius: 'fromRadii',
|
||||
toRadius: 'toRadii',
|
||||
},
|
||||
uniformCountMacroName: 'INVERTED_TUNNEL_COUNT',
|
||||
shaderCombinationSteps: [0, 1, 4, 16, 32],
|
||||
empty: new InvertedTunnel(vec2.fromValues(0, 0), vec2.fromValues(0, 0), 0, 0),
|
||||
|
|
|
|||
|
|
@ -8,44 +8,46 @@ export class Tunnel extends Drawable {
|
|||
public static descriptor: DrawableDescriptor = {
|
||||
sdf: {
|
||||
shader: `
|
||||
uniform struct Tunnel {
|
||||
vec2 from;
|
||||
vec2 toFromDelta;
|
||||
float fromRadius;
|
||||
float toRadius;
|
||||
}[TUNNEL_COUNT] tunnels;
|
||||
uniform vec2 froms[TUNNEL_COUNT];
|
||||
uniform vec2 toFromDeltas[TUNNEL_COUNT];
|
||||
uniform float fromRadii[TUNNEL_COUNT];
|
||||
uniform float toRadii[TUNNEL_COUNT];
|
||||
|
||||
void tunnelMinDistance(inout float minDistance, inout float color) {
|
||||
float myMinDistance = minDistance;
|
||||
for (int i = 0; i < TUNNEL_COUNT; i++) {
|
||||
Tunnel tunnel = tunnels[i];
|
||||
vec2 targetFromDelta = position - tunnel.from;
|
||||
|
||||
float h = clamp(
|
||||
dot(targetFromDelta, tunnel.toFromDelta)
|
||||
/ dot(tunnel.toFromDelta, tunnel.toFromDelta),
|
||||
0.0, 1.0
|
||||
);
|
||||
|
||||
float currentDistance = -mix(
|
||||
tunnel.fromRadius, tunnel.toRadius, h
|
||||
) + distance(
|
||||
targetFromDelta, tunnel.toFromDelta * h
|
||||
);
|
||||
void tunnelMinDistance(inout float minDistance, inout float color) {
|
||||
float myMinDistance = minDistance;
|
||||
for (int i = 0; i < TUNNEL_COUNT; i++) {
|
||||
vec2 targetFromDelta = position - froms[i];
|
||||
|
||||
float h = clamp(
|
||||
dot(targetFromDelta, toFromDeltas[i])
|
||||
/ dot(toFromDeltas[i], toFromDeltas[i]),
|
||||
0.0, 1.0
|
||||
);
|
||||
|
||||
float currentDistance = -mix(
|
||||
fromRadii[i], toRadii[i], h
|
||||
) + distance(
|
||||
targetFromDelta, toFromDeltas[i] * h
|
||||
);
|
||||
|
||||
myMinDistance = min(myMinDistance, currentDistance);
|
||||
}
|
||||
|
||||
color = mix(2.0, color, step(
|
||||
distanceNdcPixelSize + SURFACE_OFFSET,
|
||||
myMinDistance
|
||||
));
|
||||
minDistance = min(minDistance, myMinDistance);
|
||||
myMinDistance = min(myMinDistance, currentDistance);
|
||||
}
|
||||
`,
|
||||
|
||||
color = mix(2.0, color, step(
|
||||
distanceNdcPixelSize + SURFACE_OFFSET,
|
||||
myMinDistance
|
||||
));
|
||||
minDistance = min(minDistance, myMinDistance);
|
||||
}
|
||||
`,
|
||||
distanceFunctionName: 'tunnelMinDistance',
|
||||
},
|
||||
uniformName: 'tunnels',
|
||||
propertyUniformMapping: {
|
||||
from: 'froms',
|
||||
toFromDelta: 'toFromDeltas',
|
||||
fromRadius: 'fromRadii',
|
||||
toRadius: 'toRadii',
|
||||
},
|
||||
uniformCountMacroName: 'TUNNEL_COUNT',
|
||||
shaderCombinationSteps: [0, 1, 4, 16, 32],
|
||||
empty: new Tunnel(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue