Add glsl loader
This commit is contained in:
parent
ac66c91000
commit
ef315b7089
15 changed files with 150 additions and 150 deletions
|
|
@ -1,12 +1,9 @@
|
||||||
FROM python:3.8-alpine as build-error-pages
|
FROM error-pages as build-error-pages
|
||||||
|
|
||||||
WORKDIR /home/python
|
RUN python build.py 403 404 50x
|
||||||
COPY error-pages .
|
|
||||||
RUN python build.py
|
|
||||||
|
|
||||||
|
|
||||||
FROM node:latest as build-webpage
|
FROM node:latest as build-webpage
|
||||||
|
|
||||||
WORKDIR /home/node
|
WORKDIR /home/node
|
||||||
|
|
||||||
COPY src src
|
COPY src src
|
||||||
|
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
from typing import NamedTuple, Dict, List, Type
|
|
||||||
from os import makedirs, path
|
|
||||||
|
|
||||||
|
|
||||||
template_path = 'template.html'
|
|
||||||
result_path = 'built'
|
|
||||||
|
|
||||||
class Substitutions(NamedTuple):
|
|
||||||
title: str
|
|
||||||
description: str
|
|
||||||
|
|
||||||
error_messages: Dict[str, Substitutions] = {
|
|
||||||
'403': Substitutions(
|
|
||||||
title='403 - Forbidden',
|
|
||||||
description='You are not allowed to view this resource.'
|
|
||||||
),
|
|
||||||
'404': Substitutions(
|
|
||||||
title='404 - Not found',
|
|
||||||
description='The requested resource cannot be found.'
|
|
||||||
),
|
|
||||||
'50x': Substitutions(
|
|
||||||
title='50x - Server error',
|
|
||||||
description='It\'s my fault.'
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def substitute(source: str, substitutions: Substitutions) -> str:
|
|
||||||
for i, property_name in enumerate(Substitutions._fields):
|
|
||||||
source = source.replace(f'{{{property_name}}}', str(substitutions[i]))
|
|
||||||
return source
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
with open(template_path) as f:
|
|
||||||
template = f.read()
|
|
||||||
|
|
||||||
makedirs(result_path, mode=0o440, exist_ok=True)
|
|
||||||
|
|
||||||
for name, substitutions in error_messages.items():
|
|
||||||
with open(path.join(result_path, f'{name}.html'), 'w') as f:
|
|
||||||
html = substitute(template, substitutions)
|
|
||||||
f.write(html)
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<title>{title}</title>
|
|
||||||
<meta name="theme-color" content="#b7455e" />
|
|
||||||
<meta name="viewport" content="initial-scale=1.0" />
|
|
||||||
|
|
||||||
<style>
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
background-color: #b7455e;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-family: 'Roboto', 'Helvetica Neue', sans-serif;
|
|
||||||
font-weight: 100;
|
|
||||||
font-size: 4rem;
|
|
||||||
color: white;
|
|
||||||
text-align: center;
|
|
||||||
padding: 0.5rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>{description}</h1>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -38,7 +38,7 @@ http {
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
location ~* \.(jpg|jpeg|png|ico)$ {
|
location ~* \.(jpg|jpeg|png|ico)$ {
|
||||||
expires 30d;
|
expires 30d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@
|
||||||
"uuid": "^8.2.0",
|
"uuid": "^8.2.0",
|
||||||
"webpack": "^4.43.0",
|
"webpack": "^4.43.0",
|
||||||
"webpack-cli": "^3.3.11",
|
"webpack-cli": "^3.3.11",
|
||||||
"webpack-dev-server": "^3.10.3"
|
"webpack-dev-server": "^3.10.3",
|
||||||
|
"webpack-glsl-minify": "^1.4.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,6 @@ export interface Drawer {
|
||||||
startFrame();
|
startFrame();
|
||||||
finishFrame();
|
finishFrame();
|
||||||
setCameraPosition(position: Vec2);
|
setCameraPosition(position: Vec2);
|
||||||
setInViewWidth(size: number): Vec2;
|
setInViewArea(size: number): Vec2;
|
||||||
drawInfoText(text: string);
|
drawInfoText(text: string);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { Drawer } from './drawer';
|
||||||
import { Vec2 } from '../math/vec2';
|
import { Vec2 } from '../math/vec2';
|
||||||
import { createProgram } from './graphics-library/create-program';
|
import { createProgram } from './graphics-library/create-program';
|
||||||
import { prepareScreenQuad } from './graphics-library/prepare-screen-quad';
|
import { prepareScreenQuad } from './graphics-library/prepare-screen-quad';
|
||||||
|
import { Mat3 } from '../math/mat3';
|
||||||
|
|
||||||
export class WebGl2Renderer implements Drawer {
|
export class WebGl2Renderer implements Drawer {
|
||||||
private gl: WebGL2RenderingContext;
|
private gl: WebGL2RenderingContext;
|
||||||
|
|
@ -56,29 +57,20 @@ export class WebGl2Renderer implements Drawer {
|
||||||
}
|
}
|
||||||
|
|
||||||
finishFrame() {
|
finishFrame() {
|
||||||
const resolutionUniformLocation = this.gl.getUniformLocation(
|
const resolution = new Vec2(this.canvas.width, this.canvas.height);
|
||||||
this.program,
|
|
||||||
'resolution'
|
const transform = Mat3.translateMatrix(new Vec2(0.5, 0.5))
|
||||||
);
|
.times(Mat3.scaleMatrix(this.viewBoxSize.divide(resolution)))
|
||||||
this.gl.uniform2f(
|
.times(Mat3.translateMatrix(this.cameraPosition));
|
||||||
resolutionUniformLocation,
|
|
||||||
this.canvas.width,
|
|
||||||
this.canvas.height
|
|
||||||
);
|
|
||||||
|
|
||||||
const viewBoxSizeUniformLocation = this.gl.getUniformLocation(
|
const viewBoxSizeUniformLocation = this.gl.getUniformLocation(
|
||||||
this.program,
|
this.program,
|
||||||
'viewBoxSize'
|
'transform'
|
||||||
);
|
);
|
||||||
this.gl.uniform2f(viewBoxSizeUniformLocation, ...this.viewBoxSize.list);
|
this.gl.uniformMatrix3fv(
|
||||||
|
viewBoxSizeUniformLocation,
|
||||||
const cameraPositionUniformLocation = this.gl.getUniformLocation(
|
false,
|
||||||
this.program,
|
new Float32Array(transform.transposedFlat)
|
||||||
'cameraPosition'
|
|
||||||
);
|
|
||||||
this.gl.uniform2f(
|
|
||||||
cameraPositionUniformLocation,
|
|
||||||
...this.cameraPosition.list
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
|
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
@ -88,11 +80,14 @@ export class WebGl2Renderer implements Drawer {
|
||||||
this.cameraPosition = position;
|
this.cameraPosition = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
setInViewWidth(size: number): Vec2 {
|
setInViewArea(size: number): Vec2 {
|
||||||
const canvasAspectRatio =
|
const canvasAspectRatio =
|
||||||
this.canvas.clientHeight / this.canvas.clientWidth;
|
this.canvas.clientWidth / this.canvas.clientHeight;
|
||||||
|
|
||||||
this.viewBoxSize = new Vec2(size, size * canvasAspectRatio);
|
this.viewBoxSize = new Vec2(
|
||||||
|
Math.sqrt(size * canvasAspectRatio),
|
||||||
|
Math.sqrt(size / canvasAspectRatio)
|
||||||
|
);
|
||||||
return this.viewBoxSize;
|
return this.viewBoxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,17 @@ import { TouchListener } from './input/touch-listener';
|
||||||
import { CommandBroadcaster } from './commands/command-broadcaster';
|
import { CommandBroadcaster } from './commands/command-broadcaster';
|
||||||
import { ObjectContainer } from './objects/object-container';
|
import { ObjectContainer } from './objects/object-container';
|
||||||
import { DrawCommand } from './commands/types/draw';
|
import { DrawCommand } from './commands/types/draw';
|
||||||
import passthroughVertexShader from '../shaders/passthrough.vert';
|
|
||||||
import distanceFragmentShader from '../shaders/dist.frag';
|
|
||||||
import { StepCommand } from './commands/types/step';
|
import { StepCommand } from './commands/types/step';
|
||||||
import { Character } from './objects/types/character';
|
import { Character } from './objects/types/character';
|
||||||
import { InfoText } from './objects/types/info-text';
|
import { InfoText } from './objects/types/info-text';
|
||||||
import { timeIt } from './helper/timing';
|
import { timeIt } from './helper/timing';
|
||||||
|
|
||||||
|
import { GlslShader, GlslVariable, GlslVariableMap } from 'webpack-glsl-minify';
|
||||||
|
|
||||||
|
let passthroughVertexShader = require('../shaders/passthrough-vs.glsl') as GlslShader;
|
||||||
|
let distanceFragmentShader = require('../shaders/cave-fs.glsl') as GlslShader;
|
||||||
|
|
||||||
export class Game {
|
export class Game {
|
||||||
private previousTime: DOMHighResTimeStamp = 0;
|
private previousTime: DOMHighResTimeStamp = 0;
|
||||||
private objects: ObjectContainer = new ObjectContainer();
|
private objects: ObjectContainer = new ObjectContainer();
|
||||||
|
|
@ -31,9 +35,11 @@ export class Game {
|
||||||
[this.objects]
|
[this.objects]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
console.log(distanceFragmentShader);
|
||||||
|
|
||||||
this.renderer = new WebGl2Renderer(canvas, overlay, [
|
this.renderer = new WebGl2Renderer(canvas, overlay, [
|
||||||
passthroughVertexShader,
|
passthroughVertexShader.sourceCode,
|
||||||
distanceFragmentShader,
|
distanceFragmentShader.sourceCode,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.initializeScene();
|
this.initializeScene();
|
||||||
|
|
|
||||||
78
frontend/src/scripts/math/mat3.ts
Normal file
78
frontend/src/scripts/math/mat3.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
// https://github.com/Azleur/mat3/blob/master/src/index.ts
|
||||||
|
|
||||||
|
import { Vec2 } from './vec2';
|
||||||
|
|
||||||
|
export class Mat3 {
|
||||||
|
constructor(private readonly values: Array<Array<number>>) {}
|
||||||
|
|
||||||
|
public static get Zero() {
|
||||||
|
return new Mat3([
|
||||||
|
[0, 0, 0],
|
||||||
|
[0, 0, 0],
|
||||||
|
[0, 0, 0],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static get Id() {
|
||||||
|
return new Mat3([
|
||||||
|
[1, 0, 0],
|
||||||
|
[0, 1, 0],
|
||||||
|
[0, 0, 1],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static get Ones() {
|
||||||
|
return new Mat3([
|
||||||
|
[1, 1, 1],
|
||||||
|
[1, 1, 1],
|
||||||
|
[1, 1, 1],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static translateMatrix(by: Vec2): Mat3 {
|
||||||
|
return new Mat3([
|
||||||
|
[1, 0, 0],
|
||||||
|
[0, 1, 0],
|
||||||
|
[by.x, by.y, 1],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static scaleMatrix(by: Vec2): Mat3 {
|
||||||
|
return new Mat3([
|
||||||
|
[by.x, 0, 0],
|
||||||
|
[0, by.y, 0],
|
||||||
|
[0, 0, 1],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get transposed(): Mat3 {
|
||||||
|
const values: number[][] = [[], [], []];
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
for (let j = 0; j < 3; j++) {
|
||||||
|
values[i][j] = this.values[j][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Mat3(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public times(other: Mat3): Mat3 {
|
||||||
|
const values: number[][] = Mat3.Zero.values;
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
for (let j = 0; j < 3; j++) {
|
||||||
|
for (let k = 0; k < 3; k++) {
|
||||||
|
values[i][j] += this.values[i][k] * other.values[k][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Mat3(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get transposedFlat(): Array<number> {
|
||||||
|
const transposed = this.transposed;
|
||||||
|
return [
|
||||||
|
...transposed.values[0],
|
||||||
|
...transposed.values[1],
|
||||||
|
...transposed.values[2],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,10 +13,6 @@ export class Vec2 extends Typed {
|
||||||
return new Vec2(this.x * scalar, this.y * scalar);
|
return new Vec2(this.x * scalar, this.y * scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public times(other: Vec2): Vec2 {
|
|
||||||
return new Vec2(this.x * other.x, this.y * other.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public add(other: Vec2): Vec2 {
|
public add(other: Vec2): Vec2 {
|
||||||
return new Vec2(this.x + other.x, this.y + other.y);
|
return new Vec2(this.x + other.x, this.y + other.y);
|
||||||
}
|
}
|
||||||
|
|
@ -25,6 +21,14 @@ export class Vec2 extends Typed {
|
||||||
return new Vec2(this.x - other.x, this.y - other.y);
|
return new Vec2(this.x - other.x, this.y - other.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public times(other: Vec2): Vec2 {
|
||||||
|
return new Vec2(this.x * other.x, this.y * other.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public divide(other: Vec2): Vec2 {
|
||||||
|
return new Vec2(this.x / other.x, this.y / other.y);
|
||||||
|
}
|
||||||
|
|
||||||
public get length(): number {
|
public get length(): number {
|
||||||
return Math.sqrt(this.x * this.x + this.y * this.y);
|
return Math.sqrt(this.x * this.x + this.y * this.y);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ import { DrawCommand } from '../../commands/types/draw';
|
||||||
import { MoveToCommand } from '../../commands/types/move-to';
|
import { MoveToCommand } from '../../commands/types/move-to';
|
||||||
|
|
||||||
export class Camera extends GameObject {
|
export class Camera extends GameObject {
|
||||||
private inViewWidth = 1500;
|
private inViewArea = 1920 * 1080;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
|
@ -13,7 +14,7 @@ export class Camera extends GameObject {
|
||||||
|
|
||||||
private draw(c: DrawCommand) {
|
private draw(c: DrawCommand) {
|
||||||
c.drawer.setCameraPosition(this.position);
|
c.drawer.setCameraPosition(this.position);
|
||||||
this._boundingBoxSize = c.drawer.setInViewWidth(this.inViewWidth);
|
this._boundingBoxSize = c.drawer.setInViewArea(this.inViewArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
private moveTo(c: MoveToCommand) {
|
private moveTo(c: MoveToCommand) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ precision mediump float;
|
||||||
|
|
||||||
const float smoothing = 10.0;
|
const float smoothing = 10.0;
|
||||||
const float inf = 1000000.0;
|
const float inf = 1000000.0;
|
||||||
const float pi = atan(1.0) * 4.0;
|
const float pi = 3.141592654;
|
||||||
|
|
||||||
float interpolate(float from, float to, float quotient) {
|
float interpolate(float from, float to, float quotient) {
|
||||||
float steppedQ = sin(quotient * pi - pi * 0.5) * 0.5 + 0.5;
|
float steppedQ = sin(quotient * pi - pi * 0.5) * 0.5 + 0.5;
|
||||||
|
|
@ -16,14 +16,14 @@ vec2 rotate90deg(in vec2 vector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Line {
|
struct Line {
|
||||||
vec2 a;
|
vec2 from;
|
||||||
vec2 b;
|
vec2 to;
|
||||||
vec2 normal;
|
vec2 normal;
|
||||||
bool isLineEnd;
|
bool isLineEnd;
|
||||||
}[16] lines;
|
}[16] lines;
|
||||||
|
|
||||||
float lineDistance(in vec2 position, in Line line, out float h) {
|
float lineDistance(in vec2 position, in Line line, out float h) {
|
||||||
vec2 pa = position - line.a, ba = line.b - line.a;
|
vec2 pa = position - line.from, ba = line.to - line.from;
|
||||||
h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
|
h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
|
||||||
vec2 delta = pa - ba*h;
|
vec2 delta = pa - ba*h;
|
||||||
// sign can return 0, double sign prevents this
|
// sign can return 0, double sign prevents this
|
||||||
|
|
@ -32,7 +32,7 @@ float lineDistance(in vec2 position, in Line line, out float h) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Line endDummyLineFromLine(Line line) {
|
Line endDummyLineFromLine(Line line) {
|
||||||
return Line(line.b, line.b + rotate90deg(line.normal), line.normal, false);
|
return Line(line.to, line.to + rotate90deg(line.normal), line.normal, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
float getDistance(in vec2 target) {
|
float getDistance(in vec2 target) {
|
||||||
|
|
@ -55,7 +55,7 @@ float getDistance(in vec2 target) {
|
||||||
|
|
||||||
float h;
|
float h;
|
||||||
float distanceToCurrent = lineDistance(target, current, h);
|
float distanceToCurrent = lineDistance(target, current, h);
|
||||||
float rightJoinAcuteness = dot(next.b - current.a, next.normal - current.normal);
|
float rightJoinAcuteness = dot(next.to - current.from, next.normal - current.normal);
|
||||||
distanceToCurrent -= interpolate(
|
distanceToCurrent -= interpolate(
|
||||||
sign(leftJoinAcuteness) * smoothing,
|
sign(leftJoinAcuteness) * smoothing,
|
||||||
sign(rightJoinAcuteness) * smoothing, h
|
sign(rightJoinAcuteness) * smoothing, h
|
||||||
|
|
@ -64,8 +64,8 @@ float getDistance(in vec2 target) {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!(
|
!(
|
||||||
dot(target - current.a, splitterLineNormalStart * -sign(dot(current.b - current.a, splitterLineNormalStart))) > 0.0
|
dot(target - current.from, splitterLineNormalStart * -sign(dot(current.to - current.from, splitterLineNormalStart))) > 0.0
|
||||||
|| dot(target - current.b, splitterLineNormalEnd * sign(dot(current.a - current.b, splitterLineNormalEnd))) <= 0.0
|
|| dot(target - current.to, splitterLineNormalEnd * sign(dot(current.from - current.to, splitterLineNormalEnd))) <= 0.0
|
||||||
) && abs(distanceToCurrent) < abs(minDistance)
|
) && abs(distanceToCurrent) < abs(minDistance)
|
||||||
) {
|
) {
|
||||||
minDistance = distanceToCurrent;
|
minDistance = distanceToCurrent;
|
||||||
|
|
@ -95,24 +95,21 @@ void createWorld() {
|
||||||
lines[15] = Line(vec2(1150, 420.0), vec2(10200, 650.0), vec2(-1.0), true);
|
lines[15] = Line(vec2(1150, 420.0), vec2(10200, 650.0), vec2(-1.0), true);
|
||||||
|
|
||||||
for (int i = 0; i < lines.length(); i++) {
|
for (int i = 0; i < lines.length(); i++) {
|
||||||
vec2 tangent = lines[i].b - lines[i].a;
|
vec2 tangent = lines[i].to - lines[i].from;
|
||||||
lines[i].normal = normalize(
|
lines[i].normal = normalize(
|
||||||
vec2(-lines[i].normal.x * tangent.y, lines[i].normal.x * tangent.x)
|
vec2(-lines[i].normal.x * tangent.y, lines[i].normal.x * tangent.x)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uniform vec2 cameraPosition;
|
uniform mat3 transform;
|
||||||
uniform vec2 viewBoxSize;
|
|
||||||
uniform vec2 resolution;
|
|
||||||
|
|
||||||
out vec4 fragmentColor;
|
out vec4 fragmentColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
createWorld();
|
createWorld();
|
||||||
|
|
||||||
vec2 pixelPosition = gl_FragCoord.xy + vec2(0.5);
|
vec3 projectiveXY = vec3(gl_FragCoord.xy, 1.0);
|
||||||
vec2 position = pixelPosition / resolution * viewBoxSize + cameraPosition;
|
vec2 position = (projectiveXY * transform).xy;
|
||||||
//fragmentColor = getDistance(position) > 0.0 ? vec4(0.0, 0.0, 0.0, 0.0) : vec4(0.0, 0.0, 0.0, 1.0);
|
//fragmentColor = getDistance(position) > 0.0 ? vec4(0.0, 0.0, 0.0, 0.0) : vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
fragmentColor = vec4(vec3(1.0) * clamp(0.0, 1.0, getDistance(position)), 1.0);
|
fragmentColor = vec4(vec3(1.0) * clamp(0.0, 1.0, getDistance(position)), 1.0);
|
||||||
}
|
}
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"downlevelIteration": true,
|
"downlevelIteration": true,
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"experimentalDecorators": true
|
"experimentalDecorators": true,
|
||||||
|
"moduleResolution": "Node"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ const TerserJSPlugin = require('terser-webpack-plugin');
|
||||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
|
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
|
||||||
const Sharp = require('responsive-loader/sharp');
|
|
||||||
const Sass = require('sass');
|
const Sass = require('sass');
|
||||||
|
|
||||||
const isProduction = process.env.NODE_ENV === 'production';
|
const isProduction = process.env.NODE_ENV === 'production';
|
||||||
|
const isDevelopment = !isProduction;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
watchOptions: {
|
watchOptions: {
|
||||||
|
|
@ -70,13 +70,18 @@ module.exports = {
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.(jpe?g|png)$/i,
|
test: /\.(glsl)$/,
|
||||||
loader: 'responsive-loader',
|
use: {
|
||||||
options: {
|
loader: 'webpack-glsl-minify',
|
||||||
adapter: Sharp,
|
options: {
|
||||||
outputPath: 'static/',
|
output: 'object',
|
||||||
sizes: [200, 400, 800, 1200, 2000],
|
esModule: false,
|
||||||
placeholder: false,
|
stripVersion: false,
|
||||||
|
preserveDefines: false,
|
||||||
|
preserveUniforms: true,
|
||||||
|
preserveVariables: true,
|
||||||
|
disableMangle: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -87,12 +92,6 @@ module.exports = {
|
||||||
noquotes: true,
|
noquotes: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
test: /\.(frag|vert)$/i,
|
|
||||||
use: {
|
|
||||||
loader: 'raw-loader',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
test: /\.ico$/i,
|
test: /\.ico$/i,
|
||||||
use: {
|
use: {
|
||||||
|
|
@ -145,7 +144,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.ts', '.js'],
|
extensions: ['.ts', '.js', '.glsl'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: '[name].[contenthash].js',
|
filename: '[name].[contenthash].js',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue