Working version
This commit is contained in:
parent
77bde04db3
commit
b2c2cfcb41
63 changed files with 203 additions and 8301 deletions
8
src/drawables/drawable-descriptor.ts
Normal file
8
src/drawables/drawable-descriptor.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { Drawable } from './drawable';
|
||||
|
||||
export interface DrawableDescriptor {
|
||||
uniformName: string;
|
||||
countMacroName: string;
|
||||
shaderCombinationSteps: Array<number>;
|
||||
readonly empty: Drawable;
|
||||
}
|
||||
15
src/drawables/drawable.ts
Normal file
15
src/drawables/drawable.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { mat2d, vec2 } from 'gl-matrix';
|
||||
import { DrawableDescriptor } from './drawable-descriptor';
|
||||
|
||||
export abstract class Drawable {
|
||||
static get descriptor(): DrawableDescriptor {
|
||||
throw new Error('This getter should be overriden');
|
||||
}
|
||||
|
||||
public abstract distance(target: vec2): number;
|
||||
public abstract serializeToUniforms(
|
||||
uniforms: any,
|
||||
scale: number,
|
||||
transform: mat2d
|
||||
): void;
|
||||
}
|
||||
|
|
@ -1,22 +1,26 @@
|
|||
import { mat2d, vec2, vec3 } from 'gl-matrix';
|
||||
import { settings } from '../../settings';
|
||||
import { IDrawableDescriptor } from '../i-drawable-descriptor';
|
||||
import { ILight } from './i-light';
|
||||
import { settings } from '../../graphics/settings';
|
||||
import { Drawable } from '../drawable';
|
||||
import { DrawableDescriptor } from '../drawable-descriptor';
|
||||
|
||||
export class CircleLight implements ILight {
|
||||
public static descriptor: IDrawableDescriptor = {
|
||||
uniformName: 'circleLights',
|
||||
countMacroName: 'circleLightCount',
|
||||
shaderCombinationSteps: settings.shaderCombinations.circleLightSteps,
|
||||
empty: new CircleLight(vec2.fromValues(0, 0), 0, vec3.fromValues(0, 0, 0), 0),
|
||||
};
|
||||
export class CircleLight extends Drawable {
|
||||
public static get descriptor(): DrawableDescriptor {
|
||||
return {
|
||||
uniformName: 'circleLights',
|
||||
countMacroName: 'circleLightCount',
|
||||
shaderCombinationSteps: settings.shaderCombinations.circleLightSteps,
|
||||
empty: new CircleLight(vec2.fromValues(0, 0), 0, vec3.fromValues(0, 0, 0), 0),
|
||||
};
|
||||
}
|
||||
|
||||
constructor(
|
||||
public center: vec2,
|
||||
public lightDrop: number,
|
||||
public color: vec3,
|
||||
public lightness: number
|
||||
) {}
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
public distance(_: vec2): number {
|
||||
return 0;
|
||||
|
|
@ -1,21 +1,23 @@
|
|||
import { mat2d, vec2, vec3 } from 'gl-matrix';
|
||||
import { settings } from '../../settings';
|
||||
import { IDrawableDescriptor } from '../i-drawable-descriptor';
|
||||
import { ILight } from './i-light';
|
||||
import { settings } from '../../graphics/settings';
|
||||
import { Drawable } from '../drawable';
|
||||
import { DrawableDescriptor } from '../drawable-descriptor';
|
||||
|
||||
export class Flashlight implements ILight {
|
||||
public static descriptor: IDrawableDescriptor = {
|
||||
uniformName: 'flashlights',
|
||||
countMacroName: 'flashlightCount',
|
||||
shaderCombinationSteps: settings.shaderCombinations.flashlightSteps,
|
||||
empty: new Flashlight(
|
||||
vec2.fromValues(0, 0),
|
||||
vec2.fromValues(0, 0),
|
||||
0,
|
||||
vec3.fromValues(0, 0, 0),
|
||||
0
|
||||
),
|
||||
};
|
||||
export class Flashlight extends Drawable {
|
||||
public static get descriptor(): DrawableDescriptor {
|
||||
return {
|
||||
uniformName: 'flashlights',
|
||||
countMacroName: 'flashlightCount',
|
||||
shaderCombinationSteps: settings.shaderCombinations.flashlightSteps,
|
||||
empty: new Flashlight(
|
||||
vec2.fromValues(0, 0),
|
||||
vec2.fromValues(0, 0),
|
||||
0,
|
||||
vec3.fromValues(0, 0, 0),
|
||||
0
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
public constructor(
|
||||
public center: vec2,
|
||||
|
|
@ -23,7 +25,9 @@ export class Flashlight implements ILight {
|
|||
public lightDrop: number,
|
||||
public color: vec3,
|
||||
public lightness: number
|
||||
) {}
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
public distance(_: vec2): number {
|
||||
return 0;
|
||||
36
src/drawables/shapes/circle.ts
Normal file
36
src/drawables/shapes/circle.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { mat2d, vec2 } from 'gl-matrix';
|
||||
import { settings } from '../../graphics/settings';
|
||||
import { Drawable } from '../drawable';
|
||||
import { DrawableDescriptor } from '../drawable-descriptor';
|
||||
|
||||
export class Circle extends Drawable {
|
||||
public static get descriptor(): DrawableDescriptor {
|
||||
return {
|
||||
uniformName: 'circles',
|
||||
countMacroName: 'circleCount',
|
||||
shaderCombinationSteps: settings.shaderCombinations.circleSteps,
|
||||
empty: new Circle(vec2.fromValues(0, 0), 0),
|
||||
};
|
||||
}
|
||||
|
||||
constructor(public center: vec2, public radius: number) {
|
||||
super();
|
||||
}
|
||||
|
||||
public distance(position: vec2): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public serializeToUniforms(uniforms: any, scale: number, transform: mat2d): void {
|
||||
const { uniformName } = Circle.descriptor;
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(uniforms, uniformName)) {
|
||||
uniforms[uniformName] = [];
|
||||
}
|
||||
|
||||
uniforms[uniformName].push({
|
||||
center: vec2.transformMat2d(vec2.create(), this.center, transform),
|
||||
radius: this.radius * scale,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
import { IDrawable } from './i-drawable';
|
||||
|
||||
export interface IDrawableDescriptor {
|
||||
uniformName: string;
|
||||
countMacroName: string;
|
||||
shaderCombinationSteps: Array<number>;
|
||||
readonly empty: IDrawable;
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
import { vec2, mat2d } from 'gl-matrix';
|
||||
|
||||
export interface IDrawable {
|
||||
distance(target: vec2): number;
|
||||
serializeToUniforms(uniforms: any, scale: number, transform: mat2d): void;
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import { IDrawable } from '../i-drawable';
|
||||
|
||||
export type ILight = IDrawable;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { mat2d, vec2 } from 'gl-matrix';
|
||||
import { DrawableDescriptor } from '../../../drawables/drawable-descriptor';
|
||||
import { getCombinations } from '../../../helper/get-combinations';
|
||||
import { last } from '../../../helper/last';
|
||||
import { IDrawableDescriptor } from '../../drawables/i-drawable-descriptor';
|
||||
import { FragmentShaderOnlyProgram } from './fragment-shader-only-program';
|
||||
import { IProgram } from './i-program';
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ export class UniformArrayAutoScalingProgram implements IProgram {
|
|||
constructor(
|
||||
private gl: WebGL2RenderingContext,
|
||||
shaderSources: [string, string],
|
||||
private descriptors: Array<IDrawableDescriptor>
|
||||
private descriptors: Array<DrawableDescriptor>
|
||||
) {
|
||||
const names = descriptors.map((o) => o.countMacroName);
|
||||
for (const combination of getCombinations(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { IDrawable } from './drawables/i-drawable';
|
||||
import { ILight } from './drawables/lights/i-light';
|
||||
import { Drawable } from '../drawables/drawable';
|
||||
|
||||
export interface IRenderer {
|
||||
initialize(): Promise<void>;
|
||||
|
|
@ -8,9 +7,8 @@ export interface IRenderer {
|
|||
startFrame(deltaTime: DOMHighResTimeStamp): void;
|
||||
finishFrame(): void;
|
||||
|
||||
drawShape(drawable: IDrawable): void;
|
||||
drawLight(light: ILight): void;
|
||||
drawInfoText(text: string): void;
|
||||
drawShape(drawable: Drawable): void;
|
||||
drawLight(light: Drawable): void;
|
||||
|
||||
readonly canvasSize: vec2;
|
||||
setViewArea(topLeft: vec2, size: vec2): void;
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { IDrawable } from '../drawables/i-drawable';
|
||||
import { IDrawableDescriptor } from '../drawables/i-drawable-descriptor';
|
||||
import { Drawable } from '../../drawables/drawable';
|
||||
import { DrawableDescriptor } from '../../drawables/drawable-descriptor';
|
||||
import { FrameBuffer } from '../graphics-library/frame-buffer/frame-buffer';
|
||||
import { UniformArrayAutoScalingProgram } from '../graphics-library/program/uniform-array-autoscaling-program';
|
||||
import { settings } from '../settings';
|
||||
|
||||
export class RenderingPass {
|
||||
private drawables: Array<IDrawable> = [];
|
||||
private drawables: Array<Drawable> = [];
|
||||
private program: UniformArrayAutoScalingProgram;
|
||||
|
||||
constructor(
|
||||
gl: WebGL2RenderingContext,
|
||||
shaderSources: [string, string],
|
||||
drawableDescriptors: Array<IDrawableDescriptor>,
|
||||
drawableDescriptors: Array<DrawableDescriptor>,
|
||||
private frame: FrameBuffer
|
||||
) {
|
||||
this.program = new UniformArrayAutoScalingProgram(
|
||||
|
|
@ -26,7 +26,7 @@ export class RenderingPass {
|
|||
await this.program.initialize();
|
||||
}
|
||||
|
||||
public addDrawable(drawable: IDrawable) {
|
||||
public addDrawable(drawable: Drawable) {
|
||||
this.drawables.push(drawable);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { IDrawable } from '../drawables/i-drawable';
|
||||
import { CircleLight } from '../drawables/lights/circle-light';
|
||||
import { Flashlight } from '../drawables/lights/flashlight';
|
||||
import { ILight } from '../drawables/lights/i-light';
|
||||
import { Drawable } from '../../drawables/drawable';
|
||||
import { CircleLight } from '../../drawables/lights/circle-light';
|
||||
import { Flashlight } from '../../drawables/lights/flashlight';
|
||||
import { Circle } from '../../drawables/shapes/circle';
|
||||
import { DefaultFrameBuffer } from '../graphics-library/frame-buffer/default-frame-buffer';
|
||||
import { IntermediateFrameBuffer } from '../graphics-library/frame-buffer/intermediate-frame-buffer';
|
||||
import { getWebGl2Context } from '../graphics-library/helper/get-webgl2-context';
|
||||
|
|
@ -28,7 +28,7 @@ export class WebGl2Renderer implements IRenderer {
|
|||
|
||||
private initializePromise: Promise<[void, void]>;
|
||||
|
||||
constructor(private canvas: HTMLCanvasElement, private overlay: HTMLElement) {
|
||||
constructor(private canvas: HTMLCanvasElement) {
|
||||
this.gl = getWebGl2Context(canvas);
|
||||
|
||||
this.distanceFieldFrameBuffer = new IntermediateFrameBuffer(this.gl);
|
||||
|
|
@ -37,7 +37,7 @@ export class WebGl2Renderer implements IRenderer {
|
|||
this.distancePass = new RenderingPass(
|
||||
this.gl,
|
||||
[distanceVertexShader, distanceFragmentShader],
|
||||
[],
|
||||
[Circle.descriptor],
|
||||
this.distanceFieldFrameBuffer
|
||||
);
|
||||
|
||||
|
|
@ -74,11 +74,11 @@ export class WebGl2Renderer implements IRenderer {
|
|||
await this.initializePromise;
|
||||
}
|
||||
|
||||
public drawShape(shape: IDrawable) {
|
||||
public drawShape(shape: Drawable) {
|
||||
this.distancePass.addDrawable(shape);
|
||||
}
|
||||
|
||||
public drawLight(light: ILight) {
|
||||
public drawLight(light: Drawable) {
|
||||
this.lightingPass.addDrawable(light);
|
||||
}
|
||||
|
||||
|
|
@ -117,10 +117,4 @@ export class WebGl2Renderer implements IRenderer {
|
|||
public get canvasSize(): vec2 {
|
||||
return vec2.fromValues(this.canvas.clientWidth, this.canvas.clientHeight);
|
||||
}
|
||||
|
||||
public drawInfoText(text: string) {
|
||||
if (this.overlay.innerText != text) {
|
||||
this.overlay.innerText = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,9 +51,8 @@ export const settings = {
|
|||
tileMultiplier: 8,
|
||||
shaderMacros: {},
|
||||
shaderCombinations: {
|
||||
lineSteps: [0, 1, 2, 4, 8, 16, 128],
|
||||
blobSteps: [0, 1, 2, 8],
|
||||
circleLightSteps: [0, 1],
|
||||
circleSteps: [0, 1, 16],
|
||||
flashlightSteps: [0, 1],
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
precision lowp float;
|
||||
|
||||
#define LINE_COUNT {lineCount}
|
||||
#define BLOB_COUNT {blobCount}
|
||||
// #define LINE_COUNT {lineCount}
|
||||
// #define BLOB_COUNT {blobCount}
|
||||
#define CIRCLE_COUNT {circleCount}
|
||||
|
||||
#define SURFACE_OFFSET 0.001
|
||||
|
||||
|
|
@ -20,7 +21,7 @@ float smoothMin(float a, float b)
|
|||
b = pow(b, k);
|
||||
return pow((a * b) / (a + b), 1.0 / k);
|
||||
}
|
||||
|
||||
/*
|
||||
#if LINE_COUNT > 0
|
||||
uniform struct {
|
||||
vec2 from;
|
||||
|
|
@ -53,7 +54,22 @@ float smoothMin(float a, float b)
|
|||
minDistance = -myMinDistance;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
#if CIRCLE_COUNT > 0
|
||||
uniform struct {
|
||||
vec2 center;
|
||||
float radius;
|
||||
}[CIRCLE_COUNT] circles;
|
||||
|
||||
void circleMinDistance(inout float minDistance, inout float color) {
|
||||
for (int i = 0; i < CIRCLE_COUNT; i++) {
|
||||
float dist = distance(circles[i].center, position) - circles[i].radius;
|
||||
minDistance = min(minDistance, dist);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
#if BLOB_COUNT > 0
|
||||
uniform struct {
|
||||
vec2 headCenter;
|
||||
|
|
@ -88,22 +104,26 @@ float smoothMin(float a, float b)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
out vec2 fragmentColor;
|
||||
|
||||
void main() {
|
||||
float minDistance = -maxMinDistance;
|
||||
float color = 0.0;
|
||||
float minDistance = 10.0; //-maxMinDistance;
|
||||
float color = 1.0;
|
||||
|
||||
#if LINE_COUNT > 0
|
||||
/*#if LINE_COUNT > 0
|
||||
lineMinDistance(minDistance, color);
|
||||
#endif
|
||||
|
||||
#if BLOB_COUNT > 0
|
||||
blobMinDistance(minDistance, color);
|
||||
#endif*/
|
||||
|
||||
#if CIRCLE_COUNT > 0
|
||||
circleMinDistance(minDistance, color);
|
||||
#endif
|
||||
|
||||
|
||||
// minDistance / 2.0: NDC to UV scale
|
||||
fragmentColor = vec2((minDistance - SURFACE_OFFSET) / 2.0, color);
|
||||
fragmentColor = vec2(minDistance / 2.0, color);
|
||||
}
|
||||
|
|
|
|||
22
src/main.ts
22
src/main.ts
|
|
@ -1,18 +1,14 @@
|
|||
import { glMatrix } from 'gl-matrix';
|
||||
import { IRenderer } from './graphics/i-renderer';
|
||||
import { WebGl2Renderer } from './graphics/rendering/webgl2-renderer';
|
||||
import { applyArrayPlugins } from './helper/array';
|
||||
import { Random } from './helper/random';
|
||||
|
||||
glMatrix.setMatrixArrayType(Array);
|
||||
applyArrayPlugins();
|
||||
export { Drawable } from './drawables/drawable';
|
||||
export { CircleLight } from './drawables/lights/circle-light';
|
||||
export { Circle } from './drawables/shapes/circle';
|
||||
|
||||
const main = async () => {
|
||||
try {
|
||||
Random.seed = 42;
|
||||
//await new Game().start();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert(e);
|
||||
}
|
||||
export const compile = (canvas: HTMLCanvasElement): IRenderer => {
|
||||
glMatrix.setMatrixArrayType(Array);
|
||||
applyArrayPlugins();
|
||||
return new WebGl2Renderer(canvas);
|
||||
};
|
||||
|
||||
main();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue