Some refactoring

This commit is contained in:
schmelczerandras 2020-09-14 19:18:59 +02:00
parent a51c06ae7b
commit 99f47e2961
45 changed files with 72 additions and 113 deletions

View file

@ -1,48 +0,0 @@
#version 300 es
precision mediump float;
const float inf = 1000000.0;
const float pi = atan(1.0) * 4.0;
float interpolate(float from, float to, float quotient) {
float steppedQ = sin(quotient * pi - pi * 0.5) * 0.5 + 0.5;
return from + (to - from) * clamp(steppedQ, 0.0, 1.0);
}
float noise(float x){
return fract(sin(x) * 43758.5453123);
}
float terrain(float x) {
float result = 0.0;
float frequency = 0.01;
float amplitude = 1.0;
for (int i = 0; i < 8; i++) {
result += sin(2.0 * pi * x * frequency - 2.0 * pi * noise(float(i) * 200.0)) * amplitude;
frequency *= 1.5;
amplitude /= 1.2;
}
return result;
}
vec2 random2(vec2 st){
st = vec2( dot(st,vec2(127.1,311.7)),
dot(st,vec2(269.5,183.3)) );
return -1.0 + 2.0*fract(sin(st)*43758.5453123);
}
float noise(vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
vec2 u = f*f*(3.0-2.0*f);
return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
}

View file

@ -1,8 +1,8 @@
import { CommandBroadcaster } from './commands/command-broadcaster'; import { CommandBroadcaster } from './commands/command-broadcaster';
import { BeforeRenderCommand } from './drawing/commands/before-render'; import { BeforeRenderCommand } from './graphics/commands/before-render';
import { RenderCommand } from './drawing/commands/render'; import { RenderCommand } from './graphics/commands/render';
import { IRenderer } from './drawing/i-renderer'; import { IRenderer } from './graphics/i-renderer';
import { WebGl2Renderer } from './drawing/rendering/webgl2-renderer'; import { WebGl2Renderer } from './graphics/rendering/webgl2-renderer';
import { timeIt } from './helper/timing'; import { timeIt } from './helper/timing';
import { IGame } from './i-game'; import { IGame } from './i-game';
import { KeyboardListener } from './input/keyboard-listener'; import { KeyboardListener } from './input/keyboard-listener';
@ -128,13 +128,12 @@ export class Game implements IGame {
this.previousFpsValues.push(1000 / deltaTime); this.previousFpsValues.push(1000 / deltaTime);
if (this.previousFpsValues.length > 30) { if (this.previousFpsValues.length > 30) {
this.previousFpsValues.sort(); this.previousFpsValues.sort();
const text = `Min: ${this.previousFpsValues[0].toFixed( const min = this.previousFpsValues[0];
2 const median = this.previousFpsValues[
)}\n\tMedian: ${this.previousFpsValues[
Math.floor(this.previousFpsValues.length / 2) Math.floor(this.previousFpsValues.length / 2)
].toFixed(2)}`; ];
InfoText.modifyRecord('FPS', text); InfoText.modifyRecord('FPS', { min, median });
this.previousFpsValues = []; this.previousFpsValues = [];
} }

View file

@ -1,5 +1,5 @@
import { IRenderer } from '../../drawing/i-renderer';
import { Command } from '../../commands/command'; import { Command } from '../../commands/command';
import { IRenderer } from '../../graphics/i-renderer';
export class RenderCommand extends Command { export class RenderCommand extends Command {
public constructor(public readonly renderer?: IRenderer) { public constructor(public readonly renderer?: IRenderer) {

View file

@ -27,7 +27,6 @@ export class DrawableBlob extends Blob implements IDrawable {
), ),
headRadius: this.headRadius * scale, headRadius: this.headRadius * scale,
footRadius: this.footRadius * scale, footRadius: this.footRadius * scale,
k: this.k / scale,
}); });
} }
} }

View file

@ -39,12 +39,13 @@ export class RenderingPass {
0.5 * 0.5 *
vec2.length(vec2.scale(vec2.create(), commonUniforms.worldAreaInView, stepsInUV)); vec2.length(vec2.scale(vec2.create(), commonUniforms.worldAreaInView, stepsInUV));
const radiusInNDC = worldR * commonUniforms.scaleWorldLengthToNDC;
const stepsInNDC = 2 * stepsInUV; const stepsInNDC = 2 * stepsInUV;
for (let x = -1; x < 1; x += stepsInNDC) { for (let x = -1; x < 1; x += stepsInNDC) {
for (let y = -1; y < 1; y += stepsInNDC) { for (let y = -1; y < 1; y += stepsInNDC) {
const uniforms = { ...commonUniforms }; const uniforms = { ...commonUniforms, maxMinDistance: 0.0 };
uniforms.maxMinDistance = 2 * worldR * uniforms.scaleWorldLengthToNDC;
const ndcBottomLeft = vec2.fromValues(x, y); const ndcBottomLeft = vec2.fromValues(x, y);

View file

@ -96,7 +96,8 @@ export class WebGl2Renderer implements IRenderer {
public finishFrame() { public finishFrame() {
const common = { const common = {
distanceUvPixelSize: 2 / this.distanceFieldFrameBuffer.getSize().y, distanceNdcPixelSize: 2 / Math.max(...this.distanceFieldFrameBuffer.getSize()),
shadingNdcPixelSize: 2 / Math.max(...this.distanceFieldFrameBuffer.getSize()),
}; };
this.distancePass.render(this.uniformsProvider.getUniforms(common)); this.distancePass.render(this.uniformsProvider.getUniforms(common));

View file

@ -22,16 +22,11 @@ export const settings = {
softShadowsEnabled: false, softShadowsEnabled: false,
}, },
{ {
distanceRenderScale: 0.5, distanceRenderScale: 0.3,
finalRenderScale: 1.0,
softShadowsEnabled: false,
},
{
distanceRenderScale: 0.5,
finalRenderScale: 1.0, finalRenderScale: 1.0,
softShadowsEnabled: true, softShadowsEnabled: true,
}, },
{ /*{
distanceRenderScale: 1.0, distanceRenderScale: 1.0,
finalRenderScale: 1.5, finalRenderScale: 1.5,
softShadowsEnabled: true, softShadowsEnabled: true,
@ -45,7 +40,7 @@ export const settings = {
distanceRenderScale: 2, distanceRenderScale: 2,
finalRenderScale: 2, finalRenderScale: 2,
softShadowsEnabled: true, softShadowsEnabled: true,
}, },*/
], ],
startingTargetIndex: 2, startingTargetIndex: 2,
scalingOptions: { scalingOptions: {

View file

@ -4,12 +4,23 @@ precision lowp float;
#define LINE_COUNT {lineCount} #define LINE_COUNT {lineCount}
#define BLOB_COUNT {blobCount} #define BLOB_COUNT {blobCount}
#define SURFACE_OFFSET 0.001
uniform float maxMinDistance; uniform float maxMinDistance;
uniform float distanceUvPixelSize; uniform float distanceNdcPixelSize;
in vec2 position; in vec2 position;
float smoothMin(float a, float b)
{
const float k = 2.0;
a = pow(a, k);
b = pow(b, k);
return pow((a * b) / (a + b), 1.0 / k);
}
#if LINE_COUNT > 0 #if LINE_COUNT > 0
uniform struct { uniform struct {
vec2 from; vec2 from;
@ -38,8 +49,7 @@ in vec2 position;
myMinDistance = min(myMinDistance, lineDistance); myMinDistance = min(myMinDistance, lineDistance);
} }
color = mix(0.0, color, step(distanceUvPixelSize, -myMinDistance)); color = mix(0.0, color, step(distanceNdcPixelSize + SURFACE_OFFSET, -myMinDistance));
minDistance = -myMinDistance; minDistance = -myMinDistance;
} }
#endif #endif
@ -60,14 +70,21 @@ in vec2 position;
void blobMinDistance(inout float minDistance, inout float color) { void blobMinDistance(inout float minDistance, inout float color) {
for (int i = 0; i < BLOB_COUNT; i++) { for (int i = 0; i < BLOB_COUNT; i++) {
float res = exp2(-blobs[i].k * circleMinDistance(blobs[i].headCenter, blobs[i].headRadius)); float headDistance = circleMinDistance(blobs[i].headCenter, blobs[i].headRadius);
res += exp2(-blobs[i].k * circleMinDistance(blobs[i].leftFootCenter, blobs[i].footRadius)); float leftFootDistance = circleMinDistance(blobs[i].leftFootCenter, blobs[i].footRadius);
res += exp2(-blobs[i].k * circleMinDistance(blobs[i].rightFootCenter, blobs[i].footRadius)); float rightFootDistance = circleMinDistance(blobs[i].rightFootCenter, blobs[i].footRadius);
res = -log2(res) / blobs[i].k;
color = mix(1.0, color, step(distanceUvPixelSize, res)); float res = min(
smoothMin(headDistance, leftFootDistance),
smoothMin(headDistance, rightFootDistance)
);
res = min(100.0, headDistance);
res = min(res, leftFootDistance);
res = min(res, rightFootDistance);
//color = mix(2.0, color, step(distanceUvPixelSize + SURFACE_OFFSET, res));
minDistance = min(minDistance, res); minDistance = min(minDistance, res);
color = mix(2.0, color, step(distanceNdcPixelSize + SURFACE_OFFSET, res));
} }
} }
#endif #endif
@ -82,12 +99,11 @@ void main() {
lineMinDistance(minDistance, color); lineMinDistance(minDistance, color);
#endif #endif
#if BLOB_COUNT > 10 #if BLOB_COUNT > 0
blobMinDistance(minDistance, color); blobMinDistance(minDistance, color);
#endif #endif
// minDistance / 2.0: NDC to UV scale // minDistance / 2.0: NDC to UV scale
// - 0.005 is for making it more consistent with the physics fragmentColor = vec2((minDistance - SURFACE_OFFSET) / 2.0, color);
fragmentColor = vec2(minDistance / 2.0 - 0.005, color);
} }

View file

@ -12,6 +12,7 @@ precision lowp float;
uniform bool softShadowsEnabled; uniform bool softShadowsEnabled;
uniform vec2 squareToAspectRatioTimes2; uniform vec2 squareToAspectRatioTimes2;
uniform float shadingNdcPixelSize;
uniform sampler2D distanceTexture; uniform sampler2D distanceTexture;
in vec2 position; in vec2 position;
@ -37,11 +38,11 @@ float softShadowTransparency(float startingDistance, float lightCenterDistance,
float rayLength = startingDistance; float rayLength = startingDistance;
float q = 1.0 / SHADOW_HARDNESS; float q = 1.0 / SHADOW_HARDNESS;
for (int j = 0; j < 96; j++) { for (int j = 0; j < 128; j++) {
float minDistance = getDistance(uvCoordinates + direction * rayLength); float minDistance = getDistance(uvCoordinates + direction * rayLength);
q = min(q, minDistance / rayLength); q = min(q, minDistance / rayLength);
rayLength += minDistance / 2.0; rayLength += minDistance / 2.5;
if (rayLength >= lightCenterDistance) { if (rayLength >= lightCenterDistance) {
return q * SHADOW_HARDNESS; return q * SHADOW_HARDNESS;

View file

@ -2,7 +2,7 @@ import { GameObject } from './objects/game-object';
import { BoundingBoxBase } from './shapes/bounding-box-base'; import { BoundingBoxBase } from './shapes/bounding-box-base';
export interface IGame { export interface IGame {
addObject(o: GameObject); addObject(o: GameObject): void;
readonly viewArea: BoundingBoxBase; readonly viewArea: BoundingBoxBase;
findIntersecting(box: BoundingBoxBase): Array<BoundingBoxBase>; findIntersecting(box: BoundingBoxBase): Array<BoundingBoxBase>;
} }

View file

@ -1,5 +1,5 @@
import { vec2 } from 'gl-matrix'; import { vec2 } from 'gl-matrix';
import { BeforeRenderCommand } from '../../drawing/commands/before-render'; import { BeforeRenderCommand } from '../../graphics/commands/before-render';
import { CursorMoveCommand } from '../../input/commands/cursor-move-command'; import { CursorMoveCommand } from '../../input/commands/cursor-move-command';
import { ZoomCommand } from '../../input/commands/zoom'; import { ZoomCommand } from '../../input/commands/zoom';
import { MoveToCommand } from '../../physics/commands/move-to'; import { MoveToCommand } from '../../physics/commands/move-to';
@ -7,7 +7,7 @@ import { BoundingBox } from '../../shapes/bounding-box';
import { GameObject } from '../game-object'; import { GameObject } from '../game-object';
export class Camera extends GameObject { export class Camera extends GameObject {
private inViewAreaSize = 1920 * 1080 * 5; private inViewAreaSize = 1920 * 1080 * 2;
private cursorPosition = vec2.create(); private cursorPosition = vec2.create();
private _viewArea: BoundingBox; private _viewArea: BoundingBox;

View file

@ -1,7 +1,7 @@
import { vec2, vec3 } from 'gl-matrix'; import { vec2, vec3 } from 'gl-matrix';
import { RenderCommand } from '../../drawing/commands/render'; import { RenderCommand } from '../../graphics/commands/render';
import { DrawableBlob } from '../../drawing/drawables/drawable-blob'; import { DrawableBlob } from '../../graphics/drawables/drawable-blob';
import { Flashlight } from '../../drawing/drawables/lights/flashlight'; import { Flashlight } from '../../graphics/drawables/lights/flashlight';
import { IGame } from '../../i-game'; import { IGame } from '../../i-game';
import { KeyDownCommand } from '../../input/commands/key-down'; import { KeyDownCommand } from '../../input/commands/key-down';
import { KeyUpCommand } from '../../input/commands/key-up'; import { KeyUpCommand } from '../../input/commands/key-up';
@ -14,23 +14,19 @@ import { GameObject } from '../game-object';
export class Character extends GameObject { export class Character extends GameObject {
private keysDown: Set<string> = new Set(); private keysDown: Set<string> = new Set();
private light: Flashlight; private light = new Flashlight(
vec2.create(),
vec2.fromValues(-1, 0),
0.7,
vec3.fromValues(1, 0.6, 0.45),
1.5
);
private shape = new DrawableBlob(vec2.create()); private shape = new DrawableBlob(vec2.create());
private static speed = 1.5; private static speed = 1.5;
constructor(private game: IGame) { constructor(private game: IGame) {
super(); super();
this.light = new Flashlight(
vec2.create(),
vec2.fromValues(-1, 0),
0.7,
vec3.fromValues(1, 0.6, 0.45),
1.5
);
//this.light = new CircleLight(vec2.create(), 0.2, vec3.fromValues(1, 0.6, 0.45), 1.5);
this.addCommandExecutor(StepCommand, this.stepHandler.bind(this));
this.addCommandExecutor(RenderCommand, this.draw.bind(this)); this.addCommandExecutor(RenderCommand, this.draw.bind(this));
this.addCommandExecutor(TeleportToCommand, (c) => this.setPosition(c.position)); this.addCommandExecutor(TeleportToCommand, (c) => this.setPosition(c.position));
this.addCommandExecutor(KeyDownCommand, (c) => this.keysDown.add(c.key)); this.addCommandExecutor(KeyDownCommand, (c) => this.keysDown.add(c.key));
@ -116,7 +112,7 @@ export class Character extends GameObject {
private setPosition(value: vec2) { private setPosition(value: vec2) {
this.shape.position = value; this.shape.position = value;
this.light.center = vec2.add(vec2.create(), value, vec2.fromValues(150, 0)); this.light.center = vec2.add(vec2.create(), value, vec2.fromValues(50, -40));
} }
public stepHandler(c: StepCommand) { public stepHandler(c: StepCommand) {

View file

@ -1,4 +1,4 @@
import { RenderCommand } from '../../drawing/commands/render'; import { RenderCommand } from '../../graphics/commands/render';
import { GameObject } from '../game-object'; import { GameObject } from '../game-object';
export class InfoText extends GameObject { export class InfoText extends GameObject {

View file

@ -1,6 +1,6 @@
import { vec2, vec3 } from 'gl-matrix'; import { vec2, vec3 } from 'gl-matrix';
import { RenderCommand } from '../../drawing/commands/render'; import { RenderCommand } from '../../graphics/commands/render';
import { CircleLight } from '../../drawing/drawables/lights/circle-light'; import { CircleLight } from '../../graphics/drawables/lights/circle-light';
import { MoveToCommand } from '../../physics/commands/move-to'; import { MoveToCommand } from '../../physics/commands/move-to';
import { GameObject } from '../game-object'; import { GameObject } from '../game-object';

View file

@ -1,6 +1,6 @@
import { vec2 } from 'gl-matrix'; import { vec2 } from 'gl-matrix';
import { RenderCommand } from '../../drawing/commands/render'; import { RenderCommand } from '../../graphics/commands/render';
import { DrawableTunnel } from '../../drawing/drawables/drawable-tunnel'; import { DrawableTunnel } from '../../graphics/drawables/drawable-tunnel';
import { Physics } from '../../physics/physics'; import { Physics } from '../../physics/physics';
import { GameObject } from '../game-object'; import { GameObject } from '../game-object';

View file

@ -10,8 +10,6 @@ export class Blob implements IShape {
protected readonly headRadius = 40; protected readonly headRadius = 40;
protected readonly footRadius = 15; protected readonly footRadius = 15;
protected readonly k = 1000000;
private readonly headOffset = vec2.fromValues(0, -15); private readonly headOffset = vec2.fromValues(0, -15);
private readonly leftFootOffset = vec2.fromValues(-12, -60); private readonly leftFootOffset = vec2.fromValues(-12, -60);
private readonly rightFootOffset = vec2.fromValues(12, -60); private readonly rightFootOffset = vec2.fromValues(12, -60);

View file

@ -1,7 +1,7 @@
import { vec2 } from 'gl-matrix'; import { vec2 } from 'gl-matrix';
import { IShape } from '../i-shape';
import { BoundingBox } from '../bounding-box';
import { GameObject } from '../../objects/game-object'; import { GameObject } from '../../objects/game-object';
import { BoundingBox } from '../bounding-box';
import { IShape } from '../i-shape';
export class Circle implements IShape { export class Circle implements IShape {
public readonly isInverted = false; public readonly isInverted = false;

View file

@ -3,11 +3,12 @@
"outDir": "./dist/", "outDir": "./dist/",
"sourceMap": true, "sourceMap": true,
"noImplicitAny": false, "noImplicitAny": false,
"module": "es6",
"target": "es5", "target": "es5",
"downlevelIteration": true, "downlevelIteration": true,
"allowJs": true, "allowJs": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"moduleResolution": "Node" "moduleResolution": "Node",
"module": "commonjs",
"lib": ["es2015", "dom"]
} }
} }