diff --git a/custom-webgl/CustomWebGL.wlp b/custom-webgl/CustomWebGL.wlp new file mode 100644 index 0000000..80be9e9 --- /dev/null +++ b/custom-webgl/CustomWebGL.wlp @@ -0,0 +1,929 @@ +{ + "objects": { + "76": { + "name": "Player", + "components": [ + { + "type": "wasd-controls", + "wasd-controls": { + "headObject": "77" + } + } + ], + "scaling": [ + 0.9999998, + 1.0, + 0.9999998 + ], + "translation": [ + -3.9999997, + 1.8000134, + 4.0 + ], + "rotation": [ + 0.0, + -0.3826834, + 0.0, + 0.9238795 + ] + }, + "77": { + "name": "NonVrCamera", + "parent": "76", + "components": [ + { + "type": "view" + }, + { + "type": "mouse-look" + } + ] + }, + "78": { + "name": "EyeLeft", + "parent": "76", + "components": [ + { + "type": "view" + }, + { + "type": "input", + "input": { + "type": "eye left" + } + } + ] + }, + "79": { + "name": "EyeRight", + "parent": "76", + "components": [ + { + "type": "view" + }, + { + "type": "input", + "input": { + "type": "eye right" + } + } + ] + }, + "80": { + "name": "FloorPlane", + "components": [ + { + "type": "mesh", + "mesh": { + "mesh": "p0", + "material": "20" + } + } + ], + "scaling": [ + 15.9999961, + 16.0, + 16.0 + ], + "translation": [ + 0.0, + -0.0, + 1.1921009956950004e-7 + ], + "rotation": [ + -0.7072544, + 0.0, + 0.0, + 0.7069591 + ] + }, + "81": { + "name": "Cube", + "components": [ + { + "type": "mesh", + "mesh": { + "mesh": "p1", + "material": "22" + } + } + ], + "scaling": [ + 0.5, + 0.5, + 0.5 + ], + "translation": [ + -0.6665739, + 0.4999999, + 0.5696738 + ], + "rotation": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "82": { + "name": "Light", + "components": [ + { + "type": "light", + "light": { + "intensity": 9.0, + "type": "spot", + "outerAngle": 120.0, + "shadows": true, + "shadowRange": 20.0, + "innerAngle": 110.0 + } + } + ], + "scaling": [ + 1.0000013, + 0.9999992, + 1.0 + ], + "translation": [ + -0.2080335, + 3.2420806, + 2.9316577 + ], + "rotation": [ + 0.2517567, + -0.7649071, + -0.1853631, + 0.5631838 + ] + }, + "83": { + "name": "Light.000", + "components": [ + { + "type": "light", + "light": { + "intensity": 9.0, + "type": "spot", + "shadows": true, + "outerAngle": 120.0, + "innerAngle": 110.0, + "shadowRange": 20.0 + } + } + ], + "scaling": [ + 0.9999988, + 0.9999977, + 0.9999989 + ], + "translation": [ + -2.3912234, + 3.4619092, + -3.0973172 + ], + "rotation": [ + -0.3265219, + 0.1176851, + 0.3179933, + 0.8822776 + ] + }, + "84": { + "name": "Cone", + "components": [ + { + "type": "mesh", + "mesh": { + "mesh": "p3", + "material": "25" + } + } + ], + "scaling": [ + 1.0, + 1.0, + 1.0 + ], + "translation": [ + 0.8334258, + 1.0, + 0.5696737 + ], + "rotation": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "85": { + "name": "Sphere", + "components": [ + { + "type": "mesh", + "mesh": { + "mesh": "p2", + "material": "26" + } + } + ], + "scaling": [ + 0.75, + 0.75, + 0.75 + ], + "translation": [ + -0.166574, + 0.75, + -0.6803262 + ], + "rotation": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "86": { + "name": "Manager", + "components": [ + { + "type": "custom-webgl" + } + ] + } + }, + "meshes": { + "p0": { + "link": { + "name": "PrimitivePlane", + "file": "default" + } + }, + "p1": { + "link": { + "name": "PrimitiveCube", + "file": "default" + } + }, + "p2": { + "link": { + "name": "PrimitiveSphere", + "file": "default" + } + }, + "p3": { + "link": { + "name": "PrimitiveCone", + "file": "default" + } + }, + "p4": { + "link": { + "name": "PrimitiveCylinder", + "file": "default" + } + }, + "p5": { + "link": { + "name": "PrimitiveCircle", + "file": "default" + } + } + }, + "materials": { + "DefaultFontMaterial": { + "link": { + "name": "DefaultFontMaterial", + "file": "default" + } + }, + "20": { + "name": "White", + "Phong": { + "specularColor": [ + 9.999899930335232e-7, + 9.99993744699168e-7, + 9.999999974752427e-7, + 1.0 + ], + "shininess": 1, + "emissiveColor": [ + 0.2, + 0.2, + 0.2, + 1.0 + ], + "ambientColor": [ + 0.05, + 0.05, + 0.05, + 1.0 + ], + "diffuseColor": [ + 0.5, + 0.5, + 0.5, + 1.0 + ] + }, + "pipeline": "37" + }, + "22": { + "name": "Pink", + "Phong": { + "diffuseColor": [ + 0.9098039, + 0.0, + 0.5411764, + 1.0 + ], + "specularColor": [ + 9.999899930335232e-7, + 9.999911299019004e-7, + 9.999999974752427e-7, + 1.0 + ], + "shininess": 10, + "ambientColor": [ + 0.05, + 0.05, + 0.05, + 1.0 + ], + "emissiveColor": [ + 0.1921568, + 0.0, + 0.1310161, + 1.0 + ] + }, + "pipeline": "91", + "CustomShader": { + "color": [ + 1.0, + 0.0, + 0.0, + 1.0 + ] + } + }, + "25": { + "name": "Yellow", + "Phong": { + "diffuseColor": [ + 1.0, + 0.8039215, + 0.0, + 1.0 + ], + "specularColor": [ + 9.999999974752427e-7, + 9.999899930335232e-7, + 9.999899930335232e-7, + 1.0 + ], + "ambientColor": [ + 0.05, + 0.05, + 0.05, + 1.0 + ], + "emissiveColor": [ + 0.2588235, + 0.2080737, + 0.0, + 1.0 + ] + }, + "pipeline": "37" + }, + "26": { + "name": "Green", + "Phong": { + "diffuseColor": [ + 0.1529411, + 0.7882353, + 0.5411764, + 1.0 + ], + "specularColor": [ + 9.999999974752427e-7, + 9.999899930335232e-7, + 9.999899930335232e-7, + 1.0 + ], + "ambientColor": [ + 0.05, + 0.05, + 0.05, + 1.0 + ], + "emissiveColor": [ + 0.0, + 0.1686274, + 0.10305, + 1.0 + ] + }, + "pipeline": "37" + }, + "89": { + "name": "Sky", + "Phong": { + "specularColor": [ + 9.999899930335232e-7, + 9.99993744699168e-7, + 9.999999974752427e-7, + 1.0 + ], + "shininess": 1, + "emissiveColor": [ + 0.2, + 0.2, + 0.2, + 1.0 + ], + "ambientColor": [ + 0.05, + 0.05, + 0.05, + 1.0 + ], + "diffuseColor": [ + 0.5, + 0.5, + 0.5, + 1.0 + ] + }, + "pipeline": "54", + "Sky": { + "colorStop3": [ + 0.57584, + 0.5798863, + 0.5803921, + 1.0 + ], + "colorStop2": [ + 0.2023221, + 0.2037438, + 0.2039215, + 1.0 + ], + "colorStop1": [ + 0.2023221, + 0.2037438, + 0.2039215, + 1.0 + ], + "colorStop0": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + } + } + }, + "shaders": { + "2": { + "link": { + "name": "Flat.frag", + "file": "default" + } + }, + "4": { + "link": { + "name": "MeshVisualizer.frag", + "file": "default" + } + }, + "5": { + "link": { + "name": "Phong.frag", + "file": "default" + } + }, + "28": { + "link": { + "name": "Dynamic.vert", + "file": "default" + } + }, + "30": { + "link": { + "name": "Skinning.vert", + "file": "default" + } + }, + "32": { + "link": { + "name": "DistanceFieldVector.frag", + "file": "default" + } + }, + "39": { + "link": { + "name": "Particle.frag", + "file": "default" + } + }, + "42": { + "link": { + "name": "Background.frag", + "file": "default" + } + }, + "43": { + "link": { + "name": "Depth.frag", + "file": "default" + } + }, + "45": { + "link": { + "name": "FullScreenTriangle.vert", + "file": "default" + } + }, + "46": { + "link": { + "name": "Physical.frag", + "file": "default" + } + }, + "49": { + "link": { + "name": "Sky.frag", + "file": "default" + } + }, + "50": { + "link": { + "name": "Text.frag", + "file": "default" + } + }, + "52": { + "link": { + "name": "Text.vert", + "file": "default" + } + }, + "53": { + "link": { + "name": "TileFeedback.frag", + "file": "default" + } + }, + "86": { + "link": { + "name": "AtmosphericSky.frag", + "file": "default" + } + }, + "88": { + "link": { + "name": "Color.frag", + "file": "default" + } + }, + "89": { + "link": { + "name": "CustomShader.frag", + "file": "default" + } + } + }, + "settings": { + "project": { + "name": "CustomWebGL.wlp", + "version": [ + 1, + 5, + 0 + ] + }, + "scripting": { + "application": { + "output": "CustomWebGL.wlp-app.js", + "bundling": "esbuild" + }, + "components": { + "output": "CustomWebGL.wlp-bundle.js" + }, + "libraryPaths": [ + "/js/lib/" + ] + }, + "rendering": { + "hdr": { + "exposure": 1.5 + }, + "sky": { + "enabled": true, + "material": "89" + }, + "environment": { + "bakingMode": "sky", + "material": "89" + } + }, + "runtime": { + "viewObject": "77", + "loadUncompressedImagesAsBitmap": false + }, + "xr": { + "leftEyeObject": "78", + "rightEyeObject": "79" + } + }, + "animations": {}, + "skins": {}, + "pipelines": { + "33": { + "link": { + "name": "DistanceFieldVector", + "file": "default" + } + }, + "34": { + "link": { + "name": "Flat Opaque", + "file": "default" + } + }, + "35": { + "link": { + "name": "Flat Opaque Textured", + "file": "default" + } + }, + "36": { + "link": { + "name": "MeshVisualizer", + "file": "default" + } + }, + "37": { + "link": { + "name": "Phong Opaque", + "file": "default" + }, + "features": { + "WITH_EMISSIVE": true + } + }, + "38": { + "link": { + "name": "Phong Opaque Textured", + "file": "default" + }, + "features": { + "WITH_EMISSIVE": true + } + }, + "40": { + "link": { + "name": "Foliage", + "file": "default" + } + }, + "41": { + "link": { + "name": "Particle", + "file": "default" + } + }, + "44": { + "link": { + "name": "Depth", + "file": "default" + } + }, + "47": { + "link": { + "name": "Physical Opaque", + "file": "default" + }, + "features": { + "SEPARATE_OCCLUSION_TEXTURE": true + } + }, + "48": { + "link": { + "name": "Physical Opaque Textured", + "file": "default" + }, + "features": { + "SEPARATE_OCCLUSION_TEXTURE": true + } + }, + "51": { + "link": { + "name": "Text", + "file": "default" + } + }, + "54": { + "link": { + "name": "Sky", + "file": "default" + }, + "features": { + "GRADIENT": true, + "TEXTURED": false, + "GRADIENT_4_STOPS": true, + "ENVIRONMENT_PROBE": false + } + }, + "66": { + "link": { + "name": "Phong Normalmapped", + "file": "default" + }, + "features": { + "WITH_EMISSIVE": true + } + }, + "67": { + "link": { + "name": "Phong Lightmapped", + "file": "default" + }, + "features": { + "WITH_EMISSIVE": true + } + }, + "74": { + "link": { + "name": "TileFeedback", + "file": "default" + } + }, + "88": { + "link": { + "name": "AtmosphericSky", + "file": "default" + } + }, + "89": { + "link": { + "name": "Color", + "file": "default" + } + }, + "90": { + "link": { + "name": "VertexColor", + "file": "default" + } + }, + "91": { + "link": { + "name": "CustomShader", + "file": "default" + }, + "blending": true, + "blendSrcRgb": "source alpha", + "blendDestAlpha": "one minus source alpha", + "blendDestRgb": "one minus source alpha", + "depthWrite": false + }, + "92": { + "link": { + "name": "CustomShader Textured", + "file": "default" + } + } + }, + "textures": {}, + "images": {}, + "fonts": { + "55": { + "link": { + "name": "DejaVuSans.ttf", + "file": "default" + } + } + }, + "languages": {}, + "files": {}, + "morphTargets": {}, + "audioClips": {}, + "shaderChunks": { + "1": { + "link": { + "name": "lib\\Color.glsl", + "file": "default" + } + }, + "2": { + "link": { + "name": "lib\\Compatibility.glsl", + "file": "default" + } + }, + "3": { + "link": { + "name": "lib\\CoordinateSystems.glsl", + "file": "default" + } + }, + "4": { + "link": { + "name": "lib\\GI.glsl", + "file": "default" + } + }, + "5": { + "link": { + "name": "lib\\Inputs.glsl", + "file": "default" + } + }, + "6": { + "link": { + "name": "lib\\Lights.glsl", + "file": "default" + } + }, + "7": { + "link": { + "name": "lib\\Materials.glsl", + "file": "default" + } + }, + "8": { + "link": { + "name": "lib\\Math.glsl", + "file": "default" + } + }, + "9": { + "link": { + "name": "lib\\MorphTargets.glsl", + "file": "default" + } + }, + "10": { + "link": { + "name": "lib\\Packing.glsl", + "file": "default" + } + }, + "11": { + "link": { + "name": "lib\\PhysicalBSDF.glsl", + "file": "default" + } + }, + "12": { + "link": { + "name": "lib\\Quaternion.glsl", + "file": "default" + } + }, + "13": { + "link": { + "name": "lib\\SkyProcedural.glsl", + "file": "default" + } + }, + "14": { + "link": { + "name": "lib\\Slug.frag.glsl", + "file": "default" + } + }, + "15": { + "link": { + "name": "lib\\Slug.vert.glsl", + "file": "default" + } + }, + "16": { + "link": { + "name": "lib\\Surface.glsl", + "file": "default" + } + }, + "17": { + "link": { + "name": "lib\\Textures.glsl", + "file": "default" + } + }, + "18": { + "link": { + "name": "lib\\Uniforms.glsl", + "file": "default" + } + } + }, + "particleEffects": {}, + "probeVolumeScenarios": {}, + "plugins": {} +} \ No newline at end of file diff --git a/custom-webgl/app.js b/custom-webgl/app.js new file mode 100644 index 0000000..87b196b --- /dev/null +++ b/custom-webgl/app.js @@ -0,0 +1,80 @@ +/** + * /!\ This file is auto-generated. + * + * This is the entry point of your standalone application. + * + * There are multiple tags used by the editor to inject code automatically: + * - `wle:auto-constants:start` and `wle:auto-constants:end`: The project's constants, + * such as the project's name, whether it should use the physx runtime, etc... + * - `wle:auto-benchmark:start` and `wle:auto-benchmark:end`: Append the benchmarking code + */ + +import {loadRuntime} from '@wonderlandengine/api'; + +/* wle:auto-constants:start */ +const Constants = { + ProjectName: 'CustomWebGL.wlp', + RuntimeBaseName: 'WonderlandRuntime', + WebXRRequiredFeatures: ['local',], + WebXROptionalFeatures: ['local','hand-tracking','hit-test',], +}; +const RuntimeOptions = { + webgl2: true, + webgpu: false, + physx: false, + loader: false, + xrFramebufferScaleFactor: 1, + loadUncompressedImagesAsBitmap: false, + xrOfferSession: { + mode: 'auto', + features: Constants.WebXRRequiredFeatures, + optionalFeatures: Constants.WebXROptionalFeatures, + }, + canvas: 'canvas', +}; +/* wle:auto-constants:end */ + +const engine = await loadRuntime(Constants.RuntimeBaseName, RuntimeOptions); +engine.onLoadingScreenEnd.once(() => { + const el = document.getElementById('version'); + if (el) setTimeout(() => el.remove(), 2000); +}); + +/* WebXR setup. */ + +function requestSession(mode) { + engine + .requestXRSession(mode, Constants.WebXRRequiredFeatures, Constants.WebXROptionalFeatures) + .catch((e) => console.error(e)); +} + +function setupButtonsXR() { + /* Setup AR / VR buttons */ + const arButton = document.getElementById('ar-button'); + if (arButton) { + arButton.setAttribute('data-supported', engine.arSupported.toString()); + arButton.addEventListener('click', () => requestSession('immersive-ar')); + } + const vrButton = document.getElementById('vr-button'); + if (vrButton) { + vrButton.setAttribute('data-supported', engine.vrSupported.toString()); + vrButton.addEventListener('click', () => requestSession('immersive-vr')); + } +} + +if (document.readyState === 'loading') { + window.addEventListener('load', setupButtonsXR); +} else { + setupButtonsXR(); +} + +/* Load main scene */ +try { + await engine.loadMainScene(`${Constants.ProjectName}.bin`); +} catch (e) { + console.error(e); + window.alert(`Failed to load ${Constants.ProjectName}.bin:`, e); +} + +/* wle:auto-benchmark:start */ +/* wle:auto-benchmark:end */ diff --git a/custom-webgl/js/custom-webgl.ts b/custom-webgl/js/custom-webgl.ts new file mode 100644 index 0000000..9280bf7 --- /dev/null +++ b/custom-webgl/js/custom-webgl.ts @@ -0,0 +1,63 @@ +import { Component, Pipeline, TextureManager } from "@wonderlandengine/api"; + +const TextureUnit = 6; + +export class CustomWebGL extends Component { + static TypeName = 'custom-webgl'; + + url = 'noise.png'; + + _gl: WebGL2RenderingContext | null = null; + _texture: WebGLTexture | null = null; + + _pipeline: Pipeline; + _ready = false; + + _draw = () => { + const gl = this._gl; + + const prevActive = gl.getParameter(gl.ACTIVE_TEXTURE); + gl.activeTexture(WebGL2RenderingContext.TEXTURE0 + TextureUnit); + gl.bindTexture(WebGL2RenderingContext.TEXTURE_2D, this._texture); + + if(!this._ready) { + const shader = this._pipeline.webglProgram; + gl.useProgram(shader); + const loc = gl.getUniformLocation(shader, 'customTexture'); + gl.uniform1i(loc, TextureUnit); + this._ready = true; + } + + /* This is required to avoid breaking the current active state in the engine */ + gl.activeTexture(prevActive); + }; + + async init() { + this._gl = this.engine.canvas.getContext('webgl2')!; + this._texture = this._gl.createTexture(); + + const img = await TextureManager.fetchImage(this.url, 'anonymous'); + + const gl = this._gl!; + gl.bindTexture(gl.TEXTURE_2D, this._texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + + onActivate(): void { + this._pipeline = this.engine.pipelines.findByName('CustomShader'); + this._pipeline.onPreRender.add(this._draw); + } + + onDeactivate(): void { + if (!this._pipeline) return; + this._pipeline.onPreRender.remove(this._draw); + } + + onDestroy(): void { + this._gl.deleteTexture(this._texture); + } +} \ No newline at end of file diff --git a/custom-webgl/js/index.js b/custom-webgl/js/index.js new file mode 100644 index 0000000..f7af1d7 --- /dev/null +++ b/custom-webgl/js/index.js @@ -0,0 +1,23 @@ +/** + * /!\ This file is auto-generated. + * + * This is the entry point of your standalone application. + * + * There are multiple tags used by the editor to inject code automatically: + * - `wle:auto-imports:start` and `wle:auto-imports:end`: The list of import statements + * - `wle:auto-register:start` and `wle:auto-register:end`: The list of component to register + */ + +/* wle:auto-imports:start */ +import {MouseLookComponent} from '@wonderlandengine/components'; +import {WasdControlsComponent} from '@wonderlandengine/components'; +import {CustomWebGL} from './custom-webgl.js'; +/* wle:auto-imports:end */ + +export default function(engine) { +/* wle:auto-register:start */ +engine.registerComponent(MouseLookComponent); +engine.registerComponent(WasdControlsComponent); +engine.registerComponent(CustomWebGL); +/* wle:auto-register:end */ +} diff --git a/custom-webgl/package.json b/custom-webgl/package.json new file mode 100644 index 0000000..473c23f --- /dev/null +++ b/custom-webgl/package.json @@ -0,0 +1,22 @@ +{ + "name": "default-scene", + "version": "1.0.0", + "description": "Wonderland Engine default template", + "main": "js/index.js", + "type": "module", + "module": "js/index.js", + "scripts": { + "build": "echo \"The 'build' script is run by the editor and should produce your application bundle\"" + }, + "keywords": [ + "wonderland-engine" + ], + "dependencies": { + "@wonderlandengine/api": "file:../../../wonderland-engine/js/api/packages/api", + "@wonderlandengine/components": "^1.2.1", + "gl-matrix": "^3.4.3" + }, + "overrides": { + "@wonderlandengine/api": "$@wonderlandengine/api" + } +} \ No newline at end of file diff --git a/custom-webgl/shaders/CustomShader.frag b/custom-webgl/shaders/CustomShader.frag new file mode 100644 index 0000000..058ab51 --- /dev/null +++ b/custom-webgl/shaders/CustomShader.frag @@ -0,0 +1,34 @@ +#include "lib/Compatibility.glsl" + +#define USE_TEXTURE_COORDS /* provides fragTextureCoords */ +#define USE_MATERIAL_ID /* provides fragMaterialId */ + +#include "lib/Inputs.glsl" +#include "lib/Packing.glsl" +#include "lib/Materials.glsl" + +uniform sampler2D customTexture; /* Binding 6 */ + +/* This structure is essential. Wonderland Editor will look + * for it and parse the material properties to generate UI + * from it. + * If a uint property ends with "*Texture", it will be regarded + * as a texture, only 2D textures are currently supported. */ +struct Material { + lowp vec4 color; +}; + +/* Wonderland Engine does some material packing magic and + * automatically generates the matching unpacking code + * if it finds this snippet in a shader. */ +Material decodeMaterial(uint matIndex) { + {{decoder}} + return mat; +} + +void main() { + Material mat = decodeMaterial(fragMaterialId); + vec4 tex = textureLod(customTexture, fragTextureCoords, 0.0); + outColor = tex * mat.color; + outColor.a = length(tex.rgb); +} diff --git a/custom-webgl/static/noise.png b/custom-webgl/static/noise.png new file mode 100644 index 0000000..0c285ee --- /dev/null +++ b/custom-webgl/static/noise.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2ba33582aa03c79b4618a8a746916a4e9252c2cf7e9f856184fca673f6ea2e4 +size 112236 diff --git a/custom-webgl/tsconfig.json b/custom-webgl/tsconfig.json new file mode 100644 index 0000000..1021dcb --- /dev/null +++ b/custom-webgl/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "nodenext", + "moduleResolution": "nodenext", + "experimentalDecorators": true, + }, + "include": [ "./**/*.ts" ], + "exclude": ["node_modules", "deploy"] +}