index-static/scripts/portal-min.js

2 lines
7.6 KiB
JavaScript

class Portal{constructor(t,e){const i=[`${"/"!==e?e:""}/sky.png`,`${"/"!==e?e:""}/portal.png`];this.version="1.1",this.notice(),this.canvas=t,this.gl=this.canvas.getContext("webgl2"),this.gl?(this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight,this.time=Date.now()-this.randomRange(6e4,18e4),this.prog=this.build("#version 300 es\n\n\t\tlayout (location = 0) in vec3 Position;\n\n\t\tuniform mat4 modelViewMatrix;\n\t\tuniform mat4 projectionMatrix;\n\t\t\n\t\tuniform vec2 canvasResolution;\n\n\t\tvec4 projection_from_position(vec4 position) {\n\t\t\tvec4 projection = position * 0.5;\n\t\t\tprojection.xy = vec2(projection.x + projection.w, projection.y + projection.w);\n\t\t\tprojection.zw = position.zw;\n\t\t\treturn projection;\n\t\t}\n\n\t\tout vec4 texProj0;\n\n\t\tvoid main() {\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4(Position, 1.0);\n\n\t\t\ttexProj0 = projection_from_position(gl_Position);\n\t\t\ttexProj0 = vec4(texProj0.xy * canvasResolution / max(canvasResolution.x, canvasResolution.y), texProj0.zw);\n\t\t}","#version 300 es\n\n\t\tprecision highp float;\n\n\t\tuniform sampler2D sky;\n\t\tuniform sampler2D particles;\n\t\tuniform float dt;\n\n\t\tin vec4 texProj0;\n\n\t\tconst int LAYERS = 15;\n\t\tconst vec3 COLORS[] = vec3[](\n\t\t\tvec3(0.022087, 0.098399, 0.110818),\n\t\t\tvec3(0.011892, 0.095924, 0.089485),\n\t\t\tvec3(0.027636, 0.101689, 0.100326),\n\t\t\tvec3(0.046564, 0.109883, 0.114838),\n\t\t\tvec3(0.064901, 0.117696, 0.097189),\n\t\t\tvec3(0.063761, 0.086895, 0.123646),\n\t\t\tvec3(0.084817, 0.111994, 0.166380),\n\t\t\tvec3(0.097489, 0.154120, 0.091064),\n\t\t\tvec3(0.106152, 0.131144, 0.195191),\n\t\t\tvec3(0.097721, 0.110188, 0.187229),\n\t\t\tvec3(0.133516, 0.138278, 0.148582),\n\t\t\tvec3(0.070006, 0.243332, 0.235792),\n\t\t\tvec3(0.196766, 0.142899, 0.214696),\n\t\t\tvec3(0.047281, 0.315338, 0.321970),\n\t\t\tvec3(0.204675, 0.390010, 0.302066),\n\t\t\tvec3(0.080955, 0.314821, 0.661491)\n\t\t);\n\n\t\tconst mat4 SCALE_TRANSLATE = mat4(\n\t\t\t0.5, 0.0, 0.0, 0.25,\n\t\t\t0.0, 0.5, 0.0, 0.25,\n\t\t\t0.0, 0.0, 1.0, 0.0,\n\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t);\n\n\t\tmat2 mat2_rotate_z(float radians) {\n\t\t\treturn mat2(\n\t\t\t\tcos(radians), -sin(radians),\n\t\t\t\tsin(radians), cos(radians)\n\t\t\t);\n\t\t}\n\n\t\tmat4 portal_layer(float layer) {\n\t\t\tmat4 translate = mat4(\n\t\t\t\t1.0, 0.0, 0.0, 17.0 / layer,\n\t\t\t\t0.0, 1.0, 0.0, (2.0 + layer / 1.5) * (dt * 1.5),\n\t\t\t\t0.0, 0.0, 1.0, 0.0,\n\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t);\n\n\t\t\tmat2 rotate = mat2_rotate_z(radians((layer * layer * 4321.0 + layer * 9.0) * 2.0));\n\n\t\t\tmat2 scale = mat2((4.5 - layer / 4.0) * 2.0);\n\n\t\t\treturn mat4(scale * rotate) * translate * SCALE_TRANSLATE;\n\t\t}\n\n\t\tout vec4 fragColor;\n\n\t\tvoid main() {\n\t\t\tvec3 color = textureProj(sky, texProj0).rgb * COLORS[0];\n\t\t\t\n\t\t\tfor (int i = 0; i < LAYERS; i++) {\n\t\t\t\tcolor += textureProj(particles, texProj0 * portal_layer(float(i + 1))).rgb * COLORS[i];\n\t\t\t}\n\t\t\t\n\t\t\tfragColor = vec4(color, 1.0);\n\t\t}"),this.prog?(window.addEventListener("resize",this.resize.bind(this)),this.promises=i.map((t=>this.loadImage(t))),this.initialize(),Promise.all(this.promises).then((t=>{t.forEach(((t,e)=>this.loadResource(t,e))),this.gl.useProgram(this.prog),this.render()}))):alert("Failed to compile WebGL 2 shaders.\nOpen the developer console for debug output.")):alert("Unable to initialize WebGL 2. Your browser or machine may not support it.")}notice(){console.log(`%c \u2587%c\u2587%c\u2587 %c\u2587%c\u2587%c\u2587 %c // ECMAPortal v${this.version} by Endermanch & WiPet\n\n\thttps://enderman.ch\n\thttps://go.enderman.ch/wipet`,"color: #E58EFF","color: #D52DFF","color: #E58EFF","color: #E58EFF","color: #D52DFF","color: #E58EFF","color: #008000"),console.log("If any errors occur below, please send a screenshot of them my way!\n\t%ccontact@enderman.ch","color: #87CEFA")}randomRange(t,e){return t=Math.ceil(t),e=Math.floor(e),Math.floor(Math.random()*(e-t+1))+t}build(t,e){let i=this.gl.createShader(this.gl.VERTEX_SHADER);if(this.gl.shaderSource(i,t),this.gl.compileShader(i),!this.gl.getShaderParameter(i,this.gl.COMPILE_STATUS))return console.error(this.gl.getShaderInfoLog(i)),!1;let r=this.gl.createShader(this.gl.FRAGMENT_SHADER);if(this.gl.shaderSource(r,e),this.gl.compileShader(r),!this.gl.getShaderParameter(r,this.gl.COMPILE_STATUS))return console.error(this.gl.getShaderInfoLog(r)),!1;let n=this.gl.createProgram();return this.gl.attachShader(n,i),this.gl.attachShader(n,r),this.gl.linkProgram(n),this.gl.getProgramParameter(n,this.gl.LINK_STATUS)?n:(console.error(this.gl.getProgramInfoLog(n)),!1)}loadImage(t){return new Promise(((e,i)=>{let r=new Image;r.onload=()=>e(r),r.onerror=i,r.src=t}))}loadResource(t,e){const i=[this.gl.CLAMP_TO_EDGE,this.gl.MIRRORED_REPEAT];let r=this.gl.createSampler();this.gl.samplerParameteri(r,this.gl.TEXTURE_WRAP_S,i[e]),this.gl.samplerParameteri(r,this.gl.TEXTURE_WRAP_T,i[e]),this.gl.samplerParameteri(r,this.gl.TEXTURE_WRAP_R,i[e]),this.gl.samplerParameteri(r,this.gl.TEXTURE_MIN_FILTER,this.gl.NEAREST_MIPMAP_LINEAR),this.gl.samplerParameteri(r,this.gl.TEXTURE_MAG_FILTER,this.gl.NEAREST),this.gl.bindSampler(e,r);let n=this.gl.createTexture();this.gl.activeTexture(this.gl.TEXTURE0+e),this.gl.bindTexture(this.gl.TEXTURE_2D,n),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,t),this.gl.generateMipmap(this.gl.TEXTURE_2D)}initialize(){this.uniforms={modelViewMatrix:this.gl.getUniformLocation(this.prog,"modelViewMatrix"),projectionMatrix:this.gl.getUniformLocation(this.prog,"projectionMatrix"),dt:this.gl.getUniformLocation(this.prog,"dt"),resolution:this.gl.getUniformLocation(this.prog,"canvasResolution"),sky:this.gl.getUniformLocation(this.prog,"sky"),particles:this.gl.getUniformLocation(this.prog,"particles")};let t=this.gl.createBuffer(),e=new Float32Array([-1,-1,1,-1,1,1,1,1,-1,1,-1,-1]);this.gl.bindBuffer(this.gl.ARRAY_BUFFER,t),this.gl.bufferData(this.gl.ARRAY_BUFFER,e,this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null);let i=this.gl.createBuffer(),r=new Float32Array([0,1,1,1,1,0,1,0,0,0,0,1]);this.gl.bindBuffer(this.gl.ARRAY_BUFFER,i),this.gl.bufferData(this.gl.ARRAY_BUFFER,r,this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null);this.gl.bindBuffer(this.gl.ARRAY_BUFFER,t),this.gl.vertexAttribPointer(0,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(0),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null);this.gl.bindBuffer(this.gl.ARRAY_BUFFER,i),this.gl.vertexAttribPointer(4,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(4),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)}scene(){let t=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e=(Date.now()-this.time)/1e3/1e3;this.gl.uniformMatrix4fv(this.uniforms.modelViewMatrix,!1,t),this.gl.uniformMatrix4fv(this.uniforms.projectionMatrix,!1,t),this.gl.uniform2f(this.uniforms.resolution,this.canvas.clientWidth,this.canvas.clientHeight),console.log(this.canvas.clientWidth,this.canvas.clientHeight),this.gl.uniform1f(this.uniforms.dt,e),this.gl.uniform1i(this.uniforms.sky,0),this.gl.uniform1i(this.uniforms.particles,1),this.gl.drawArraysInstanced(this.gl.TRIANGLES,0,6,1)}render(){this.gl.viewport(0,0,this.gl.drawingBufferWidth,this.gl.drawingBufferHeight),this.scene(),requestAnimationFrame(this.render.bind(this))}resize(){let t=window.innerWidth,e=window.innerHeight;this.canvas.width===t&&this.canvas.height===e||(this.canvas.width=t,this.canvas.height=e)}destruct(){this.gl.deleteBuffer(vertexPosBuffer),this.gl.deleteBuffer(vertexTexBuffer),this.gl.deleteSampler(sampler),this.gl.deleteTexture(texture),this.gl.deleteProgram(this.prog)}}const canvas=document.querySelector("#ecmaportal"),portal=new Portal(canvas,"/images/portal");