Scaffold WebGl
This commit is contained in:
parent
7c68deef24
commit
fb50ade480
19 changed files with 186 additions and 86 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,3 +1 @@
|
||||||
**/node_modules
|
|
||||||
**/dist
|
|
||||||
infrastructure/data/certbot
|
infrastructure/data/certbot
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,9 @@
|
||||||

|

|
||||||
|
|
||||||
A nice looking 2D adventure.
|
A nice looking 2D adventure.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
- npm install
|
||||||
|
- npm run start
|
||||||
|
- npm run build
|
||||||
|
|
|
||||||
3
frontend/.gitignore
vendored
Normal file
3
frontend/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
dist
|
||||||
|
node_modules
|
||||||
|
package-lock.json
|
||||||
6
frontend/.prettierrc
Normal file
6
frontend/.prettierrc
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"singleQuote": true,
|
||||||
|
"endOfLine": "lf"
|
||||||
|
}
|
||||||
29
frontend/custom.d.ts
vendored
Normal file
29
frontend/custom.d.ts
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
declare module '*.frag' {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.vert' {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
declare module '*.png' {
|
||||||
|
import { ResponsiveImage } from 'src/framework/model/misc';
|
||||||
|
const content: ResponsiveImage;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.jpg' {
|
||||||
|
import { ResponsiveImage } from 'src/framework/model/misc';
|
||||||
|
const content: ResponsiveImage;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.jpeg' {
|
||||||
|
import { ResponsiveImage } from 'src/framework/model/misc';
|
||||||
|
const content: ResponsiveImage;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
{
|
{
|
||||||
"name": "decla.red",
|
"name": "decla.red",
|
||||||
"version": "1.0.0",
|
"version": "0.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "webpack-dev-server --mode development",
|
"start": "webpack-dev-server --mode development",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"build": "webpack && find dist -type f -not -name '*.html' | xargs rm"
|
||||||
"build": "webpack"
|
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "András Schmelczer",
|
"author": "András Schmelczer",
|
||||||
"license": "UNLICENSED",
|
|
||||||
"postcss": {
|
"postcss": {
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"autoprefixer": {}
|
"autoprefixer": {}
|
||||||
|
|
@ -20,7 +18,9 @@
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"defaults"
|
"defaults"
|
||||||
],
|
],
|
||||||
"sideEffects": false,
|
"sideEffects": [
|
||||||
|
"*.scss"
|
||||||
|
],
|
||||||
"optimization": {
|
"optimization": {
|
||||||
"usedExports": true
|
"usedExports": true
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<noscript><h1>Javascript is required for this website.</h1></noscript>
|
<noscript><h1>Javascript is required for this website.</h1></noscript>
|
||||||
|
<canvas id="main"></canvas>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,4 @@
|
||||||
function component() {
|
import './styling/main.scss';
|
||||||
const element = document.createElement('div');
|
import { main } from './scripting/main';
|
||||||
|
|
||||||
element.innerHTML = 'Hello world';
|
main();
|
||||||
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.body.appendChild(component());
|
|
||||||
|
|
|
||||||
63
frontend/src/scripting/drawing/renderer.ts
Normal file
63
frontend/src/scripting/drawing/renderer.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
import * as twgl from 'twgl.js';
|
||||||
|
|
||||||
|
export class Renderer {
|
||||||
|
private gl: WebGL2RenderingContext;
|
||||||
|
private programInfo: any;
|
||||||
|
private bufferInfo: any;
|
||||||
|
private vao: any;
|
||||||
|
|
||||||
|
constructor(private canvas: HTMLCanvasElement, shaderSources: Array<string>) {
|
||||||
|
twgl.setDefaults({ attribPrefix: 'a_' });
|
||||||
|
|
||||||
|
this.gl = this.canvas.getContext('webgl2');
|
||||||
|
if (!this.gl) {
|
||||||
|
throw new Error('WebGl2 not supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.programInfo = twgl.createProgramInfo(this.gl, shaderSources);
|
||||||
|
|
||||||
|
const arrays = {
|
||||||
|
position: {
|
||||||
|
numComponents: 3,
|
||||||
|
data: [-1.0, -1.0, 0.0, -1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, -1.0, 0.0],
|
||||||
|
},
|
||||||
|
indices: {
|
||||||
|
numComponents: 3,
|
||||||
|
data: [0, 1, 2, 0, 2, 3],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.bufferInfo = twgl.createBufferInfoFromArrays(this.gl, arrays);
|
||||||
|
this.vao = twgl.createVAOFromBufferInfo(
|
||||||
|
this.gl,
|
||||||
|
this.programInfo,
|
||||||
|
this.bufferInfo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
requestAnimationFrame(this.render.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private render(time: number) {
|
||||||
|
const gl = this.gl;
|
||||||
|
|
||||||
|
twgl.resizeCanvasToDisplaySize(this.canvas);
|
||||||
|
this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);
|
||||||
|
|
||||||
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
const uniforms = {
|
||||||
|
/*time: time * 0.001,
|
||||||
|
resolution: [this.gl.canvas.width, this.gl.canvas.height],*/
|
||||||
|
};
|
||||||
|
|
||||||
|
this.gl.useProgram(this.programInfo.program);
|
||||||
|
this.gl.bindVertexArray(this.vao);
|
||||||
|
//twgl.setBuffersAndAttributes(this.gl, this.programInfo, this.bufferInfo);
|
||||||
|
|
||||||
|
twgl.setUniforms(this.programInfo, uniforms);
|
||||||
|
twgl.drawBufferInfo(this.gl, this.bufferInfo);
|
||||||
|
|
||||||
|
requestAnimationFrame(this.render.bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
16
frontend/src/scripting/main.ts
Normal file
16
frontend/src/scripting/main.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { Renderer } from './drawing/renderer';
|
||||||
|
|
||||||
|
import passthroughVertexShader from '../shaders/passthrough.vert';
|
||||||
|
import distanceFragmentShader from '../shaders/dist.frag';
|
||||||
|
|
||||||
|
|
||||||
|
export const main = () => {
|
||||||
|
try {
|
||||||
|
const canvas: HTMLCanvasElement = document.querySelector('canvas#main');
|
||||||
|
const renderer = new Renderer(canvas, [passthroughVertexShader, distanceFragmentShader]);
|
||||||
|
renderer.start();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -1,23 +1,19 @@
|
||||||
#ifdef GL_ES
|
#version 300 es
|
||||||
precision mediump float;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define INFINITY 1.0 / 0.0
|
precision mediump float;
|
||||||
|
|
||||||
|
|
||||||
|
#define INFINITY 10000000.0
|
||||||
|
|
||||||
#define WORLD_SIZE 4
|
#define WORLD_SIZE 4
|
||||||
|
|
||||||
#define N (20)
|
#define N (20)
|
||||||
|
|
||||||
uniform vec2 u_resolution;
|
out vec4 fragmentColor;
|
||||||
uniform vec2 u_mouse;
|
|
||||||
uniform float u_time;
|
|
||||||
|
|
||||||
struct Light {
|
uniform vec2 resolution;
|
||||||
vec2 center;
|
// uniform vec2 u_mouse;
|
||||||
float radius;
|
uniform float time;
|
||||||
vec3 color;
|
|
||||||
float intensity;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Circle {
|
struct Circle {
|
||||||
vec2 center;
|
vec2 center;
|
||||||
|
|
@ -52,11 +48,6 @@ float circleDistance(in vec2 position, in Circle circle)
|
||||||
return length(position - circle.center) - circle.radius;
|
return length(position - circle.center) - circle.radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
float circleDistance(in vec2 position, in Light circle)
|
|
||||||
{
|
|
||||||
return length(position - circle.center) - circle.radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getDistance(in vec2 target) {
|
float getDistance(in vec2 target) {
|
||||||
float distance = INFINITY;
|
float distance = INFINITY;
|
||||||
for (int i = 0; i < WORLD_SIZE; i++) {
|
for (int i = 0; i < WORLD_SIZE; i++) {
|
||||||
|
|
@ -93,5 +84,5 @@ void main() {
|
||||||
vec2 position = gl_FragCoord.xy + vec2(0.5);
|
vec2 position = gl_FragCoord.xy + vec2(0.5);
|
||||||
|
|
||||||
vec3 color = vec3(1.0) * linearstep(0.0, 1.0, getDistance(position));
|
vec3 color = vec3(1.0) * linearstep(0.0, 1.0, getDistance(position));
|
||||||
gl_FragColor = vec4(color, 1.0);
|
fragmentColor = vec4(color, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -10,9 +12,9 @@ precision mediump float;
|
||||||
#define LIGHT_PENETRATION 0.95
|
#define LIGHT_PENETRATION 0.95
|
||||||
#define ANTIALIASING_RADIUS 1.0
|
#define ANTIALIASING_RADIUS 1.0
|
||||||
|
|
||||||
uniform vec2 u_resolution;
|
uniform vec2 resolution;
|
||||||
uniform vec2 u_mouse;
|
// uniform vec2 u_mouse;
|
||||||
uniform float u_time;
|
uniform float time;
|
||||||
|
|
||||||
struct Light {
|
struct Light {
|
||||||
vec2 center;
|
vec2 center;
|
||||||
|
|
|
||||||
7
frontend/src/shaders/passthrough.vert
Normal file
7
frontend/src/shaders/passthrough.vert
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
in vec4 a_position;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = a_position;
|
||||||
|
}
|
||||||
19
frontend/src/styling/main.scss
Normal file
19
frontend/src/styling/main.scss
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
html, body, main {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
background-color: #333;
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
width: 100%;
|
||||||
|
background-color: hotpink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "./dist/",
|
"outDir": "./dist/",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"module": "es6",
|
"module": "es6",
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"downlevelIteration": true,
|
"downlevelIteration": true,
|
||||||
"allowJs": true
|
"allowJs": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,40 +62,6 @@ module.exports = {
|
||||||
placeholder: false,
|
placeholder: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
test: /\.(webm|mp4|gif)$/i,
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: 'file-loader',
|
|
||||||
query: {
|
|
||||||
outputPath: 'static/',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
loader: 'image-webpack-loader',
|
|
||||||
options: {
|
|
||||||
disable: !isProduction,
|
|
||||||
mozjpeg: {
|
|
||||||
progressive: true,
|
|
||||||
quality: 65,
|
|
||||||
},
|
|
||||||
optipng: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
pngquant: {
|
|
||||||
quality: [0.65, 0.9],
|
|
||||||
speed: 4,
|
|
||||||
},
|
|
||||||
gifsicle: {
|
|
||||||
interlaced: false,
|
|
||||||
},
|
|
||||||
webp: {
|
|
||||||
quality: 65,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
test: /\.svg$/,
|
test: /\.svg$/,
|
||||||
loader: 'svg-url-loader',
|
loader: 'svg-url-loader',
|
||||||
|
|
@ -105,13 +71,9 @@ module.exports = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(pdf)$/i,
|
test: /\.(frag|vert)$/i,
|
||||||
use: {
|
use: {
|
||||||
loader: 'file-loader',
|
loader: 'raw-loader'
|
||||||
query: {
|
|
||||||
outputPath: 'static/',
|
|
||||||
name: '[name].[ext]',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ server {
|
||||||
server_name decla.red;
|
server_name decla.red;
|
||||||
server_tokens off;
|
server_tokens off;
|
||||||
|
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/decla.red/fullchain.pem;
|
ssl_certificate /etc/letsencrypt/live/decla.red/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/decla.red/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/decla.red/privkey.pem;
|
||||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue