diff --git a/.gitignore b/.gitignore index e69de29..1115aed 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +target +dist \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8fe677c..dac0115 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2630,36 +2630,6 @@ "schema-utils": "^2.7.1" }, "dependencies": { - "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, "json5": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", @@ -2680,12 +2650,6 @@ "json5": "^2.1.2" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", diff --git a/package.json b/package.json index e42f98d..5114bb0 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,23 @@ { "name": "webgl3drenderer", - "version": "1.0.0", - "description": "3D PBR WIP renderer", + "version": "0.1.0", + "description": "3D Game engine on the web.", "private": true, + "scripts": { "dev": "concurrently --kill-others \"webpack watch --dev\" \"tsc --watch\"", "build": "webpack --config webpack.config.js", "watchwp": "webpack --watch", - "watchts": "tsc --watch" + "watchts": "tsc --watch", + "serve": "webpack-dev-server", + "watch": "", + "clean": "" }, + "author": "Abdullah Amr", + "license": "ISC", + "devDependencies": { "@babel/core": "^7.11.6", "@babel/preset-env": "^7.11.5", @@ -23,6 +30,7 @@ "webpack-cli": "^3.3.12", "webpack-dev-server": "^3.11.0" }, + "dependencies": { "gl-matrix": "^3.1.0" } diff --git a/scripts/build.js b/scripts/build.js new file mode 100644 index 0000000..f293d3a --- /dev/null +++ b/scripts/build.js @@ -0,0 +1 @@ +//todo. \ No newline at end of file diff --git a/scripts/clean.js b/scripts/clean.js new file mode 100644 index 0000000..f293d3a --- /dev/null +++ b/scripts/clean.js @@ -0,0 +1 @@ +//todo. \ No newline at end of file diff --git a/scripts/watch.js b/scripts/watch.js new file mode 100644 index 0000000..f293d3a --- /dev/null +++ b/scripts/watch.js @@ -0,0 +1 @@ +//todo. \ No newline at end of file diff --git a/src/CameraController.ts b/src/CameraController.ts index 59fee19..adf2326 100644 --- a/src/CameraController.ts +++ b/src/CameraController.ts @@ -8,6 +8,10 @@ export abstract class Projection { public abstract update(): void; } + + + + export namespace Projection { export class Prespective extends Projection { constructor ( @@ -47,6 +51,13 @@ export namespace Projection { } } + + +class KeyStateMap { + constructor(public name: string, public state: boolean) {} +} + + export class CameraController implements IUpdatableSystem { @@ -63,8 +74,26 @@ export class CameraController implements IUpdatableSystem { this.oriantation ); + console.log("camera controller init"); + window.addEventListener("keydown", event => { + if ( event.key == "w") this.activeKeys[0].state = true; + if ( event.key == "s") this.activeKeys[1].state = true; + if ( event.key == "d") this.activeKeys[2].state = true; + if ( event.key == "a") this.activeKeys[3].state = true; + }); + + window.addEventListener("keyup", event => { + if ( event.key == "w") this.activeKeys[0].state = false; + if ( event.key == "s") this.activeKeys[1].state = false; + if ( event.key == "d") this.activeKeys[2].state = false; + if ( event.key == "a") this.activeKeys[3].state = false; + }); + } + + + public updateCameraMatrix(timestep: number): void { this.viewMatrix = mat4.lookAt( this.viewMatrix, @@ -75,8 +104,42 @@ export class CameraController implements IUpdatableSystem { } public update(timestep: number): void { - + + if(this.activeKeys[0].state) this.moveForward(); + if(this.activeKeys[1].state) this.moveBackward(); + if(this.activeKeys[2].state) this.moveRight(); + if(this.activeKeys[3].state) this.moveLeft(); + + } + + private moveForward() : void { + console.log("moving forward"); + vec3.add(this.position, this.position, this.forwardVector); + } + + private moveBackward() : void { + vec3.add(this.position, this.position, vec3.scale(new vec3(), this.forwardVector, -1)); + } + + private moveRight() : void { + console.log("moving to the right"); } + + private moveLeft() : void { + console.log("moving to the left"); + } + + + + private activeKeys: Array = [ + new KeyStateMap("w", false), + new KeyStateMap("s", false), + new KeyStateMap("d", false), + new KeyStateMap("a", false), + ]; + + private forwardVector: vec3 = vec3.fromValues(0, 1, 0); + private rightVector: vec3 = vec3.fromValues(0, 0, 1); } export namespace CameraController { diff --git a/src/Engine.ts b/src/Engine.ts index 0362512..fc1ea20 100644 --- a/src/Engine.ts +++ b/src/Engine.ts @@ -1,15 +1,14 @@ import { IUpdatableSystem } from "Engine/core/SystemsManager"; - export class Engine { private lastUpdate: number = 0; - private runningSystems: IUpdatableSystem[] = []; private runningTasks: CallableFunction[] = []; constructor(renderingContext: WebGLRenderingContext) { } + public onInit(context: WebGLRenderingContext): void { } @@ -35,7 +34,6 @@ export class Engine { this.lastUpdate = Date.now(); } - public run(): void { let that = this; function loop() { diff --git a/src/assets/image.ts b/src/assets/image.ts deleted file mode 100644 index 365c80d..0000000 --- a/src/assets/image.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module "*.jpg" { - const value: any; - export default value; - }; \ No newline at end of file diff --git a/src/assets/models/cube.json b/src/assets/models/cube.json new file mode 100644 index 0000000..2e6b901 --- /dev/null +++ b/src/assets/models/cube.json @@ -0,0 +1,186 @@ +{ + "vertcies": [ + -1.0, + 1.0, + -1.0, + 0.5, + 0.5, + 0.5, + -1.0, + 1.0, + 1.0, + 0.5, + 0.5, + 0.5, + 1.0, + 1.0, + 1.0, + 0.5, + 0.5, + 0.5, + 1.0, + 1.0, + -1.0, + 0.5, + 0.5, + 0.5, + -1.0, + 1.0, + 1.0, + 0.75, + 0.25, + 0.5, + -1.0, + -1.0, + 1.0, + 0.75, + 0.25, + 0.5, + -1.0, + -1.0, + -1.0, + 0.75, + 0.25, + 0.5, + -1.0, + 1.0, + -1.0, + 0.75, + 0.25, + 0.5, + 1.0, + 1.0, + 1.0, + 0.25, + 0.25, + 0.75, + 1.0, + -1.0, + 1.0, + 0.25, + 0.25, + 0.75, + 1.0, + -1.0, + -1.0, + 0.25, + 0.25, + 0.75, + 1.0, + 1.0, + -1.0, + 0.25, + 0.25, + 0.75, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.15, + 1.0, + -1.0, + 1.0, + 1.0, + 0.0, + 0.15, + -1.0, + -1.0, + 1.0, + 1.0, + 0.0, + 0.15, + -1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 0.15, + 1.0, + 1.0, + -1.0, + 0.0, + 1.0, + 0.15, + 1.0, + -1.0, + -1.0, + 0.0, + 1.0, + 0.15, + -1.0, + -1.0, + -1.0, + 0.0, + 1.0, + 0.15, + -1.0, + 1.0, + -1.0, + 0.0, + 1.0, + 0.15, + -1.0, + -1.0, + -1.0, + 0.5, + 0.5, + 1.0, + -1.0, + -1.0, + 1.0, + 0.5, + 0.5, + 1.0, + 1.0, + -1.0, + 1.0, + 0.5, + 0.5, + 1.0, + 1.0, + -1.0, + -1.0, + 0.5, + 0.5, + 1.0 + ], + "indcies": [ + 0, + 1, + 2, + 0, + 2, + 3, + 5, + 4, + 6, + 6, + 4, + 7, + 8, + 9, + 10, + 8, + 10, + 11, + 13, + 12, + 14, + 15, + 14, + 12, + 16, + 17, + 18, + 16, + 18, + 19, + 21, + 20, + 22, + 22, + 20, + 23 + ] +} \ No newline at end of file diff --git a/src/assets/models/model.d.ts b/src/assets/models/model.d.ts new file mode 100644 index 0000000..a1784ea --- /dev/null +++ b/src/assets/models/model.d.ts @@ -0,0 +1,9 @@ +export interface Model { + vertcies: number[]; + indcies: number[]; +} + +declare module "*.json" { + const content: Model; + export default content; +} \ No newline at end of file diff --git a/src/assets/models/triangle.json b/src/assets/models/triangle.json new file mode 100644 index 0000000..0a388e4 --- /dev/null +++ b/src/assets/models/triangle.json @@ -0,0 +1,24 @@ +{ + "vertcies": [ + 0.0, + 0.5, + 1.0, + 1.0, + 0.0, + -0.5, + -0.5, + 0.7, + 0.0, + 1.0, + 0.5, + -0.5, + 0.1, + 1.0, + 0.6 + ], + "indcies": [ + 1, + 2, + 3 + ] +} \ No newline at end of file diff --git a/src/assets/shaders/DefaultFragmentShader.glsl b/src/assets/shaders/DefaultFragmentShader.glsl deleted file mode 100644 index 18d0f37..0000000 --- a/src/assets/shaders/DefaultFragmentShader.glsl +++ /dev/null @@ -1,7 +0,0 @@ -precision mediump float; - -varying vec3 fragColor; -void main() -{ - gl_FragColor = vec4(fragColor, 1.0); -} \ No newline at end of file diff --git a/src/assets/shaders/defaultPipelineShader.glsl b/src/assets/shaders/defaultPipelineShader.glsl new file mode 100644 index 0000000..28478cf --- /dev/null +++ b/src/assets/shaders/defaultPipelineShader.glsl @@ -0,0 +1,24 @@ +precision mediump float; + +attribute vec3 vertPosition; +attribute vec3 vertColor; +varying vec3 fragColor; +uniform mat4 mWorld; +uniform mat4 mView; +uniform mat4 mProj; + +void main() +{ + fragColor = vertColor; + gl_Position = mProj * mView * mWorld * vec4(vertPosition, 1.0); +} + +//<> + +precision mediump float; + +varying vec3 fragColor; +void main() +{ + gl_FragColor = vec4(fragColor, 1.0); +} diff --git a/src/assets/shaders/DefaultVertexShader.glsl b/src/assets/shaders/primitivePipelineShader.glsl similarity index 61% rename from src/assets/shaders/DefaultVertexShader.glsl rename to src/assets/shaders/primitivePipelineShader.glsl index ef7250a..19d497a 100644 --- a/src/assets/shaders/DefaultVertexShader.glsl +++ b/src/assets/shaders/primitivePipelineShader.glsl @@ -8,4 +8,14 @@ void main() { fragColor = vertColor; gl_Position = vec4(vertPosition, 0.0, 1.0); +} + +//<> + +precision mediump float; + +varying vec3 fragColor; +void main() +{ + gl_FragColor = vec4(fragColor, 1.0); } \ No newline at end of file diff --git a/src/assets/shaders/shaders.d.ts b/src/assets/shaders/shaders.d.ts index e060c51..3796a63 100644 --- a/src/assets/shaders/shaders.d.ts +++ b/src/assets/shaders/shaders.d.ts @@ -1,4 +1,19 @@ -declare module "*!glsl" { +declare module "*.txt" { const content: string; export default content; - } \ No newline at end of file +} + +declare module "*.glsl" { + const content: string; + export default content; +} + +declare module "*.vert" { + const content: string; + export default content; +} + +declare module "*.frag" { + const content: string; + export default content; +} \ No newline at end of file diff --git a/src/assets/image.jpg b/src/assets/textures/noise.png similarity index 100% rename from src/assets/image.jpg rename to src/assets/textures/noise.png diff --git a/src/assets/textures/texture.d.ts b/src/assets/textures/texture.d.ts new file mode 100644 index 0000000..ced2dc8 --- /dev/null +++ b/src/assets/textures/texture.d.ts @@ -0,0 +1,4 @@ +declare module "*.png" { + const content: string; + export default content; +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index f19cdfd..d76048a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,138 +10,32 @@ import { Components } from "./Core/CoreComponents/Components"; import { ActorManager } from "./Core/Actors"; +import * as cubeMeshData from "Models/cube.json"; +import * as triangleMeshData from "Models/triangle.json"; -var _2dcanvas = document.getElementById("view_texture") as HTMLCanvasElement; -var ctx = _2dcanvas.getContext("2d") as CanvasRenderingContext2D; +import * as defaultGlslShaderSource from "Shaders/defaultPipelineShader.glsl"; +import * as primativeGlslShaderSource from "Shaders/primitivePipelineShader.glsl"; +import * as defaultNoiseTexture from "Textures/noise.png"; +console.log(defaultNoiseTexture.default); -//#region -var triangleVertices = - [ // X, Y, R, G, B - 0.0, 0.5, 1.0, 1.0, 0.0, - -0.5, -0.5, 0.7, 0.0, 1.0, - 0.5, -0.5, 0.1, 1.0, 0.6 - ]; - -var triangleIndices = [1, 2, 3]; - -var boxVertices = - [ // X, Y, Z R, G, B - // Top - -1.0, 1.0, -1.0, 0.5, 0.5, 0.5, - -1.0, 1.0, 1.0, 0.5, 0.5, 0.5, - 1.0, 1.0, 1.0, 0.5, 0.5, 0.5, - 1.0, 1.0, -1.0, 0.5, 0.5, 0.5, - - // Left - -1.0, 1.0, 1.0, 0.75, 0.25, 0.5, - -1.0, -1.0, 1.0, 0.75, 0.25, 0.5, - -1.0, -1.0, -1.0, 0.75, 0.25, 0.5, - -1.0, 1.0, -1.0, 0.75, 0.25, 0.5, - - // Right - 1.0, 1.0, 1.0, 0.25, 0.25, 0.75, - 1.0, -1.0, 1.0, 0.25, 0.25, 0.75, - 1.0, -1.0, -1.0, 0.25, 0.25, 0.75, - 1.0, 1.0, -1.0, 0.25, 0.25, 0.75, - - // Front - 1.0, 1.0, 1.0, 1.0, 0.0, 0.15, - 1.0, -1.0, 1.0, 1.0, 0.0, 0.15, - -1.0, -1.0, 1.0, 1.0, 0.0, 0.15, - -1.0, 1.0, 1.0, 1.0, 0.0, 0.15, - - // Back - 1.0, 1.0, -1.0, 0.0, 1.0, 0.15, - 1.0, -1.0, -1.0, 0.0, 1.0, 0.15, - -1.0, -1.0, -1.0, 0.0, 1.0, 0.15, - -1.0, 1.0, -1.0, 0.0, 1.0, 0.15, - - // Bottom - -1.0, -1.0, -1.0, 0.5, 0.5, 1.0, - -1.0, -1.0, 1.0, 0.5, 0.5, 1.0, - 1.0, -1.0, 1.0, 0.5, 0.5, 1.0, - 1.0, -1.0, -1.0, 0.5, 0.5, 1.0, - ]; - -var CubeVertcies = -[ - - // X, Y, Z - // Top - -1.0, 1.0, -1.0, - -1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, - 1.0, 1.0, -1.0, - // Left - -1.0, 1.0, 1.0, - -1.0, -1.0, 1.0, - -1.0, -1.0, -1.0, - -1.0, 1.0, -1.0, - // Right - 1.0, 1.0, 1.0, - 1.0, -1.0, 1.0, - 1.0, -1.0, -1.0, - 1.0, 1.0, -1.0, - // Front - 1.0, 1.0, 1.0, - 1.0, -1.0, 1.0, - -1.0, -1.0, 1.0, - -1.0, 1.0, 1.0, - // Back - 1.0, 1.0, -1.0, - 1.0, -1.0, -1.0, - -1.0, -1.0, -1.0, - -1.0, 1.0, -1.0, - // Bottom - -1.0, -1.0, -1.0, - -1.0, -1.0, 1.0, - 1.0, -1.0, 1.0, - 1.0, -1.0, -1.0, -]; - -var boxIndices = - [ - // Top - 0, 1, 2, - 0, 2, 3, - - // Left - 5, 4, 6, - 6, 4, 7, - - // Right - 8, 9, 10, - 8, 10, 11, - - // Front - 13, 12, 14, - 15, 14, 12, - - // Back - 16, 17, 18, - 16, 18, 19, - - // Bottom - 21, 20, 22, - 22, 20, 23 - ]; -//#endregion +let defaultPipelineShader = defaultGlslShaderSource.default.split("//<>"); +let primativePipelineShader = primativeGlslShaderSource.default.split("//<>"); let actorManager: ActorManager = new ActorManager(); let cubeMesh: Components.StaticMesh = { - vertcies: boxVertices, - indcies: boxIndices, + vertcies: cubeMeshData.vertcies, + indcies: cubeMeshData.indcies, } let cube = new CubeGActor("cube"); cube.attachStaticMesh(cubeMesh); let mainCamera = new CameraController( - vec3.fromValues(8,8,-8), - vec3.fromValues(0,0,0), - vec3.fromValues(0,1,0), + vec3.fromValues(8, 8, -8), + vec3.fromValues(0, 0, 0), + vec3.fromValues(0, 1, 0), ); actorManager.registerActor(cube); @@ -152,70 +46,7 @@ let game = new Engine(gl); game.registerNewSystem(actorManager); game.registerNewSystem(mainCamera); - -//#region -var vertexShaderText = - [ - 'precision mediump float;', - '', - 'attribute vec2 vertPosition;', - 'attribute vec3 vertColor;', - 'varying vec3 fragColor;', - '', - 'void main()', - '{', - ' fragColor = vertColor;', - ' gl_Position = vec4(vertPosition, 0.0, 1.0);', - '}' - ].join('\n'); - -var fragmentShaderText = - [ - 'precision mediump float;', - '', - 'varying vec3 fragColor;', - 'void main()', - '{', - ' gl_FragColor = vec4(fragColor, 1.0);', - '}' - ].join('\n'); - -var vertexShaderCubeText = - [ - 'precision mediump float;', - '', - 'attribute vec3 vertPosition;', - 'attribute vec3 vertColor;', - 'varying vec3 fragColor;', - 'uniform mat4 mWorld;', - 'uniform mat4 mView;', - 'uniform mat4 mProj;', - '', - 'void main()', - '{', - ' fragColor = vertColor;', - ' gl_Position = mProj * mView * mWorld * vec4(vertPosition, 1.0);', - '}' - ].join('\n'); - -var fragmentShaderCubeText = - [ - 'precision mediump float;', - '', - 'varying vec3 fragColor;', - 'void main()', - '{', - ' gl_FragColor = vec4(fragColor, 1.0);', - '}' - ].join('\n'); - -import glsl from "./assets/shaders/DefaultFragmentShader.glsl!glsl" - -console.log("Hello world", glsl); - -//#endregion - -const flatColorShader = new Shader("flatColor", vertexShaderCubeText, fragmentShaderCubeText); +const flatColorShader = new Shader("flatColor", defaultPipelineShader[0], defaultPipelineShader[1]); const program = flatColorShader.shaderProgram; const vao_triangle = new VertexArray(program); @@ -223,9 +54,9 @@ const bufferLayout_triangle = new Buffer.BufferLayout([ new Buffer.BufferElement("vertPosition", Buffer.ShaderDataType.Float2), new Buffer.BufferElement("vertColor", Buffer.ShaderDataType.Float3) ]); -const vbo_triangle = new VertexBuffer(program, triangleVertices, triangleVertices.length); +const vbo_triangle = new VertexBuffer(program, triangleMeshData.vertcies, triangleMeshData.vertcies.length); vbo_triangle.setLayout(bufferLayout_triangle); -const ibo_triangle = new IndexBuffer(triangleIndices, triangleIndices.length); +const ibo_triangle = new IndexBuffer(triangleMeshData.indcies, triangleMeshData.indcies.length); vao_triangle.addVertexBuffer(vbo_triangle); vao_triangle.setIndexBuffer(ibo_triangle); vao_triangle.unbind(); @@ -236,9 +67,9 @@ const bufferLayout = new Buffer.BufferLayout([ new Buffer.BufferElement("vertPosition", Buffer.ShaderDataType.Float3), new Buffer.BufferElement("vertColor", Buffer.ShaderDataType.Float3) ]); -const vbo = new VertexBuffer(program, boxVertices, boxVertices.length); +const vbo = new VertexBuffer(program, cubeMeshData.vertcies, cubeMeshData.vertcies.length); vbo.setLayout(bufferLayout); -const ibo = new IndexBuffer(boxIndices, boxIndices.length); +const ibo = new IndexBuffer(cubeMeshData.vertcies, cubeMeshData.vertcies.length); vao.addVertexBuffer(vbo); vao.setIndexBuffer(ibo); vao.unbind(); @@ -253,7 +84,6 @@ flatColorShader.bind(); var viewMatrix = mainCamera.viewMatrix; var projMatrix = mat4.perspective(mat4.create(), glMatrix.toRadian(45), gl.canvas.width / gl.canvas.height, 0.1, 1000.0); - RenderCommands.initRenderer(); game.registerNewTask(function (time: number) { @@ -273,5 +103,4 @@ game.registerNewTask(function (time: number) { }); }); - game.run(); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 6b90995..e3e0b3c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -46,7 +46,8 @@ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - //"resolveJsonModule": true, + "moduleResolution": "Node", + "resolveJsonModule": true, // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/webpack.config.js b/webpack.config.js index 0a47231..377dd1c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -21,7 +21,14 @@ module.exports = { module: { rules: [ - { test: /\.glsl$/, use: 'raw-loader' } + { + test: /\.(png|jpe?g|gif|jpg)$/i, + use: 'file-loader' + }, + { + test: /\.glsl$/i, + use: 'raw-loader' + } ] },