Comparing version 1.0.0 to 1.0.1
1560
dist/index.js
@@ -1,1560 +0,2 @@ | ||
module.exports = | ||
/******/ (function(modules) { // webpackBootstrap | ||
/******/ // The module cache | ||
/******/ var installedModules = {}; | ||
/******/ | ||
/******/ // The require function | ||
/******/ function __webpack_require__(moduleId) { | ||
/******/ | ||
/******/ // Check if module is in cache | ||
/******/ if(installedModules[moduleId]) { | ||
/******/ return installedModules[moduleId].exports; | ||
/******/ } | ||
/******/ // Create a new module (and put it into the cache) | ||
/******/ var module = installedModules[moduleId] = { | ||
/******/ i: moduleId, | ||
/******/ l: false, | ||
/******/ exports: {} | ||
/******/ }; | ||
/******/ | ||
/******/ // Execute the module function | ||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
/******/ | ||
/******/ // Flag the module as loaded | ||
/******/ module.l = true; | ||
/******/ | ||
/******/ // Return the exports of the module | ||
/******/ return module.exports; | ||
/******/ } | ||
/******/ | ||
/******/ | ||
/******/ // expose the modules object (__webpack_modules__) | ||
/******/ __webpack_require__.m = modules; | ||
/******/ | ||
/******/ // expose the module cache | ||
/******/ __webpack_require__.c = installedModules; | ||
/******/ | ||
/******/ // define getter function for harmony exports | ||
/******/ __webpack_require__.d = function(exports, name, getter) { | ||
/******/ if(!__webpack_require__.o(exports, name)) { | ||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); | ||
/******/ } | ||
/******/ }; | ||
/******/ | ||
/******/ // define __esModule on exports | ||
/******/ __webpack_require__.r = function(exports) { | ||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { | ||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); | ||
/******/ } | ||
/******/ Object.defineProperty(exports, '__esModule', { value: true }); | ||
/******/ }; | ||
/******/ | ||
/******/ // create a fake namespace object | ||
/******/ // mode & 1: value is a module id, require it | ||
/******/ // mode & 2: merge all properties of value into the ns | ||
/******/ // mode & 4: return value when already ns object | ||
/******/ // mode & 8|1: behave like require | ||
/******/ __webpack_require__.t = function(value, mode) { | ||
/******/ if(mode & 1) value = __webpack_require__(value); | ||
/******/ if(mode & 8) return value; | ||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; | ||
/******/ var ns = Object.create(null); | ||
/******/ __webpack_require__.r(ns); | ||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); | ||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); | ||
/******/ return ns; | ||
/******/ }; | ||
/******/ | ||
/******/ // getDefaultExport function for compatibility with non-harmony modules | ||
/******/ __webpack_require__.n = function(module) { | ||
/******/ var getter = module && module.__esModule ? | ||
/******/ function getDefault() { return module['default']; } : | ||
/******/ function getModuleExports() { return module; }; | ||
/******/ __webpack_require__.d(getter, 'a', getter); | ||
/******/ return getter; | ||
/******/ }; | ||
/******/ | ||
/******/ // Object.prototype.hasOwnProperty.call | ||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | ||
/******/ | ||
/******/ // __webpack_public_path__ | ||
/******/ __webpack_require__.p = ""; | ||
/******/ | ||
/******/ | ||
/******/ // Load entry module and return exports | ||
/******/ return __webpack_require__(__webpack_require__.s = "./lib/index.ts"); | ||
/******/ }) | ||
/************************************************************************/ | ||
/******/ ({ | ||
/***/ "./lib/attributes.ts": | ||
/*!***************************!*\ | ||
!*** ./lib/attributes.ts ***! | ||
\***************************/ | ||
/*! no static exports found */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/** | ||
* @fileoverview Shader attributes module. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Mat4Attribute = exports.Mat3Attribute = exports.Mat2Attribute = exports.Vec4Attribute = exports.Vec3Attribute = exports.Vec2Attribute = exports.FloatAttribute = exports.Attribute = void 0; | ||
const gl_1 = __webpack_require__(/*! ./gl */ "./lib/gl.ts"); | ||
/** | ||
* Abstraction for sending data to shaders in attributes. | ||
*/ | ||
class Attribute { | ||
constructor(name_, dimension_, data_) { | ||
this.name_ = name_; | ||
this.dimension_ = dimension_; | ||
this.data_ = data_; | ||
if (Array.isArray(this.data_) && !isNaN(this.data_[0])) { | ||
this.data_ = new Float32Array(this.data_); | ||
} | ||
} | ||
send(gl, program) { | ||
if (!this.buffer_) | ||
this.buffer_ = gl.createBuffer(); | ||
gl_1.sendAttribute(gl, program, this.buffer_, this.name_, this.data_, this.dimension_); | ||
} | ||
length() { | ||
if (this.data_ instanceof Float32Array) { | ||
let result = this.data_.byteLength / this.data_.BYTES_PER_ELEMENT; | ||
result /= this.dimension_; | ||
return result; | ||
} | ||
else { | ||
return this.data_.length / this.dimension_; | ||
} | ||
} | ||
} | ||
exports.Attribute = Attribute; | ||
/** | ||
* Returns an attribute builder function for the appropriate type. | ||
*/ | ||
const attribute = (dimension) => (name, data) => new Attribute(name, dimension, data); | ||
/** | ||
* Sends a float attribute to a shader. | ||
*/ | ||
exports.FloatAttribute = attribute(1); | ||
/** | ||
* Sends a 2-dimensional vector attribute to a shader. | ||
*/ | ||
exports.Vec2Attribute = attribute(2); | ||
/** | ||
* Sends a 3-dimensional vector attribute to a shader. | ||
*/ | ||
exports.Vec3Attribute = attribute(3); | ||
/** | ||
* Sends a 4-dimensional vector attribute to a shader. | ||
*/ | ||
exports.Vec4Attribute = attribute(4); | ||
class MatrixAttribute extends Attribute { | ||
constructor(name, dimension, data) { | ||
super(name, dimension, data); | ||
if (Array.isArray(data[0]) && Array.isArray(data[0][0])) { | ||
this.data_ = this.data_.map((arr) => new Float32Array(arr)); | ||
} | ||
} | ||
send(gl, program) { | ||
if (!this.buffer_) | ||
this.buffer_ = gl.createBuffer(); | ||
gl_1.sendMatrixAttribute(gl, program, this.buffer_, this.name_, this.data_, this.dimension_); | ||
} | ||
} | ||
const matrixAttribute = (dimension) => (name, data) => new MatrixAttribute(name, dimension, data); | ||
/** | ||
* Sends a 2-dimensional matrix attribute to a shader. | ||
*/ | ||
exports.Mat2Attribute = matrixAttribute(2); | ||
/** | ||
* Sends a 3-dimensional matrix attribute to a shader. | ||
*/ | ||
exports.Mat3Attribute = matrixAttribute(3); | ||
/** | ||
* Sends a 4-dimensional matrix attribute to a shader. | ||
*/ | ||
exports.Mat4Attribute = matrixAttribute(4); | ||
/***/ }), | ||
/***/ "./lib/constants.ts": | ||
/*!**************************!*\ | ||
!*** ./lib/constants.ts ***! | ||
\**************************/ | ||
/*! no static exports found */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/** | ||
* @fileoverview Constants exported by the library. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CUBE_NORMALS = exports.CUBE_TEX_COORDS = exports.CUBE_INDICES = exports.CUBE_VERTICES = exports.PLANE_TEX_COORDS = exports.PLANE_VERTICES = void 0; | ||
/** | ||
* Full-view plane vertex coordinates. | ||
* | ||
* Can be rendered using drawArrays() with | ||
* WebGLRenderingContext.TRIANGLE_STRIP. | ||
* | ||
* Order of elements is always: | ||
* upper left, | ||
* upper right, | ||
* lower left, | ||
* lower right. | ||
*/ | ||
exports.PLANE_VERTICES = new Float32Array([-1, 1, 1, 1, -1, -1, 1, -1]); | ||
exports.PLANE_TEX_COORDS = new Float32Array([0, 1, 1, 1, 0, 0, 1, 0]); | ||
/** | ||
* Cube vertex coordinates. | ||
* | ||
* Can be rendered using drawElements() with | ||
* WebGLRenderingContext.TRIANGLES | ||
*/ | ||
exports.CUBE_VERTICES = new Float32Array([ | ||
// Front face | ||
-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 face | ||
-1.0, -1.0, -1.0, | ||
-1.0, 1.0, -1.0, | ||
1.0, 1.0, -1.0, | ||
1.0, -1.0, -1.0, | ||
// Top face | ||
-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 face | ||
-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 face | ||
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 face | ||
-1.0, -1.0, -1.0, | ||
-1.0, -1.0, 1.0, | ||
-1.0, 1.0, 1.0, | ||
-1.0, 1.0, -1.0, | ||
]); | ||
exports.CUBE_INDICES = new Uint16Array([ | ||
0, 1, 2, 0, 2, 3, | ||
4, 5, 6, 4, 6, 7, | ||
8, 9, 10, 8, 10, 11, | ||
12, 13, 14, 12, 14, 15, | ||
16, 17, 18, 16, 18, 19, | ||
20, 21, 22, 20, 22, 23, | ||
]); | ||
exports.CUBE_TEX_COORDS = new Float32Array([ | ||
// Front | ||
0.0, 0.0, | ||
1.0, 0.0, | ||
1.0, 1.0, | ||
0.0, 1.0, | ||
// Back | ||
0.0, 0.0, | ||
1.0, 0.0, | ||
1.0, 1.0, | ||
0.0, 1.0, | ||
// Top | ||
0.0, 0.0, | ||
1.0, 0.0, | ||
1.0, 1.0, | ||
0.0, 1.0, | ||
// Bottom | ||
0.0, 0.0, | ||
1.0, 0.0, | ||
1.0, 1.0, | ||
0.0, 1.0, | ||
// Right | ||
0.0, 0.0, | ||
1.0, 0.0, | ||
1.0, 1.0, | ||
0.0, 1.0, | ||
// Left | ||
0.0, 0.0, | ||
1.0, 0.0, | ||
1.0, 1.0, | ||
0.0, 1.0, | ||
]); | ||
exports.CUBE_NORMALS = new Float32Array([ | ||
// Front | ||
0.0, 0.0, 1.0, | ||
0.0, 0.0, 1.0, | ||
0.0, 0.0, 1.0, | ||
0.0, 0.0, 1.0, | ||
// Back | ||
0.0, 0.0, -1.0, | ||
0.0, 0.0, -1.0, | ||
0.0, 0.0, -1.0, | ||
0.0, 0.0, -1.0, | ||
// Top | ||
0.0, 1.0, 0.0, | ||
0.0, 1.0, 0.0, | ||
0.0, 1.0, 0.0, | ||
0.0, 1.0, 0.0, | ||
// Bottom | ||
0.0, -1.0, 0.0, | ||
0.0, -1.0, 0.0, | ||
0.0, -1.0, 0.0, | ||
0.0, -1.0, 0.0, | ||
// Right | ||
1.0, 0.0, 0.0, | ||
1.0, 0.0, 0.0, | ||
1.0, 0.0, 0.0, | ||
1.0, 0.0, 0.0, | ||
// Left | ||
-1.0, 0.0, 0.0, | ||
-1.0, 0.0, 0.0, | ||
-1.0, 0.0, 0.0, | ||
-1.0, 0.0, 0.0 | ||
]); | ||
/***/ }), | ||
/***/ "./lib/gl.ts": | ||
/*!*******************!*\ | ||
!*** ./lib/gl.ts ***! | ||
\*******************/ | ||
/*! no static exports found */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/** | ||
* @fileoverview Module for GL context related operations. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.glRender = exports.cubeTextureFromFramebuffer = exports.texture2DFromFramebuffer = exports.renderBuffer = exports.sendCubeTexture = exports.send2DTexture = exports.cubeTexure = exports.texture2d = exports.isVideo = exports.newTextureOffset = exports.sendVectorUniform = exports.sendMatrixUniform = exports.sendBytesUniform = exports.UniformType = exports.sendMatrixAttribute = exports.sendAttribute = exports.sendIndices = exports.glProgram = exports.glContext = void 0; | ||
const math_1 = __webpack_require__(/*! ./math */ "./lib/math.ts"); | ||
/** | ||
* Get the current WebGL context. | ||
* If this is the first time you | ||
*/ | ||
exports.glContext = (canvas) => { | ||
const gl = canvas.getContext('webgl', { preserveDrawingBuffer: true }) | ||
|| canvas.getContext('experimental-webgl', { preserveDrawingBuffer: true }); | ||
gl.enable(gl.DEPTH_TEST); | ||
gl.depthFunc(gl.LEQUAL); | ||
return gl; | ||
}; | ||
/** | ||
* Compile one of the shaders. | ||
*/ | ||
const compileShader = (gl, shader, src) => { | ||
gl.shaderSource(shader, src); | ||
gl.compileShader(shader); | ||
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { | ||
throw new Error(`Shader failed to compile: ${gl.getShaderInfoLog(shader)}`); | ||
} | ||
return shader; | ||
}; | ||
/** | ||
* Create and compile a shader program. | ||
*/ | ||
exports.glProgram = (gl, vertexSrc, fragmentSrc) => { | ||
const vertexShader = compileShader(gl, gl.createShader(WebGLRenderingContext.VERTEX_SHADER), vertexSrc); | ||
const fragmentShader = compileShader(gl, gl.createShader(WebGLRenderingContext.FRAGMENT_SHADER), fragmentSrc); | ||
const result = gl.createProgram(); | ||
gl.attachShader(result, vertexShader); | ||
gl.attachShader(result, fragmentShader); | ||
gl.linkProgram(result); | ||
if (!gl.getProgramParameter(result, gl.LINK_STATUS)) { | ||
throw new Error(`Shader failed to compile: ${gl.getProgramInfoLog(result)}`); | ||
} | ||
return result; | ||
}; | ||
/** | ||
* Send indices to the element array buffer. | ||
*/ | ||
exports.sendIndices = (gl, indices) => { | ||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer()); | ||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); | ||
}; | ||
/** | ||
* Send an attribute to a shader's array buffer. | ||
*/ | ||
exports.sendAttribute = (gl, program, buffer, name, data, size) => { | ||
const loc = gl.getAttribLocation(program, name); | ||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | ||
gl.vertexAttribPointer(loc, size, gl.FLOAT, false, 0, 0); | ||
gl.enableVertexAttribArray(loc); | ||
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); | ||
}; | ||
/** | ||
* Send a matrix attribute to a shader's array buffer. | ||
* | ||
* Matrix attributes are sent as vectors in column-major | ||
* order. Each element in "data" is the data for one column | ||
* for each vertex. | ||
*/ | ||
exports.sendMatrixAttribute = (gl, program, buffer, name, data, dimension) => { | ||
const loc = gl.getAttribLocation(program, name); | ||
for (let i = 0; i < dimension; i++) { | ||
gl.enableVertexAttribArray(loc + i); | ||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | ||
gl.bufferData(gl.ARRAY_BUFFER, data[i], gl.STATIC_DRAW); | ||
gl.vertexAttribPointer(loc + i, dimension, gl.FLOAT, false, 0, 0); | ||
} | ||
}; | ||
/** | ||
* Different possible types of uniforms. | ||
*/ | ||
var UniformType; | ||
(function (UniformType) { | ||
UniformType["BOOLEAN"] = "boolean"; | ||
UniformType["FLOAT"] = "float"; | ||
UniformType["INTEGER"] = "integer"; | ||
UniformType["VECTOR"] = "vector"; | ||
UniformType["MATRIX"] = "matrix"; | ||
UniformType["TEXTURE"] = "texture"; | ||
})(UniformType = exports.UniformType || (exports.UniformType = {})); | ||
/** | ||
* Send a uniform to a shader that can be represented | ||
* with just a few bytes (boolean, float, integer). | ||
*/ | ||
exports.sendBytesUniform = (gl, program, name, type, data) => { | ||
const loc = gl.getUniformLocation(program, name); | ||
switch (type) { | ||
case UniformType.BOOLEAN: | ||
gl.uniform1i(loc, data); | ||
break; | ||
case UniformType.FLOAT: | ||
gl.uniform1f(loc, data); | ||
break; | ||
case UniformType.INTEGER: | ||
gl.uniform1i(loc, data); | ||
break; | ||
default: | ||
throw new Error(`Unexpected uniform type: ${type}`); | ||
} | ||
}; | ||
/** | ||
* Sends a vector uniform to a shader. | ||
*/ | ||
exports.sendMatrixUniform = (gl, program, name, dimension, data) => { | ||
const loc = gl.getUniformLocation(program, name); | ||
switch (dimension) { | ||
case 2: | ||
gl.uniformMatrix2fv(loc, false, data); | ||
break; | ||
case 3: | ||
gl.uniformMatrix3fv(loc, false, data); | ||
break; | ||
case 4: | ||
gl.uniformMatrix4fv(loc, false, data); | ||
break; | ||
} | ||
}; | ||
/** | ||
* Sends a vector uniform to a shader. | ||
*/ | ||
exports.sendVectorUniform = (gl, program, name, dimension, data) => { | ||
const loc = gl.getUniformLocation(program, name); | ||
switch (dimension) { | ||
case 2: | ||
gl.uniform2fv(loc, data); | ||
break; | ||
case 3: | ||
gl.uniform3fv(loc, data); | ||
break; | ||
case 4: | ||
gl.uniform4fv(loc, data); | ||
break; | ||
default: | ||
throw new Error(`Unexpected dimension: ${dimension}`); | ||
} | ||
}; | ||
const textureOffsets = new WeakMap(); | ||
/** | ||
* Get the next available address for textures. | ||
*/ | ||
exports.newTextureOffset = (program, name) => { | ||
const offsets = textureOffsets.get(program) || []; | ||
for (let i = 0; i < offsets.length; i++) { | ||
if (offsets[i] === name) | ||
return i; | ||
} | ||
const curOffset = offsets.length; | ||
if (curOffset === 32) { | ||
throw new Error('Already at maximum number of textures for this program'); | ||
} | ||
offsets.push(name); | ||
if (!curOffset) | ||
textureOffsets.set(program, offsets); | ||
return curOffset; | ||
}; | ||
/** | ||
* Get if texture data is for a video source. | ||
*/ | ||
exports.isVideo = (data) => { | ||
if (math_1.isCube(data)) { | ||
return Object.keys(data).some((k) => data[k] instanceof HTMLVideoElement); | ||
} | ||
return data instanceof HTMLVideoElement; | ||
}; | ||
/** | ||
* Create a 2D texture with the provided data. | ||
*/ | ||
exports.texture2d = (gl, data) => { | ||
const texture = gl.createTexture(); | ||
gl.bindTexture(gl.TEXTURE_2D, texture); | ||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, data); | ||
if (!exports.isVideo(data) && math_1.isPowerOfTwo(data.width) && math_1.isPowerOfTwo(data.height)) { | ||
gl.generateMipmap(gl.TEXTURE_2D); | ||
} | ||
else { | ||
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); | ||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); | ||
} | ||
return texture; | ||
}; | ||
const glTexCubeMapFaces = { | ||
posx: WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_X, | ||
negx: WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_X, | ||
posy: WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_Y, | ||
negy: WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_Y, | ||
posz: WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_Z, | ||
negz: WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_Z, | ||
}; | ||
const cubeFacesArePowersOfTwo = (data) => { | ||
for (const cf of math_1.cubeFaces()) { | ||
if (!math_1.isPowerOfTwo(data[cf].width) || !math_1.isPowerOfTwo(data[cf].height)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
/** | ||
* Create a cube texture with the provided data. | ||
*/ | ||
exports.cubeTexure = (gl, data) => { | ||
const texture = gl.createTexture(); | ||
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); | ||
for (const cf of math_1.cubeFaces()) { | ||
gl.texImage2D(glTexCubeMapFaces[cf], 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, data[cf]); | ||
} | ||
if (!exports.isVideo(data) && cubeFacesArePowersOfTwo(data)) { | ||
gl.generateMipmap(gl.TEXTURE_CUBE_MAP); | ||
} | ||
else { | ||
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); | ||
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); | ||
} | ||
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); | ||
return texture; | ||
}; | ||
const sendTexture = (target) => (gl, program, name, offset, texture) => { | ||
const loc = gl.getUniformLocation(program, name); | ||
gl.uniform1i(loc, offset); | ||
gl.activeTexture(gl.TEXTURE0 + offset); | ||
gl.bindTexture(target, texture); | ||
}; | ||
/** | ||
* Send a 2D texture as a uniform to a shader. | ||
*/ | ||
exports.send2DTexture = sendTexture(WebGLRenderingContext.TEXTURE_2D); | ||
/** | ||
* Send a cube texture as a uniform to a shader. | ||
*/ | ||
exports.sendCubeTexture = sendTexture(WebGLRenderingContext.TEXTURE_CUBE_MAP); | ||
/** | ||
* Creates a render buffer from a given frame buffer. | ||
*/ | ||
exports.renderBuffer = (gl, fBuffer, width, height) => { | ||
const rBuffer = gl.createRenderbuffer(); | ||
gl.bindFramebuffer(gl.FRAMEBUFFER, fBuffer); | ||
gl.bindRenderbuffer(gl.RENDERBUFFER, rBuffer); | ||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); | ||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rBuffer); | ||
return rBuffer; | ||
}; | ||
/** | ||
* Create a 2D texture that will sample from a framebuffer. | ||
*/ | ||
exports.texture2DFromFramebuffer = (gl, frameBuffer, width, height) => { | ||
const texture = gl.createTexture(); | ||
gl.bindTexture(gl.TEXTURE_2D, texture); | ||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_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); | ||
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); | ||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); | ||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); | ||
return texture; | ||
}; | ||
/** | ||
* Generate a cube texture which will sample from a cube of framebuffers. | ||
*/ | ||
exports.cubeTextureFromFramebuffer = (gl, frameBuffers, width, height) => { | ||
const texture = gl.createTexture(); | ||
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); | ||
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); | ||
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); | ||
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); | ||
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); | ||
for (const cf of math_1.cubeFaces()) { | ||
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffers[cf]); | ||
gl.texImage2D(glTexCubeMapFaces[cf], 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); | ||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, glTexCubeMapFaces[cf], texture, 0); | ||
} | ||
return texture; | ||
}; | ||
/** | ||
* Draws primitives to the bound buffers. | ||
*/ | ||
exports.glRender = (gl, nVertices, clear, viewport, mode, drawElements) => { | ||
gl.clearColor(0, 0, 0, 1); | ||
if (clear) { | ||
gl.clearDepth(gl.getParameter(gl.DEPTH_CLEAR_VALUE)); | ||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); | ||
} | ||
gl.viewport(...viewport); | ||
if (drawElements) { | ||
gl.drawElements(mode, nVertices, gl.UNSIGNED_SHORT, 0); | ||
} | ||
else { | ||
gl.drawArrays(mode, 0, nVertices); | ||
} | ||
}; | ||
/***/ }), | ||
/***/ "./lib/index.ts": | ||
/*!**********************!*\ | ||
!*** ./lib/index.ts ***! | ||
\**********************/ | ||
/*! no static exports found */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/** | ||
* @fileoverview Lib's main export script. | ||
*/ | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var attributes_1 = __webpack_require__(/*! ./attributes */ "./lib/attributes.ts"); | ||
Object.defineProperty(exports, "FloatAttribute", { enumerable: true, get: function () { return attributes_1.FloatAttribute; } }); | ||
Object.defineProperty(exports, "Mat2Attribute", { enumerable: true, get: function () { return attributes_1.Mat2Attribute; } }); | ||
Object.defineProperty(exports, "Mat3Attribute", { enumerable: true, get: function () { return attributes_1.Mat3Attribute; } }); | ||
Object.defineProperty(exports, "Mat4Attribute", { enumerable: true, get: function () { return attributes_1.Mat4Attribute; } }); | ||
Object.defineProperty(exports, "Vec2Attribute", { enumerable: true, get: function () { return attributes_1.Vec2Attribute; } }); | ||
Object.defineProperty(exports, "Vec3Attribute", { enumerable: true, get: function () { return attributes_1.Vec3Attribute; } }); | ||
Object.defineProperty(exports, "Vec4Attribute", { enumerable: true, get: function () { return attributes_1.Vec4Attribute; } }); | ||
__exportStar(__webpack_require__(/*! ./constants */ "./lib/constants.ts"), exports); | ||
__exportStar(__webpack_require__(/*! ./shader */ "./lib/shader.ts"), exports); | ||
var uniforms_1 = __webpack_require__(/*! ./uniforms */ "./lib/uniforms.ts"); | ||
Object.defineProperty(exports, "BooleanUniform", { enumerable: true, get: function () { return uniforms_1.BooleanUniform; } }); | ||
Object.defineProperty(exports, "CubeCameraUniform", { enumerable: true, get: function () { return uniforms_1.CubeCameraUniform; } }); | ||
Object.defineProperty(exports, "CubeTextureUniform", { enumerable: true, get: function () { return uniforms_1.CubeTextureUniform; } }); | ||
Object.defineProperty(exports, "FloatUniform", { enumerable: true, get: function () { return uniforms_1.FloatUniform; } }); | ||
Object.defineProperty(exports, "IntegerUniform", { enumerable: true, get: function () { return uniforms_1.IntegerUniform; } }); | ||
Object.defineProperty(exports, "Mat2Uniform", { enumerable: true, get: function () { return uniforms_1.Mat2Uniform; } }); | ||
Object.defineProperty(exports, "Mat3Uniform", { enumerable: true, get: function () { return uniforms_1.Mat3Uniform; } }); | ||
Object.defineProperty(exports, "Mat4Uniform", { enumerable: true, get: function () { return uniforms_1.Mat4Uniform; } }); | ||
Object.defineProperty(exports, "ModelMatUniform", { enumerable: true, get: function () { return uniforms_1.ModelMatUniform; } }); | ||
Object.defineProperty(exports, "NormalMatUniform", { enumerable: true, get: function () { return uniforms_1.NormalMatUniform; } }); | ||
Object.defineProperty(exports, "PerspectiveMatUniform", { enumerable: true, get: function () { return uniforms_1.PerspectiveMatUniform; } }); | ||
Object.defineProperty(exports, "Texture2DUniform", { enumerable: true, get: function () { return uniforms_1.Texture2DUniform; } }); | ||
Object.defineProperty(exports, "Vec2Uniform", { enumerable: true, get: function () { return uniforms_1.Vec2Uniform; } }); | ||
Object.defineProperty(exports, "Vec3Uniform", { enumerable: true, get: function () { return uniforms_1.Vec3Uniform; } }); | ||
Object.defineProperty(exports, "Vec4Uniform", { enumerable: true, get: function () { return uniforms_1.Vec4Uniform; } }); | ||
Object.defineProperty(exports, "ViewMatUniform", { enumerable: true, get: function () { return uniforms_1.ViewMatUniform; } }); | ||
/***/ }), | ||
/***/ "./lib/math.ts": | ||
/*!*********************!*\ | ||
!*** ./lib/math.ts ***! | ||
\*********************/ | ||
/*! no static exports found */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/** | ||
* @fileoverview Math module contains utility methods. | ||
* | ||
* All exported functions from this module should be pure functions. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.cube = exports.isCube = exports.cubeFaces = exports.perspective = exports.lookAt = exports.rotate = exports.scale = exports.translate = exports.multiply = exports.identity = exports.add = exports.isVector3 = exports.isPowerOfTwo = void 0; | ||
/** | ||
* Returns if a number is a power of two. | ||
*/ | ||
exports.isPowerOfTwo = (n) => ((n & (n - 1)) === 0); | ||
/** | ||
* Checks if an object is a Vector3. | ||
*/ | ||
exports.isVector3 = (obj) => Array.isArray(obj) && obj.length === 3 && obj.every(x => !isNaN(x)); | ||
const normalize = (v) => { | ||
const len = Math.hypot(...v); | ||
if (!len) { | ||
throw new Error('Cannot normalize a vector with no length'); | ||
} | ||
return v.map(x => x / len); | ||
}; | ||
/** | ||
* Add two vectors. | ||
*/ | ||
exports.add = (a, b) => a.map((cur, i) => cur + b[i]); | ||
const subtract = (a, b) => a.map((cur, i) => cur - b[i]); | ||
const dot = (a, b) => a.reduce((acc, cur, i) => acc + (cur * b[i]), 0); | ||
const cross = (a, b) => [ | ||
(a[1] * b[2]) - (a[2] * b[1]), | ||
(a[2] * b[0]) - (a[0] * b[2]), | ||
(a[0] * b[1]) - (a[1] * b[0]), | ||
]; | ||
const matDimension = (arr) => Math.sqrt(arr.length); | ||
const vecDimension = (arr) => arr.length; | ||
const zeros = (dim) => [...Array(Math.pow(dim, 2))].map(() => 0); | ||
const zeroVector = (dim) => [...Array(dim)].map(() => 0); | ||
/** | ||
* Initialize an identity matrix with the provided dimension. | ||
*/ | ||
exports.identity = (dim) => { | ||
const M = zeros(dim); | ||
for (let i = 0; i < dim; i++) { | ||
M[(i * dim) + i] = 1; | ||
} | ||
return M; | ||
}; | ||
const multiplyM = (A, B, d) => { | ||
const result = zeros(d); | ||
for (let i = 0; i < d; i++) | ||
for (let j = 0; j < d; j++) | ||
for (let k = 0; k < d; k++) { | ||
result[(d * i) + j] += A[(d * i) + k] * B[(d * k) + j]; | ||
} | ||
return result; | ||
}; | ||
const multiplyMv = (A, b, d) => { | ||
const result = zeroVector(d); | ||
for (let i = 0; i < d; i++) | ||
for (let j = 0; j < d; j++) { | ||
result[i] += A[(i * d) + j] * b[j]; | ||
} | ||
return result; | ||
}; | ||
/** | ||
* Can be used for matrix-matrix and matrix-vector multiplication. | ||
*/ | ||
exports.multiply = (A, B) => { | ||
const d = matDimension(A); | ||
if (d !== matDimension(B)) { | ||
if (d !== vecDimension(B)) { | ||
throw new Error('Cannot multiply, incompatible dimensions'); | ||
} | ||
return multiplyMv(A, B, d); | ||
} | ||
return multiplyM(A, B, d); | ||
}; | ||
/** | ||
* Apply a 3D transmation to a 4-dimensional matrix, M. | ||
*/ | ||
exports.translate = (M, x, y, z) => { | ||
const result = M.slice(0, 16); | ||
result[12] += x; | ||
result[13] += y; | ||
result[14] += z; | ||
return result; | ||
}; | ||
/** | ||
* Apply a scale transformation to a matrix. | ||
*/ | ||
exports.scale = (A, ...args) => { | ||
if (!args.length) { | ||
throw new Error('You must provide at least one number to scale a matrix'); | ||
} | ||
const d = matDimension(A); | ||
if (d === 4 && args.length === 2) { | ||
throw new Error('You must provide 1, 3, or 4 arguments to scale for a 4D matrix'); | ||
} | ||
const S = exports.identity(d); | ||
for (let i = 0; i < d; i++) { | ||
if (i === 3 && exports.scale.length < 4) { | ||
S[(d * i) + i] = 1; | ||
} | ||
else { | ||
S[(d * i) + i] = Number(isNaN(args[i]) ? args[0] : args[i]); | ||
} | ||
} | ||
return exports.multiply(S, A); | ||
}; | ||
const quatToRotationMat = (q) => [ | ||
// first column | ||
1 - (2 * ((Math.pow(q[2], 2)) + (Math.pow(q[3], 2)))), | ||
2 * ((q[1] * q[2]) + (q[3] * q[0])), | ||
2 * ((q[1] * q[3]) - (q[2] * q[0])), | ||
// second column | ||
2 * ((q[1] * q[2]) - (q[3] * q[0])), | ||
1 - (2 * ((Math.pow(q[1], 2)) + (Math.pow(q[3], 2)))), | ||
2 * ((q[2] * q[3]) + (q[1] * q[0])), | ||
// third column | ||
2 * ((q[1] * q[3]) + (q[2] * q[0])), | ||
2 * ((q[2] * q[3]) - (q[1] * q[0])), | ||
1 - (2 * ((Math.pow(q[1], 2)) + (Math.pow(q[2], 2)))), | ||
]; | ||
const rotate2 = (M, theta) => { | ||
const c = Math.cos(theta); | ||
const s = Math.sin(theta); | ||
return exports.multiply([c, s, c, -s], M); | ||
}; | ||
/** | ||
* Apply a 3D rotation of theta radians around the given axis | ||
* to a 4D matrix. | ||
*/ | ||
exports.rotate = (A, theta, ...axis) => { | ||
if (isNaN(theta)) { | ||
throw new Error('Expected a number as a 2nd argument'); | ||
} | ||
const d = matDimension(A); | ||
if (d === 2) | ||
return rotate2(A, theta); | ||
axis = axis.slice(0, 3); | ||
if (!exports.isVector3(axis)) { | ||
throw new Error('Expected numeric 3rd, 4th, and 5th argument'); | ||
} | ||
axis = normalize(axis); | ||
const s = Math.sin(theta / 2); | ||
const q = [ | ||
Math.cos(theta / 2), | ||
axis[0] * s, | ||
axis[1] * s, | ||
axis[2] * s, | ||
]; | ||
const R = quatToRotationMat(q); | ||
if (d === 3) | ||
return exports.multiply(A, R); | ||
const R4 = [ | ||
R[0], R[1], R[2], 0, | ||
R[3], R[4], R[5], 0, | ||
R[6], R[7], R[8], 0, | ||
0, 0, 0, 1, | ||
]; | ||
return exports.multiply(A, R4); | ||
}; | ||
/** | ||
* Compute the 4D view matrix for a camera at | ||
* position "eye", looking at position "at", oriented | ||
* with "up" facing in the y+ direction. | ||
* | ||
* Based on https://github/toji/gl-matrix | ||
*/ | ||
exports.lookAt = (eye, at, up, epsilon = 1e-6) => { | ||
let z = subtract(eye, at); | ||
let count = 0; | ||
for (let i = 0; i < 3; i++) { | ||
if (Math.abs(z[i]) < epsilon) | ||
count++; | ||
} | ||
if (count === 3) | ||
return exports.identity(4); | ||
z = normalize(z); | ||
let x; | ||
try { | ||
x = normalize(cross(up, z)); | ||
} | ||
catch (ok) { | ||
x = [0, 0, 0]; | ||
} | ||
let y; | ||
try { | ||
y = normalize(cross(z, x)); | ||
} | ||
catch (ok) { | ||
y = [0, 0, 0]; | ||
} | ||
return [ | ||
x[0], y[0], z[0], 0, | ||
x[1], y[1], z[1], 0, | ||
x[2], y[2], z[2], 0, | ||
-dot(x, eye), -dot(y, eye), -dot(z, eye), 1, | ||
]; | ||
}; | ||
/** | ||
* Generate a 4D perspective matrix from | ||
* @param {fovy} vertical field of view (radians) | ||
* @param {aspect} width / height aspect ratio | ||
* @param {near} near bound of the frustum | ||
* @param {far} far bound of the frustum, can be Infinity or null | ||
*/ | ||
exports.perspective = (fovy, aspect, near, far) => { | ||
const f = 1.0 / Math.tan(fovy / 2); | ||
let out10; | ||
let out14; | ||
if (far !== null && far !== Infinity) { | ||
const nf = 1 / (near - far); | ||
out10 = (near + far) * nf; | ||
out14 = 2 * far * near * nf; | ||
} | ||
else { | ||
out10 = -1; | ||
out14 = -2 * near; | ||
} | ||
return [ | ||
f / aspect, 0, 0, 0, | ||
0, f, 0, 0, | ||
0, 0, out10, -1, | ||
0, 0, out14, 0, | ||
]; | ||
}; | ||
/** | ||
* Returns an array of all the cube face keys. | ||
*/ | ||
exports.cubeFaces = () => ['posx', 'negx', 'posy', 'negy', 'posz', 'negz']; | ||
/** | ||
* Test if an object is a Cube. | ||
*/ | ||
exports.isCube = (obj) => Boolean(obj) && exports.cubeFaces().every(k => obj[k] !== undefined); | ||
/** | ||
* Build a cube by iterating over each face and calling | ||
* a given callback. | ||
*/ | ||
exports.cube = (buildFace) => { | ||
const result = {}; | ||
for (const cf of exports.cubeFaces()) { | ||
result[cf] = buildFace(cf); | ||
} | ||
return result; | ||
}; | ||
/***/ }), | ||
/***/ "./lib/shader.ts": | ||
/*!***********************!*\ | ||
!*** ./lib/shader.ts ***! | ||
\***********************/ | ||
/*! no static exports found */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/** | ||
* @fileoverview Module contains the function for building a Shader. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Shader = void 0; | ||
const gl_1 = __webpack_require__(/*! ./gl */ "./lib/gl.ts"); | ||
const uniforms_1 = __webpack_require__(/*! ./uniforms */ "./lib/uniforms.ts"); | ||
const defaultOpts = { | ||
attributes: [], | ||
uniforms: [], | ||
mode: WebGLRenderingContext.TRIANGLE_STRIP, | ||
clear: true, | ||
}; | ||
const clearOption = (opts) => (opts.clear === undefined) || opts.clear; | ||
const defaultViewport = (canvas) => [0, 0, canvas.width, canvas.height]; | ||
const nVertices = (opts) => opts.indices ? opts.indices.length : opts.attributes[0].length(); | ||
const cache = new WeakMap(); | ||
const lookup = (key, canvas, vertexSrc, fragmentSrc) => { | ||
let state = cache.get(key); | ||
if (!state) { | ||
const gl = gl_1.glContext(canvas); | ||
state = { gl, program: gl_1.glProgram(gl, vertexSrc, fragmentSrc) }; | ||
cache.set(key, state); | ||
} | ||
return state; | ||
}; | ||
const pendingTextureRenders = new WeakMap(); | ||
const prepareTextureUniforms = (gl, prog, canvas, uniforms) => { | ||
for (const uniform of uniforms) { | ||
if (!uniforms_1.isTextureUniform(uniform)) | ||
continue; | ||
uniform.prepare(gl, prog); | ||
const renderFuncs = pendingTextureRenders.get(uniform); | ||
if (!renderFuncs) | ||
continue; | ||
pendingTextureRenders.delete(uniform); | ||
for (const func of renderFuncs) { | ||
func(canvas); | ||
} | ||
} | ||
}; | ||
const sendDataToShader = (gl, prog, opts) => { | ||
let firstLen; | ||
for (const attr of opts.attributes) { | ||
if (isNaN(firstLen)) { | ||
firstLen = attr.length(); | ||
} | ||
else if (attr.length() != firstLen) { | ||
throw new Error('Mismatched attrbute size'); | ||
} | ||
attr.send(gl, prog); | ||
} | ||
for (const uniform of opts.uniforms) { | ||
uniform.send(gl, prog); | ||
} | ||
if (opts.indices) | ||
gl_1.sendIndices(gl, opts.indices); | ||
}; | ||
const renderShader = (key, canvas, vertexSrc, fragmentSrc, frameBuffer, renderBuffer, opts) => { | ||
const { gl, program } = lookup(key, canvas, vertexSrc, fragmentSrc); | ||
prepareTextureUniforms(gl, program, canvas, opts.uniforms); | ||
gl.useProgram(program); | ||
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); | ||
gl.bindRenderbuffer(gl.RENDERBUFFER, renderBuffer); | ||
sendDataToShader(gl, program, opts); | ||
gl_1.glRender(gl, nVertices(opts), clearOption(opts), opts.viewport || defaultViewport(canvas), opts.mode || defaultOpts.mode, | ||
/* drawElements= */ !!opts.indices); | ||
}; | ||
const renderCubeTexture = (key, canvas, opts, target, vertexSrc, fragmentSrc) => { | ||
if (target instanceof uniforms_1.CubeCameraUniformImpl) { | ||
const gl = gl_1.glContext(canvas); | ||
const viewport = opts.viewport || defaultViewport(canvas); | ||
const { frameBuffer, renderBuffer } = target.buffers(gl, viewport); | ||
target.render((cf) => { | ||
renderShader(key, canvas, vertexSrc, fragmentSrc, frameBuffer[cf], renderBuffer[cf], opts); | ||
}); | ||
return; | ||
} | ||
// TODO render to cube texture without cube camera. | ||
throw new Error('Not implemented'); | ||
}; | ||
const render2DTexture = (key, canvas, opts, target, vertexSrc, fragmentSrc) => { | ||
const gl = gl_1.glContext(canvas); | ||
const viewport = opts.viewport || defaultViewport(canvas); | ||
const { frameBuffer, renderBuffer } = target.buffers(gl, viewport); | ||
renderShader(key, canvas, vertexSrc, fragmentSrc, frameBuffer, renderBuffer, opts); | ||
}; | ||
const createTextureRenderFunc = (key, target, vertexSrc, fragmentSrc, opts) => (canvas) => { | ||
if (uniforms_1.isCubeTextureUniform(target)) { | ||
renderCubeTexture(key, canvas, opts, target, vertexSrc, fragmentSrc); | ||
return; | ||
} | ||
render2DTexture(key, canvas, opts, target, vertexSrc, fragmentSrc); | ||
}; | ||
const addTextureRenderFunc = (target, func) => { | ||
let funcs = pendingTextureRenders.get(target); | ||
if (!funcs) { | ||
funcs = []; | ||
pendingTextureRenders.set(target, funcs); | ||
} | ||
funcs.push(func); | ||
}; | ||
/** | ||
* Create a shader function to render to a target. | ||
*/ | ||
exports.Shader = (vertexSrc, fragmentSrc, opts) => { | ||
var _a; | ||
if (!(opts && ((_a = opts.attributes) === null || _a === void 0 ? void 0 : _a.length))) { | ||
throw new Error('Shaders require at least one attribute'); | ||
} | ||
const key = {}; | ||
return (target) => { | ||
if (target instanceof HTMLCanvasElement) { | ||
renderShader(key, target, vertexSrc, fragmentSrc, null, null, opts); | ||
return target; | ||
} | ||
else if (uniforms_1.isTextureUniform(target)) { | ||
addTextureRenderFunc(target, createTextureRenderFunc(key, target, vertexSrc, fragmentSrc, opts)); | ||
return target; | ||
} | ||
throw new Error('Shader function must be called with a canvas or texture uniform'); | ||
}; | ||
}; | ||
/***/ }), | ||
/***/ "./lib/uniforms.ts": | ||
/*!*************************!*\ | ||
!*** ./lib/uniforms.ts ***! | ||
\*************************/ | ||
/*! no static exports found */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/** | ||
* @fileoverview Shader uniforms module. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CubeCameraUniform = exports.CubeCameraUniformImpl = exports.isCubeTextureUniform = exports.CubeTextureUniform = exports.CubeTextureImpl = exports.Texture2DUniform = exports.Texture2DUniformImpl = exports.isTextureUniform = exports.TextureUniform = exports.PerspectiveMatUniform = exports.ViewMatUniform = exports.ViewMatUniformImpl = exports.NormalMatUniform = exports.ModelMatUniform = exports.Mat4Uniform = exports.Mat3Uniform = exports.Mat2Uniform = exports.Vec4Uniform = exports.Vec3Uniform = exports.Vec2Uniform = exports.IntegerUniform = exports.FloatUniform = exports.BooleanUniform = exports.Uniform = void 0; | ||
const gl_1 = __webpack_require__(/*! ./gl */ "./lib/gl.ts"); | ||
const math_1 = __webpack_require__(/*! ./math */ "./lib/math.ts"); | ||
/** | ||
* Uniform base class. All uniforms are a superclass of this | ||
* class. | ||
*/ | ||
class Uniform { | ||
constructor(type_, name, dataOrCb_) { | ||
this.type_ = type_; | ||
this.name = name; | ||
this.dataOrCb_ = dataOrCb_; | ||
} | ||
static checkType(u, wantType) { | ||
if (u.type_ !== wantType) { | ||
throw new TypeError(`Expected uniform with type ${wantType} got type ${u.type_}`); | ||
} | ||
} | ||
static dataOrCallback(u) { | ||
return u.dataOrCb_; | ||
} | ||
set(dataOrCb) { | ||
this.dataOrCb_ = dataOrCb; | ||
return this; | ||
} | ||
data() { | ||
if (typeof this.dataOrCb_ === 'function') { | ||
return this.dataOrCb_(); | ||
} | ||
return this.dataOrCb_; | ||
} | ||
send(gl, program) { | ||
throw new Error('Virtual method should not be invoked'); | ||
} | ||
} | ||
exports.Uniform = Uniform; | ||
class BytesUniform extends Uniform { | ||
send(gl, program) { | ||
if (isNaN(this.data())) { | ||
throw TypeError(`Data for ${this.type_} uniform should be a number`); | ||
} | ||
gl_1.sendBytesUniform(gl, program, this.name, this.type_, this.data()); | ||
} | ||
} | ||
/** | ||
* Create a builder function for each type of numeric uniform. | ||
*/ | ||
const bytesUniform = (type) => (name, data) => new BytesUniform(type, name, data); | ||
/** | ||
* Send a boolean uniform to a shader. | ||
*/ | ||
exports.BooleanUniform = bytesUniform(gl_1.UniformType.BOOLEAN); | ||
/** | ||
* Send a float uniform to a shader. | ||
*/ | ||
exports.FloatUniform = bytesUniform(gl_1.UniformType.FLOAT); | ||
/** | ||
* Send a integer uniform to a shader. | ||
*/ | ||
exports.IntegerUniform = bytesUniform(gl_1.UniformType.INTEGER); | ||
class SequenceUniform extends Uniform { | ||
constructor(type, name, dimension, dataOrCb) { | ||
super(type, name, dataOrCb); | ||
this.dimension = dimension; | ||
} | ||
validateData_() { | ||
if (this.type_ == gl_1.UniformType.VECTOR) { | ||
if (this.data().length != this.dimension) { | ||
throw new TypeError(`Dimension mismatch for a ${this.type_}${this.dimension} uniform`); | ||
} | ||
} | ||
else { | ||
if (this.data().length != Math.pow(this.dimension, 2)) { | ||
throw new TypeError(`Dimension mismatch for a ${this.type_}${this.dimension} uniform`); | ||
} | ||
} | ||
} | ||
send(gl, program) { | ||
this.validateData_(); | ||
if (this.type_ === gl_1.UniformType.VECTOR) { | ||
gl_1.sendVectorUniform(gl, program, this.name, this.dimension, this.data()); | ||
} | ||
else { | ||
gl_1.sendMatrixUniform(gl, program, this.name, this.dimension, this.data()); | ||
} | ||
} | ||
set(dataOrCb) { | ||
this.dataOrCb_ = dataOrCb; | ||
this.validateData_(); | ||
return this; | ||
} | ||
static checkDimension(u, wantDimension) { | ||
if (u.dimension != wantDimension) { | ||
throw new TypeError(); | ||
} | ||
} | ||
} | ||
/** | ||
* Creates builder functions for vector and matrix uniforms. | ||
*/ | ||
const sequenceUniform = (type, dimension) => (name, data) => new SequenceUniform(type, name, dimension, data); | ||
/** | ||
* Sends a 2-dimensional vector to a shader. | ||
*/ | ||
exports.Vec2Uniform = sequenceUniform(gl_1.UniformType.VECTOR, 2); | ||
/** | ||
* Sends a 3-dimensional vector to a shader. | ||
*/ | ||
exports.Vec3Uniform = sequenceUniform(gl_1.UniformType.VECTOR, 3); | ||
/** | ||
* Sends a 4-dimensional vector to a shader. | ||
*/ | ||
exports.Vec4Uniform = sequenceUniform(gl_1.UniformType.VECTOR, 4); | ||
/** | ||
* Sends a 2-dimensional matrix to a shader. | ||
*/ | ||
exports.Mat2Uniform = sequenceUniform(gl_1.UniformType.MATRIX, 2); | ||
/** | ||
* Sends a 3-dimensional matrix to a shader. | ||
*/ | ||
exports.Mat3Uniform = sequenceUniform(gl_1.UniformType.MATRIX, 3); | ||
/** | ||
* Sends a 4-dimensional matrix to a shader. | ||
*/ | ||
exports.Mat4Uniform = sequenceUniform(gl_1.UniformType.MATRIX, 4); | ||
class ModelMatUniformImpl extends SequenceUniform { | ||
constructor(name, opts) { | ||
super(gl_1.UniformType.MATRIX, name, 4, () => this.matrix()); | ||
this.scaleMatrix_ = math_1.identity(4); | ||
if (opts.scale) { | ||
if (typeof opts.scale === 'number') { | ||
this.scaleMatrix_ = math_1.scale(this.scaleMatrix_, opts.scale); | ||
} | ||
else { | ||
this.scaleMatrix_ = math_1.scale(this.scaleMatrix_, ...opts.scale); | ||
} | ||
} | ||
this.rotationMatrix_ = math_1.identity(3); | ||
if (opts.rotate) { | ||
this.rotationMatrix_ = math_1.rotate(this.rotationMatrix_, ...opts.rotate); | ||
} | ||
this.translation_ = [0, 0, 0]; | ||
if (opts.translate) | ||
this.translation_ = opts.translate; | ||
} | ||
scaleMatrix() { | ||
return [...this.scaleMatrix_]; | ||
} | ||
rotationMatrix() { | ||
return [...this.rotationMatrix_]; | ||
} | ||
rotationMatrix4_() { | ||
const R = this.rotationMatrix_; | ||
return [ | ||
R[0], R[1], R[2], 0, | ||
R[3], R[4], R[5], 0, | ||
R[6], R[7], R[8], 0, | ||
0, 0, 0, 1, | ||
]; | ||
} | ||
translation() { | ||
return [...this.translation_]; | ||
} | ||
matrix() { | ||
return math_1.translate(math_1.multiply(this.rotationMatrix4_(), this.scaleMatrix()), ...this.translation_); | ||
} | ||
scale(...args) { | ||
this.scaleMatrix_ = math_1.scale(this.scaleMatrix_, ...args); | ||
} | ||
setScale(...args) { | ||
this.scaleMatrix_ = math_1.scale(math_1.identity(4), ...args); | ||
} | ||
rotate(theta, ...axis) { | ||
this.rotationMatrix_ = math_1.rotate(this.rotationMatrix_, theta, ...axis); | ||
} | ||
setRotate(theta, ...axis) { | ||
this.rotationMatrix_ = math_1.rotate(math_1.identity(3), theta, ...axis); | ||
} | ||
translate(...args) { | ||
args = args.slice(0, 3); | ||
if (!math_1.isVector3(args)) { | ||
throw new Error('Expected 3 numeric arguments'); | ||
} | ||
this.translation_ = math_1.add(this.translation_, args); | ||
} | ||
setTranslation(...args) { | ||
args = args.slice(0, 3); | ||
if (!math_1.isVector3(args)) { | ||
throw new Error('Expected 3 numeric arguments'); | ||
} | ||
this.translation_ = args; | ||
} | ||
} | ||
/** | ||
* Sends a model matrix to a shader as a uniform that applies | ||
* a scale, rotation, and translation (in that order). | ||
*/ | ||
exports.ModelMatUniform = (name, opts = {}) => new ModelMatUniformImpl(name, opts); | ||
/** | ||
* Sends the resulting normal matrix for a given | ||
* model matrix to a shader. | ||
* | ||
* The normal matrix is the inverse transpose of | ||
* the rotation component of the model matrix. | ||
* Since for any rotation matrix R, it's inverse is | ||
* R^T. | ||
*/ | ||
exports.NormalMatUniform = (name, modelMat) => { | ||
return sequenceUniform(gl_1.UniformType.MATRIX, 3)(name, () => modelMat.rotationMatrix()); | ||
}; | ||
/** | ||
* View matrix uniform with accessor and mutator methods for | ||
* the | ||
*/ | ||
class ViewMatUniformImpl extends SequenceUniform { | ||
constructor(name, eye_, at_, up_) { | ||
super(gl_1.UniformType.MATRIX, name, 4, () => math_1.lookAt(this.eye_, this.at_, this.up_)); | ||
this.eye_ = eye_; | ||
this.at_ = at_; | ||
this.up_ = up_; | ||
} | ||
eye() { | ||
return [...this.eye_]; | ||
} | ||
at() { | ||
return [...this.at_]; | ||
} | ||
up() { | ||
return [...this.up_]; | ||
} | ||
setEye(...eye) { | ||
ViewMatUniformImpl.validateVector3(eye); | ||
this.eye_ = eye; | ||
} | ||
setAt(...at) { | ||
ViewMatUniformImpl.validateVector3(at); | ||
this.at_ = at.slice(0, 3); | ||
} | ||
setUp(...up) { | ||
ViewMatUniformImpl.validateVector3(up); | ||
this.up_ = [...up]; | ||
} | ||
} | ||
exports.ViewMatUniformImpl = ViewMatUniformImpl; | ||
ViewMatUniformImpl.validateVector3 = (data) => { | ||
if (!math_1.isVector3(data)) { | ||
throw new Error('Expected 3 numbers as arguments'); | ||
} | ||
}; | ||
/** | ||
* Sends a view matrix uniform for the given | ||
* eye, at, and up vectors. | ||
*/ | ||
exports.ViewMatUniform = (name, eye, at, up) => new ViewMatUniformImpl(name, eye, at, up); | ||
class PerspectiveMatUniformImpl extends SequenceUniform { | ||
constructor(name, fovy_, aspect_, near_, far_) { | ||
super(gl_1.UniformType.MATRIX, name, 4, () => math_1.perspective(this.fovy_, this.aspect_, this.near_, this.far_)); | ||
this.fovy_ = fovy_; | ||
this.aspect_ = aspect_; | ||
this.near_ = near_; | ||
this.far_ = far_; | ||
} | ||
fovy() { | ||
return this.fovy_; | ||
} | ||
aspect() { | ||
return this.aspect_; | ||
} | ||
near() { | ||
return this.near_; | ||
} | ||
far() { | ||
return this.far_; | ||
} | ||
setFovy(fovy) { | ||
this.fovy_ = fovy; | ||
} | ||
setAspect(aspect) { | ||
this.aspect_ = aspect; | ||
} | ||
setNear(near) { | ||
this.near_ = near; | ||
} | ||
setFar(far) { | ||
this.far_ = far; | ||
} | ||
} | ||
/** | ||
* Sends a perspective 4D matrix uniform. | ||
*/ | ||
exports.PerspectiveMatUniform = (name, fovy, aspect, near, far = null) => new PerspectiveMatUniformImpl(name, fovy, aspect, near, far); | ||
class TextureUniform extends Uniform { | ||
shouldBuildTextureFromData_() { | ||
return (!this.textureBuffers_) // If this object exists then | ||
&& (!!this.dataOrCb_) | ||
&& (!this.texture_ || gl_1.isVideo(this.data())); | ||
} | ||
prepare(gl, p) { | ||
throw new Error('Virtual method should not be invoked'); | ||
} | ||
buffers(gl, v) { | ||
throw new Error('Virtual method should not be invoked'); | ||
} | ||
set(dataOrCb) { | ||
this.dataOrCb_ = dataOrCb; | ||
this.texture_ = undefined; | ||
return this; | ||
} | ||
} | ||
exports.TextureUniform = TextureUniform; | ||
/** | ||
* Tests if a uniform is for a texture. | ||
*/ | ||
exports.isTextureUniform = (u) => u instanceof TextureUniform; | ||
/** | ||
* Implementation of a 2D texture uniform. | ||
*/ | ||
class Texture2DUniformImpl extends TextureUniform { | ||
constructor(name, dataOrCb) { | ||
super(gl_1.UniformType.TEXTURE, name, dataOrCb); | ||
} | ||
prepare(gl, program) { | ||
if (isNaN(this.offset_)) { | ||
this.offset_ = gl_1.newTextureOffset(program, this.name); | ||
} | ||
if (this.shouldBuildTextureFromData_()) { | ||
this.texture_ = gl_1.texture2d(gl, this.data()); | ||
} | ||
} | ||
send(gl, program) { | ||
gl_1.send2DTexture(gl, program, this.name, this.offset_, this.texture_); | ||
} | ||
buffers(gl, viewport) { | ||
if (this.textureBuffers_) | ||
return this.textureBuffers_; | ||
const frameBuffer = gl.createFramebuffer(); | ||
const [, , width, height] = viewport; | ||
this.textureBuffers_ = { | ||
frameBuffer, | ||
renderBuffer: gl_1.renderBuffer(gl, frameBuffer, width, height), | ||
}; | ||
this.texture_ = gl_1.texture2DFromFramebuffer(gl, frameBuffer, width, height); | ||
return this.textureBuffers_; | ||
} | ||
} | ||
exports.Texture2DUniformImpl = Texture2DUniformImpl; | ||
/** | ||
* Sends a 2D texture uniform to a shader. | ||
*/ | ||
exports.Texture2DUniform = (name, data) => new Texture2DUniformImpl(name, data); | ||
class CubeTextureImpl extends TextureUniform { | ||
validateData() { | ||
if (!math_1.isCube(this.data())) { | ||
throw new Error('You must provide an object with "posx", "negx", "posy", "negy", ' + | ||
'"posz", and "negz" keys'); | ||
} | ||
} | ||
set(dataOrCb) { | ||
this.dataOrCb_ = dataOrCb; | ||
this.validateData(); | ||
this.texture_ = undefined; | ||
return this; | ||
} | ||
prepare(gl, program) { | ||
if (isNaN(this.offset_)) { | ||
this.offset_ = gl_1.newTextureOffset(program, this.name); | ||
} | ||
if (this.shouldBuildTextureFromData_()) { | ||
this.texture_ = gl_1.cubeTexure(gl, this.data()); | ||
} | ||
} | ||
send(gl, program) { | ||
gl_1.sendCubeTexture(gl, program, this.name, this.offset_, this.texture_); | ||
} | ||
buffers(gl, viewport) { | ||
if (this.textureBuffers_) | ||
return this.textureBuffers_; | ||
const [, , width, height] = viewport; | ||
const frameBufferCube = math_1.cube(() => gl.createFramebuffer()); | ||
this.textureBuffers_ = { | ||
frameBuffer: frameBufferCube, | ||
renderBuffer: math_1.cube((cf) => gl_1.renderBuffer(gl, frameBufferCube[cf], width, height)), | ||
}; | ||
this.texture_ = gl_1.cubeTextureFromFramebuffer(gl, this.buffers(gl, viewport).frameBuffer, width, height); | ||
return this.textureBuffers_; | ||
} | ||
} | ||
exports.CubeTextureImpl = CubeTextureImpl; | ||
/** | ||
* Sends a cube texture uniform to a shader. | ||
*/ | ||
exports.CubeTextureUniform = (name, data) => new CubeTextureImpl(gl_1.UniformType.TEXTURE, name, data); | ||
/** | ||
* Tests if a uniform is a cube texture uniform. | ||
*/ | ||
exports.isCubeTextureUniform = (u) => u instanceof CubeTextureImpl; | ||
/** | ||
* Implementation of a cube camera uniform. | ||
*/ | ||
class CubeCameraUniformImpl extends CubeTextureImpl { | ||
constructor(name, position_, viewMat_, perspectiveMat_) { | ||
super(gl_1.UniformType.TEXTURE, name); | ||
this.position_ = position_; | ||
this.viewMat_ = viewMat_; | ||
this.perspectiveMat_ = perspectiveMat_; | ||
if (!math_1.isVector3(position_)) { | ||
throw new Error('Expected array of 3 arguments as the first argument'); | ||
} | ||
Uniform.checkType(viewMat_, gl_1.UniformType.MATRIX); | ||
SequenceUniform.checkDimension(viewMat_, 4); | ||
} | ||
set(dataOrCb) { | ||
throw new Error('Cube camera uniforms should get their data from a shader'); | ||
} | ||
render(renderShader) { | ||
const fovy = this.perspectiveMat_.fovy(); | ||
this.perspectiveMat_.setFovy(Math.PI / 2); | ||
const viewMatDataOrCb = Uniform.dataOrCallback(this.viewMat_); | ||
for (const cf of math_1.cubeFaces()) { | ||
const at = math_1.add(CubeCameraUniformImpl.atVectors[cf], this.position_); | ||
const up = CubeCameraUniformImpl.upVectors[cf]; | ||
this.viewMat_.set(math_1.lookAt(this.position_, at, up)); | ||
renderShader(cf); | ||
} | ||
this.viewMat_.set(viewMatDataOrCb); | ||
this.perspectiveMat_.setFovy(fovy); | ||
} | ||
} | ||
exports.CubeCameraUniformImpl = CubeCameraUniformImpl; | ||
CubeCameraUniformImpl.upVectors = { | ||
posx: [0, -1, 0], | ||
negx: [0, -1, 0], | ||
posy: [0, 0, 1], | ||
negy: [0, 0, 1], | ||
posz: [0, -1, 0], | ||
negz: [0, -1, 0], | ||
}; | ||
CubeCameraUniformImpl.atVectors = { | ||
posx: [1, 0, 0], | ||
negx: [-1, 0, 0], | ||
posy: [0, 1, 0], | ||
negy: [0, -1, 0], | ||
posz: [0, 0, 1], | ||
negz: [0, 0, -1], | ||
}; | ||
/** | ||
* Sends a cube texture to a shader rendered from | ||
* a cube camera. | ||
*/ | ||
exports.CubeCameraUniform = (name, position, viewMat, perspectiveMat) => { | ||
if (!position) | ||
position = [0, 0, 0]; | ||
if (!viewMat) { | ||
viewMat = new ViewMatUniformImpl('', [0, 0, 1], [0, 0, 0], [0, 1, 0]); | ||
} | ||
return new CubeCameraUniformImpl(name, position, viewMat, perspectiveMat); | ||
}; | ||
/***/ }) | ||
/******/ }); | ||
module.exports=function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=3)}([function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.glRender=t.cubeTextureFromFramebuffer=t.texture2DFromFramebuffer=t.renderBuffer=t.sendCubeTexture=t.send2DTexture=t.cubeTexure=t.texture2d=t.isVideo=t.newTextureOffset=t.sendVectorUniform=t.sendMatrixUniform=t.sendBytesUniform=t.UniformType=t.sendMatrixAttribute=t.sendAttribute=t.sendIndices=t.glProgram=t.glContext=void 0;const n=r(1);t.glContext=e=>{const t=e.getContext("webgl",{preserveDrawingBuffer:!0})||e.getContext("experimental-webgl",{preserveDrawingBuffer:!0});return t.enable(t.DEPTH_TEST),t.depthFunc(t.LEQUAL),t};const i=(e,t,r)=>{if(e.shaderSource(t,r),e.compileShader(t),!e.getShaderParameter(t,e.COMPILE_STATUS))throw new Error("Shader failed to compile: "+e.getShaderInfoLog(t));return t};var o;t.glProgram=(e,t,r)=>{const n=i(e,e.createShader(WebGLRenderingContext.VERTEX_SHADER),t),o=i(e,e.createShader(WebGLRenderingContext.FRAGMENT_SHADER),r),a=e.createProgram();if(e.attachShader(a,n),e.attachShader(a,o),e.linkProgram(a),!e.getProgramParameter(a,e.LINK_STATUS))throw new Error("Shader failed to compile: "+e.getProgramInfoLog(a));return a},t.sendIndices=(e,t)=>{e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,e.createBuffer()),e.bufferData(e.ELEMENT_ARRAY_BUFFER,t,e.STATIC_DRAW)},t.sendAttribute=(e,t,r,n,i,o)=>{const a=e.getAttribLocation(t,n);e.bindBuffer(e.ARRAY_BUFFER,r),e.vertexAttribPointer(a,o,e.FLOAT,!1,0,0),e.enableVertexAttribArray(a),e.bufferData(e.ARRAY_BUFFER,i,e.STATIC_DRAW)},t.sendMatrixAttribute=(e,t,r,n,i,o)=>{const a=e.getAttribLocation(t,n);for(let t=0;t<o;t++)e.enableVertexAttribArray(a+t),e.bindBuffer(e.ARRAY_BUFFER,r),e.bufferData(e.ARRAY_BUFFER,i[t],e.STATIC_DRAW),e.vertexAttribPointer(a+t,o,e.FLOAT,!1,0,0)},function(e){e.BOOLEAN="boolean",e.FLOAT="float",e.INTEGER="integer",e.VECTOR="vector",e.MATRIX="matrix",e.TEXTURE="texture"}(o=t.UniformType||(t.UniformType={})),t.sendBytesUniform=(e,t,r,n,i)=>{const a=e.getUniformLocation(t,r);switch(n){case o.BOOLEAN:e.uniform1i(a,i);break;case o.FLOAT:e.uniform1f(a,i);break;case o.INTEGER:e.uniform1i(a,i);break;default:throw new Error("Unexpected uniform type: "+n)}},t.sendMatrixUniform=(e,t,r,n,i)=>{const o=e.getUniformLocation(t,r);switch(n){case 2:e.uniformMatrix2fv(o,!1,i);break;case 3:e.uniformMatrix3fv(o,!1,i);break;case 4:e.uniformMatrix4fv(o,!1,i)}},t.sendVectorUniform=(e,t,r,n,i)=>{const o=e.getUniformLocation(t,r);switch(n){case 2:e.uniform2fv(o,i);break;case 3:e.uniform3fv(o,i);break;case 4:e.uniform4fv(o,i);break;default:throw new Error("Unexpected dimension: "+n)}};const a=new WeakMap;t.newTextureOffset=(e,t)=>{const r=a.get(e)||[];for(let e=0;e<r.length;e++)if(r[e]===t)return e;const n=r.length;if(32===n)throw new Error("Already at maximum number of textures for this program");return r.push(t),n||a.set(e,r),n},t.isVideo=e=>n.isCube(e)?Object.keys(e).some(t=>e[t]instanceof HTMLVideoElement):e instanceof HTMLVideoElement,t.texture2d=(e,r)=>{const i=e.createTexture();return e.bindTexture(e.TEXTURE_2D,i),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,r),!t.isVideo(r)&&n.isPowerOfTwo(r.width)&&n.isPowerOfTwo(r.height)?e.generateMipmap(e.TEXTURE_2D):(e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR)),i};const s={posx:WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_X,negx:WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_X,posy:WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_Y,negy:WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_Y,posz:WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_Z,negz:WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_Z};t.cubeTexure=(e,r)=>{const i=e.createTexture();e.bindTexture(e.TEXTURE_CUBE_MAP,i);for(const t of n.cubeFaces())e.texImage2D(s[t],0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,r[t]);return!t.isVideo(r)&&(e=>{for(const t of n.cubeFaces())if(!n.isPowerOfTwo(e[t].width)||!n.isPowerOfTwo(e[t].height))return!1;return!0})(r)?e.generateMipmap(e.TEXTURE_CUBE_MAP):(e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE)),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MIN_FILTER,e.LINEAR_MIPMAP_LINEAR),i};const u=e=>(t,r,n,i,o)=>{const a=t.getUniformLocation(r,n);t.uniform1i(a,i),t.activeTexture(t.TEXTURE0+i),t.bindTexture(e,o)};t.send2DTexture=u(WebGLRenderingContext.TEXTURE_2D),t.sendCubeTexture=u(WebGLRenderingContext.TEXTURE_CUBE_MAP),t.renderBuffer=(e,t,r,n)=>{const i=e.createRenderbuffer();return e.bindFramebuffer(e.FRAMEBUFFER,t),e.bindRenderbuffer(e.RENDERBUFFER,i),e.renderbufferStorage(e.RENDERBUFFER,e.DEPTH_COMPONENT16,r,n),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.DEPTH_ATTACHMENT,e.RENDERBUFFER,i),i},t.texture2DFromFramebuffer=(e,t,r,n)=>{const i=e.createTexture();return e.bindTexture(e.TEXTURE_2D,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindFramebuffer(e.FRAMEBUFFER,t),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,r,n,0,e.RGBA,e.UNSIGNED_BYTE,null),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,i,0),i},t.cubeTextureFromFramebuffer=(e,t,r,i)=>{const o=e.createTexture();e.bindTexture(e.TEXTURE_CUBE_MAP,o),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE);for(const a of n.cubeFaces())e.bindFramebuffer(e.FRAMEBUFFER,t[a]),e.texImage2D(s[a],0,e.RGBA,r,i,0,e.RGBA,e.UNSIGNED_BYTE,null),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,s[a],o,0);return o},t.glRender=(e,t,r,n,i,o)=>{e.clearColor(0,0,0,1),r&&(e.clearDepth(e.getParameter(e.DEPTH_CLEAR_VALUE)),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)),e.viewport(...n),o?e.drawElements(i,t,e.UNSIGNED_SHORT,0):e.drawArrays(i,0,t)}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.cube=t.isCube=t.cubeFaces=t.perspective=t.lookAt=t.rotate=t.scale=t.translate=t.multiply=t.identity=t.add=t.isVector3=t.isPowerOfTwo=void 0,t.isPowerOfTwo=e=>0==(e&e-1),t.isVector3=e=>Array.isArray(e)&&3===e.length&&e.every(e=>!isNaN(e));const n=e=>{const t=Math.hypot(...e);if(!t)throw new Error("Cannot normalize a vector with no length");return e.map(e=>e/t)};t.add=(e,t)=>e.map((e,r)=>e+t[r]);const i=(e,t)=>e.reduce((e,r,n)=>e+r*t[n],0),o=(e,t)=>[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]],a=e=>Math.sqrt(e.length),s=e=>[...Array(Math.pow(e,2))].map(()=>0);t.identity=e=>{const t=s(e);for(let r=0;r<e;r++)t[r*e+r]=1;return t};const u=(e,t,r)=>{const n=[...Array(r)].map(()=>0);for(let i=0;i<r;i++)for(let o=0;o<r;o++)n[i]+=e[i*r+o]*t[o];return n};t.multiply=(e,t)=>{const r=a(e);if(r!==a(t)){if(r!==t.length)throw new Error("Cannot multiply, incompatible dimensions");return u(e,t,r)}return((e,t,r)=>{const n=s(r);for(let i=0;i<r;i++)for(let o=0;o<r;o++)for(let a=0;a<r;a++)n[r*i+o]+=e[r*i+a]*t[r*a+o];return n})(e,t,r)},t.translate=(e,t,r,n)=>{const i=e.slice(0,16);return i[12]+=t,i[13]+=r,i[14]+=n,i},t.scale=(e,...r)=>{if(!r.length)throw new Error("You must provide at least one number to scale a matrix");const n=a(e);if(4===n&&2===r.length)throw new Error("You must provide 1, 3, or 4 arguments to scale for a 4D matrix");const i=t.identity(n);for(let e=0;e<n;e++)3===e&&t.scale.length<4?i[n*e+e]=1:i[n*e+e]=Number(isNaN(r[e])?r[0]:r[e]);return t.multiply(i,e)};t.rotate=(e,r,...i)=>{if(isNaN(r))throw new Error("Expected a number as a 2nd argument");const o=a(e);if(2===o)return((e,r)=>{const n=Math.cos(r),i=Math.sin(r);return t.multiply([n,i,n,-i],e)})(e,r);if(i=i.slice(0,3),!t.isVector3(i))throw new Error("Expected numeric 3rd, 4th, and 5th argument");i=n(i);const s=Math.sin(r/2),u=(e=>[1-2*(Math.pow(e[2],2)+Math.pow(e[3],2)),2*(e[1]*e[2]+e[3]*e[0]),2*(e[1]*e[3]-e[2]*e[0]),2*(e[1]*e[2]-e[3]*e[0]),1-2*(Math.pow(e[1],2)+Math.pow(e[3],2)),2*(e[2]*e[3]+e[1]*e[0]),2*(e[1]*e[3]+e[2]*e[0]),2*(e[2]*e[3]-e[1]*e[0]),1-2*(Math.pow(e[1],2)+Math.pow(e[2],2))])([Math.cos(r/2),i[0]*s,i[1]*s,i[2]*s]);if(3===o)return t.multiply(e,u);const f=[u[0],u[1],u[2],0,u[3],u[4],u[5],0,u[6],u[7],u[8],0,0,0,0,1];return t.multiply(e,f)},t.lookAt=(e,r,a,s=1e-6)=>{let u=(f=r,e.map((e,t)=>e-f[t]));var f;let c,m,d=0;for(let e=0;e<3;e++)Math.abs(u[e])<s&&d++;if(3===d)return t.identity(4);u=n(u);try{c=n(o(a,u))}catch(e){c=[0,0,0]}try{m=n(o(u,c))}catch(e){m=[0,0,0]}return[c[0],m[0],u[0],0,c[1],m[1],u[1],0,c[2],m[2],u[2],0,-i(c,e),-i(m,e),-i(u,e),1]},t.perspective=(e,t,r,n)=>{const i=1/Math.tan(e/2);let o,a;if(null!==n&&n!==1/0){const e=1/(r-n);o=(r+n)*e,a=2*n*r*e}else o=-1,a=-2*r;return[i/t,0,0,0,0,i,0,0,0,0,o,-1,0,0,a,0]},t.cubeFaces=()=>["posx","negx","posy","negy","posz","negz"],t.isCube=e=>Boolean(e)&&t.cubeFaces().every(t=>void 0!==e[t]),t.cube=e=>{const r={};for(const n of t.cubeFaces())r[n]=e(n);return r}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CubeCameraUniform=t.CubeCameraUniformImpl=t.isCubeTextureUniform=t.CubeTextureUniform=t.CubeTextureImpl=t.Texture2DUniform=t.Texture2DUniformImpl=t.isTextureUniform=t.TextureUniform=t.PerspectiveMatUniform=t.ViewMatUniform=t.ViewMatUniformImpl=t.NormalMatUniform=t.ModelMatUniform=t.Mat4Uniform=t.Mat3Uniform=t.Mat2Uniform=t.Vec4Uniform=t.Vec3Uniform=t.Vec2Uniform=t.IntegerUniform=t.FloatUniform=t.BooleanUniform=t.Uniform=void 0;const n=r(0),i=r(1);class o{constructor(e,t,r){this.type_=e,this.name=t,this.dataOrCb_=r}static checkType(e,t){if(e.type_!==t)throw new TypeError(`Expected uniform with type ${t} got type ${e.type_}`)}static dataOrCallback(e){return e.dataOrCb_}set(e){return this.dataOrCb_=e,this}data(){return"function"==typeof this.dataOrCb_?this.dataOrCb_():this.dataOrCb_}send(e,t){throw new Error("Virtual method should not be invoked")}}t.Uniform=o;class a extends o{send(e,t){if(isNaN(this.data()))throw TypeError(`Data for ${this.type_} uniform should be a number`);n.sendBytesUniform(e,t,this.name,this.type_,this.data())}}const s=e=>(t,r)=>new a(e,t,r);t.BooleanUniform=s(n.UniformType.BOOLEAN),t.FloatUniform=s(n.UniformType.FLOAT),t.IntegerUniform=s(n.UniformType.INTEGER);class u extends o{constructor(e,t,r,n){super(e,t,n),this.dimension=r}validateData_(){if(this.type_==n.UniformType.VECTOR){if(this.data().length!=this.dimension)throw new TypeError(`Dimension mismatch for a ${this.type_}${this.dimension} uniform`)}else if(this.data().length!=Math.pow(this.dimension,2))throw new TypeError(`Dimension mismatch for a ${this.type_}${this.dimension} uniform`)}send(e,t){this.validateData_(),this.type_===n.UniformType.VECTOR?n.sendVectorUniform(e,t,this.name,this.dimension,this.data()):n.sendMatrixUniform(e,t,this.name,this.dimension,this.data())}set(e){return this.dataOrCb_=e,this.validateData_(),this}static checkDimension(e,t){if(e.dimension!=t)throw new TypeError}}const f=(e,t)=>(r,n)=>new u(e,r,t,n);t.Vec2Uniform=f(n.UniformType.VECTOR,2),t.Vec3Uniform=f(n.UniformType.VECTOR,3),t.Vec4Uniform=f(n.UniformType.VECTOR,4),t.Mat2Uniform=f(n.UniformType.MATRIX,2),t.Mat3Uniform=f(n.UniformType.MATRIX,3),t.Mat4Uniform=f(n.UniformType.MATRIX,4);class c extends u{constructor(e,t){super(n.UniformType.MATRIX,e,4,()=>this.matrix_()),this.scaleMatrix_=i.identity(4),t.scale&&("number"==typeof t.scale?this.scaleMatrix_=i.scale(this.scaleMatrix_,t.scale):this.scaleMatrix_=i.scale(this.scaleMatrix_,...t.scale)),this.rotationMatrix_=i.identity(3),t.rotate&&(this.rotationMatrix_=i.rotate(this.rotationMatrix_,...t.rotate)),this.translation_=[0,0,0],t.translate&&(this.translation_=t.translate)}scaleMatrix(){return[...this.scaleMatrix_]}rotationMatrix(){return[...this.rotationMatrix_]}rotationMatrix4_(){const e=this.rotationMatrix_;return[e[0],e[1],e[2],0,e[3],e[4],e[5],0,e[6],e[7],e[8],0,0,0,0,1]}translation(){return[...this.translation_]}matrix_(){return i.translate(i.multiply(this.rotationMatrix4_(),this.scaleMatrix()),...this.translation_)}scale(...e){this.scaleMatrix_=i.scale(this.scaleMatrix_,...e)}setScale(...e){this.scaleMatrix_=i.scale(i.identity(4),...e)}rotate(e,...t){this.rotationMatrix_=i.rotate(this.rotationMatrix_,e,...t)}setRotate(e,...t){this.rotationMatrix_=i.rotate(i.identity(3),e,...t)}translate(...e){if(e=e.slice(0,3),!i.isVector3(e))throw new Error("Expected 3 numeric arguments");this.translation_=i.add(this.translation_,e)}setTranslation(...e){if(e=e.slice(0,3),!i.isVector3(e))throw new Error("Expected 3 numeric arguments");this.translation_=e}}t.ModelMatUniform=(e,t={})=>new c(e,t),t.NormalMatUniform=(e,t)=>f(n.UniformType.MATRIX,3)(e,()=>t.rotationMatrix());class m extends u{constructor(e,t,r,o){super(n.UniformType.MATRIX,e,4,()=>i.lookAt(this.eye_,this.at_,this.up_)),this.eye_=t,this.at_=r,this.up_=o}eye(){return[...this.eye_]}at(){return[...this.at_]}up(){return[...this.up_]}setEye(...e){m.validateVector3(e),this.eye_=e}setAt(...e){m.validateVector3(e),this.at_=e.slice(0,3)}setUp(...e){m.validateVector3(e),this.up_=[...e]}}t.ViewMatUniformImpl=m,m.validateVector3=e=>{if(!i.isVector3(e))throw new Error("Expected 3 numbers as arguments")},t.ViewMatUniform=(e,t,r,n)=>new m(e,t,r,n);class d extends u{constructor(e,t,r,o,a){super(n.UniformType.MATRIX,e,4,()=>i.perspective(this.fovy_,this.aspect_,this.near_,this.far_)),this.fovy_=t,this.aspect_=r,this.near_=o,this.far_=a}fovy(){return this.fovy_}aspect(){return this.aspect_}near(){return this.near_}far(){return this.far_}setFovy(e){this.fovy_=e}setAspect(e){this.aspect_=e}setNear(e){this.near_=e}setFar(e){this.far_=e}}t.PerspectiveMatUniform=(e,t,r,n,i=null)=>new d(e,t,r,n,i);class _ extends o{shouldBuildTextureFromData_(){return!this.textureBuffers_&&!!this.dataOrCb_&&(!this.texture_||n.isVideo(this.data()))}prepare(e,t){throw new Error("Virtual method should not be invoked")}buffers(e,t){throw new Error("Virtual method should not be invoked")}set(e){return this.dataOrCb_=e,this.texture_=void 0,this}}t.TextureUniform=_,t.isTextureUniform=e=>e instanceof _;class l extends _{constructor(e,t){super(n.UniformType.TEXTURE,e,t)}prepare(e,t){isNaN(this.offset_)&&(this.offset_=n.newTextureOffset(t,this.name)),this.shouldBuildTextureFromData_()&&(this.texture_=n.texture2d(e,this.data()))}send(e,t){n.send2DTexture(e,t,this.name,this.offset_,this.texture_)}buffers(e,t){if(this.textureBuffers_)return this.textureBuffers_;const r=e.createFramebuffer(),[,,i,o]=t;return this.textureBuffers_={frameBuffer:r,renderBuffer:n.renderBuffer(e,r,i,o)},this.texture_=n.texture2DFromFramebuffer(e,r,i,o),this.textureBuffers_}}t.Texture2DUniformImpl=l,t.Texture2DUniform=(e,t)=>new l(e,t);class E extends _{validateData(){if(!i.isCube(this.data()))throw new Error('You must provide an object with "posx", "negx", "posy", "negy", "posz", and "negz" keys')}set(e){return this.dataOrCb_=e,this.validateData(),this.texture_=void 0,this}prepare(e,t){isNaN(this.offset_)&&(this.offset_=n.newTextureOffset(t,this.name)),this.shouldBuildTextureFromData_()&&(this.texture_=n.cubeTexure(e,this.data()))}send(e,t){n.sendCubeTexture(e,t,this.name,this.offset_,this.texture_)}buffers(e,t){if(this.textureBuffers_)return this.textureBuffers_;const[,,r,o]=t,a=i.cube(()=>e.createFramebuffer());return this.textureBuffers_={frameBuffer:a,renderBuffer:i.cube(t=>n.renderBuffer(e,a[t],r,o))},this.texture_=n.cubeTextureFromFramebuffer(e,this.buffers(e,t).frameBuffer,r,o),this.textureBuffers_}}t.CubeTextureImpl=E,t.CubeTextureUniform=(e,t)=>new E(n.UniformType.TEXTURE,e,t),t.isCubeTextureUniform=e=>e instanceof E;class h extends E{constructor(e,t,r,a){if(super(n.UniformType.TEXTURE,e),this.position_=t,this.viewMat_=r,this.perspectiveMat_=a,!i.isVector3(t))throw new Error("Expected array of 3 arguments as the first argument");o.checkType(r,n.UniformType.MATRIX),u.checkDimension(r,4)}set(e){throw new Error("Cube camera uniforms should get their data from a shader")}render(e){const t=this.perspectiveMat_.fovy();this.perspectiveMat_.setFovy(Math.PI/2);const r=o.dataOrCallback(this.viewMat_);for(const t of i.cubeFaces()){const r=i.add(h.atVectors[t],this.position_),n=h.upVectors[t];this.viewMat_.set(i.lookAt(this.position_,r,n)),e(t)}this.viewMat_.set(r),this.perspectiveMat_.setFovy(t)}}t.CubeCameraUniformImpl=h,h.upVectors={posx:[0,-1,0],negx:[0,-1,0],posy:[0,0,1],negy:[0,0,1],posz:[0,-1,0],negz:[0,-1,0]},h.atVectors={posx:[1,0,0],negx:[-1,0,0],posy:[0,1,0],negy:[0,-1,0],posz:[0,0,1],negz:[0,0,-1]},t.CubeCameraUniform=(e,t,r,n)=>(t||(t=[0,0,0]),r||(r=new m("",[0,0,1],[0,0,0],[0,1,0])),new h(e,t,r,n))},function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r),Object.defineProperty(e,n,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),i=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||t.hasOwnProperty(r)||n(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0});var o=r(4);Object.defineProperty(t,"FloatAttribute",{enumerable:!0,get:function(){return o.FloatAttribute}}),Object.defineProperty(t,"Mat2Attribute",{enumerable:!0,get:function(){return o.Mat2Attribute}}),Object.defineProperty(t,"Mat3Attribute",{enumerable:!0,get:function(){return o.Mat3Attribute}}),Object.defineProperty(t,"Mat4Attribute",{enumerable:!0,get:function(){return o.Mat4Attribute}}),Object.defineProperty(t,"Vec2Attribute",{enumerable:!0,get:function(){return o.Vec2Attribute}}),Object.defineProperty(t,"Vec3Attribute",{enumerable:!0,get:function(){return o.Vec3Attribute}}),Object.defineProperty(t,"Vec4Attribute",{enumerable:!0,get:function(){return o.Vec4Attribute}}),i(r(5),t),i(r(6),t);var a=r(2);Object.defineProperty(t,"BooleanUniform",{enumerable:!0,get:function(){return a.BooleanUniform}}),Object.defineProperty(t,"CubeCameraUniform",{enumerable:!0,get:function(){return a.CubeCameraUniform}}),Object.defineProperty(t,"CubeTextureUniform",{enumerable:!0,get:function(){return a.CubeTextureUniform}}),Object.defineProperty(t,"FloatUniform",{enumerable:!0,get:function(){return a.FloatUniform}}),Object.defineProperty(t,"IntegerUniform",{enumerable:!0,get:function(){return a.IntegerUniform}}),Object.defineProperty(t,"Mat2Uniform",{enumerable:!0,get:function(){return a.Mat2Uniform}}),Object.defineProperty(t,"Mat3Uniform",{enumerable:!0,get:function(){return a.Mat3Uniform}}),Object.defineProperty(t,"Mat4Uniform",{enumerable:!0,get:function(){return a.Mat4Uniform}}),Object.defineProperty(t,"ModelMatUniform",{enumerable:!0,get:function(){return a.ModelMatUniform}}),Object.defineProperty(t,"NormalMatUniform",{enumerable:!0,get:function(){return a.NormalMatUniform}}),Object.defineProperty(t,"PerspectiveMatUniform",{enumerable:!0,get:function(){return a.PerspectiveMatUniform}}),Object.defineProperty(t,"Texture2DUniform",{enumerable:!0,get:function(){return a.Texture2DUniform}}),Object.defineProperty(t,"Vec2Uniform",{enumerable:!0,get:function(){return a.Vec2Uniform}}),Object.defineProperty(t,"Vec3Uniform",{enumerable:!0,get:function(){return a.Vec3Uniform}}),Object.defineProperty(t,"Vec4Uniform",{enumerable:!0,get:function(){return a.Vec4Uniform}}),Object.defineProperty(t,"ViewMatUniform",{enumerable:!0,get:function(){return a.ViewMatUniform}})},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Mat4Attribute=t.Mat3Attribute=t.Mat2Attribute=t.Vec4Attribute=t.Vec3Attribute=t.Vec2Attribute=t.FloatAttribute=t.Attribute=void 0;const n=r(0);class i{constructor(e,t,r){this.name_=e,this.dimension_=t,this.data_=r,Array.isArray(this.data_)&&!isNaN(this.data_[0])&&(this.data_=new Float32Array(this.data_))}send(e,t){this.buffer_||(this.buffer_=e.createBuffer()),n.sendAttribute(e,t,this.buffer_,this.name_,this.data_,this.dimension_)}length(){if(this.data_ instanceof Float32Array){let e=this.data_.byteLength/this.data_.BYTES_PER_ELEMENT;return e/=this.dimension_,e}return this.data_.length/this.dimension_}}t.Attribute=i;const o=e=>(t,r)=>new i(t,e,r);t.FloatAttribute=o(1),t.Vec2Attribute=o(2),t.Vec3Attribute=o(3),t.Vec4Attribute=o(4);class a extends i{constructor(e,t,r){super(e,t,r),Array.isArray(r[0])&&Array.isArray(r[0][0])&&(this.data_=this.data_.map(e=>new Float32Array(e)))}send(e,t){this.buffer_||(this.buffer_=e.createBuffer()),n.sendMatrixAttribute(e,t,this.buffer_,this.name_,this.data_,this.dimension_)}}const s=e=>(t,r)=>new a(t,e,r);t.Mat2Attribute=s(2),t.Mat3Attribute=s(3),t.Mat4Attribute=s(4)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CUBE_NORMALS=t.CUBE_TEX_COORDS=t.CUBE_INDICES=t.CUBE_VERTICES=t.PLANE_TEX_COORDS=t.PLANE_VERTICES=void 0,t.PLANE_VERTICES=new Float32Array([-1,1,1,1,-1,-1,1,-1]),t.PLANE_TEX_COORDS=new Float32Array([0,1,1,1,0,0,1,0]),t.CUBE_VERTICES=new Float32Array([-1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1]),t.CUBE_INDICES=new Uint16Array([0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,12,13,14,12,14,15,16,17,18,16,18,19,20,21,22,20,22,23]),t.CUBE_TEX_COORDS=new Float32Array([0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,1]),t.CUBE_NORMALS=new Float32Array([0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0])},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Shader=void 0;const n=r(0),i=r(2),o={attributes:[],uniforms:[],mode:WebGLRenderingContext.TRIANGLE_STRIP,clear:!0},a=e=>[0,0,e.width,e.height],s=new WeakMap,u=new WeakMap,f=(e,t,r,f,c,m,d)=>{const{gl:_,program:l}=((e,t,r,i)=>{let o=s.get(e);if(!o){const a=n.glContext(t);o={gl:a,program:n.glProgram(a,r,i)},s.set(e,o)}return o})(e,t,r,f);((e,t,r,n)=>{for(const o of n){if(!i.isTextureUniform(o))continue;o.prepare(e,t);const n=u.get(o);if(n){u.delete(o);for(const e of n)e(r)}}})(_,l,t,d.uniforms),_.useProgram(l),_.bindFramebuffer(_.FRAMEBUFFER,c),_.bindRenderbuffer(_.RENDERBUFFER,m),((e,t,r)=>{let i;for(const n of r.attributes){if(isNaN(i))i=n.length();else if(n.length()!=i)throw new Error("Mismatched attrbute size");n.send(e,t)}for(const n of r.uniforms)n.send(e,t);r.indices&&n.sendIndices(e,r.indices)})(_,l,d),n.glRender(_,(e=>e.indices?e.indices.length:e.attributes[0].length())(d),(e=>void 0===e.clear||e.clear)(d),d.viewport||a(t),d.mode||o.mode,!!d.indices)},c=(e,t,r,o,s)=>u=>{i.isCubeTextureUniform(t)?((e,t,r,o,s,u)=>{if(!(o instanceof i.CubeCameraUniformImpl))throw new Error("Not implemented");{const i=n.glContext(t),c=r.viewport||a(t),{frameBuffer:m,renderBuffer:d}=o.buffers(i,c);o.render(n=>{f(e,t,s,u,m[n],d[n],r)})}})(e,u,s,t,r,o):((e,t,r,i,o,s)=>{const u=n.glContext(t),c=r.viewport||a(t),{frameBuffer:m,renderBuffer:d}=i.buffers(u,c);f(e,t,o,s,m,d,r)})(e,u,s,t,r,o)};t.Shader=(e,t,r)=>{var n;if(!r||!(null===(n=r.attributes)||void 0===n?void 0:n.length))throw new Error("Shaders require at least one attribute");const o={};return n=>{if(n instanceof HTMLCanvasElement)return f(o,n,e,t,null,null,r),n;if(i.isTextureUniform(n))return((e,t)=>{let r=u.get(e);r||(r=[],u.set(e,r)),r.push(t)})(n,c(o,n,e,t,r)),n;throw new Error("Shader function must be called with a canvas or texture uniform")}}}]); | ||
//# sourceMappingURL=index.js.map |
@@ -22,4 +22,6 @@ /** | ||
* Create a shader function to render to a target. | ||
* | ||
* TODO validation for arguments | ||
*/ | ||
export declare const Shader: (vertexSrc: string, fragmentSrc: string, opts: ShaderOptions) => ShaderFunc; | ||
export {}; |
@@ -89,3 +89,3 @@ /** | ||
translation(): Vector3; | ||
matrix(): Matrix4; | ||
private matrix_; | ||
scale(...args: number[]): void; | ||
@@ -92,0 +92,0 @@ setScale(...args: number[]): void; |
{ | ||
"name": "phixl", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "A functional WebGL library for rendering WebGL shaders", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
148319
673
1