| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346 |
- /**
- * @Author: Caven
- * @Date: 2021-05-01 17:38:47
- */
-
- const __indexOf =
- [].indexOf ||
- function(item) {
- for (let i = 0, l = this.length; i < l; i++) {
- if (i in this && this[i] === item) return i
- }
- return -1
- }
-
- const vertexShaderBlit =
- 'attribute vec4 position;\nvarying vec2 texcoord;\nvoid main(){\n texcoord = position.xy*0.5+0.5;\n gl_Position = position;\n}'
-
- const fragmentShaderBlit =
- '#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp int;\n precision highp float;\n#else\n precision mediump int;\n precision mediump float;\n#endif\nuniform sampler2D source;\nvarying vec2 texcoord;'
-
- const nukeVendorPrefix = function() {
- let getExtension, getSupportedExtensions, vendorRe, vendors
- if (window.WebGLRenderingContext != null) {
- vendors = ['WEBKIT', 'MOZ', 'MS', 'O']
- vendorRe = /^WEBKIT_(.*)|MOZ_(.*)|MS_(.*)|O_(.*)/
- getExtension = WebGLRenderingContext.prototype.getExtension
- WebGLRenderingContext.prototype.getExtension = function(name) {
- let extobj, match, vendor, _i, _len
- match = name.match(vendorRe)
- if (match !== null) {
- name = match[1]
- }
- extobj = getExtension.call(this, name)
- if (extobj === null) {
- for (_i = 0, _len = vendors.length; _i < _len; _i++) {
- vendor = vendors[_i]
- extobj = getExtension.call(this, vendor + '_' + name)
- if (extobj !== null) {
- return extobj
- }
- }
- return null
- } else {
- return extobj
- }
- }
- getSupportedExtensions =
- WebGLRenderingContext.prototype.getSupportedExtensions
- return (WebGLRenderingContext.prototype.getSupportedExtensions = function() {
- let extension, match, result, supported, _i, _len
- supported = getSupportedExtensions.call(this)
- result = []
- for (_i = 0, _len = supported.length; _i < _len; _i++) {
- extension = supported[_i]
- match = extension.match(vendorRe)
- if (match !== null) {
- extension = match[1]
- }
- if (__indexOf.call(result, extension) < 0) {
- result.push(extension)
- }
- }
- return result
- })
- }
- }
-
- const textureFloatShims = function() {
- let checkColorBuffer,
- checkFloatLinear,
- checkSupport,
- checkTexture,
- createSourceCanvas,
- getExtension,
- getSupportedExtensions,
- name,
- shimExtensions,
- shimLookup,
- unshimExtensions,
- unshimLookup,
- _i,
- _len
- createSourceCanvas = function() {
- let canvas, ctx, imageData
- canvas = document.createElement('canvas')
- canvas.width = 2
- canvas.height = 2
- ctx = canvas.getContext('2d')
- imageData = ctx.getImageData(0, 0, 2, 2)
- imageData.data.set(
- new Uint8ClampedArray([
- 0,
- 0,
- 0,
- 0,
- 255,
- 255,
- 255,
- 255,
- 0,
- 0,
- 0,
- 0,
- 255,
- 255,
- 255,
- 255
- ])
- )
- ctx.putImageData(imageData, 0, 0)
- return canvas
- }
- createSourceCanvas()
- checkFloatLinear = function(gl, sourceType) {
- let buffer,
- cleanup,
- fragmentShader,
- framebuffer,
- positionLoc,
- program,
- readBuffer,
- result,
- source,
- sourceCanvas,
- sourceLoc,
- target,
- vertexShader,
- vertices
- program = gl.createProgram()
- vertexShader = gl.createShader(gl.VERTEX_SHADER)
- gl.attachShader(program, vertexShader)
- gl.shaderSource(
- vertexShader,
- 'attribute vec2 position;\nvoid main(){\n gl_Position = vec4(position, 0.0, 1.0);\n}'
- )
- gl.compileShader(vertexShader)
- if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
- throw gl.getShaderInfoLog(vertexShader)
- }
- fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
- gl.attachShader(program, fragmentShader)
- gl.shaderSource(
- fragmentShader,
- 'uniform sampler2D source;\nvoid main(){\n gl_FragColor = texture2D(source, vec2(1.0, 1.0));\n}'
- )
- gl.compileShader(fragmentShader)
- if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
- throw gl.getShaderInfoLog(fragmentShader)
- }
- gl.linkProgram(program)
- if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
- throw gl.getProgramInfoLog(program)
- }
- gl.useProgram(program)
- cleanup = function() {
- gl.deleteShader(fragmentShader)
- gl.deleteShader(vertexShader)
- gl.deleteProgram(program)
- gl.deleteBuffer(buffer)
- gl.deleteTexture(source)
- gl.deleteTexture(target)
- gl.deleteFramebuffer(framebuffer)
- gl.bindBuffer(gl.ARRAY_BUFFER, null)
- gl.useProgram(null)
- gl.bindTexture(gl.TEXTURE_2D, null)
- return gl.bindFramebuffer(gl.FRAMEBUFFER, null)
- }
- target = gl.createTexture()
- gl.bindTexture(gl.TEXTURE_2D, target)
- gl.texImage2D(
- gl.TEXTURE_2D,
- 0,
- gl.RGBA,
- 2,
- 2,
- 0,
- gl.RGBA,
- gl.UNSIGNED_BYTE,
- null
- )
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
- framebuffer = gl.createFramebuffer()
- gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)
- gl.framebufferTexture2D(
- gl.FRAMEBUFFER,
- gl.COLOR_ATTACHMENT0,
- gl.TEXTURE_2D,
- target,
- 0
- )
- sourceCanvas = createSourceCanvas()
- source = gl.createTexture()
- gl.bindTexture(gl.TEXTURE_2D, source)
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, sourceType, sourceCanvas)
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
- vertices = new Float32Array([1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1])
- buffer = gl.createBuffer()
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
- gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)
- positionLoc = gl.getAttribLocation(program, 'position')
- sourceLoc = gl.getUniformLocation(program, 'source')
- gl.enableVertexAttribArray(positionLoc)
- gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0)
- gl.uniform1i(sourceLoc, 0)
- gl.drawArrays(gl.TRIANGLES, 0, 6)
- readBuffer = new Uint8Array(4 * 4)
- gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, readBuffer)
- result = Math.abs(readBuffer[0] - 127) < 10
- cleanup()
- return result
- }
- checkTexture = function(gl, targetType) {
- let target
- target = gl.createTexture()
- gl.bindTexture(gl.TEXTURE_2D, target)
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, targetType, null)
- if (gl.getError() === 0) {
- gl.deleteTexture(target)
- return true
- } else {
- gl.deleteTexture(target)
- return false
- }
- }
- checkColorBuffer = function(gl, targetType) {
- let check, framebuffer, target
- target = gl.createTexture()
- gl.bindTexture(gl.TEXTURE_2D, target)
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, targetType, null)
- framebuffer = gl.createFramebuffer()
- gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)
- gl.framebufferTexture2D(
- gl.FRAMEBUFFER,
- gl.COLOR_ATTACHMENT0,
- gl.TEXTURE_2D,
- target,
- 0
- )
- check = gl.checkFramebufferStatus(gl.FRAMEBUFFER)
- gl.deleteTexture(target)
- gl.deleteFramebuffer(framebuffer)
- gl.bindTexture(gl.TEXTURE_2D, null)
- gl.bindFramebuffer(gl.FRAMEBUFFER, null)
- if (check === gl.FRAMEBUFFER_COMPLETE) {
- return true
- } else {
- return false
- }
- }
- shimExtensions = []
- shimLookup = {}
- unshimExtensions = []
- checkSupport = function() {
- let canvas,
- extobj,
- gl,
- halfFloatExt,
- halfFloatTexturing,
- singleFloatExt,
- singleFloatTexturing
- canvas = document.createElement('canvas')
- gl = null
- try {
- gl = canvas.getContext('experimental-webgl')
- if (gl === null) {
- gl = canvas.getContext('webgl')
- }
- // eslint-disable-next-line no-empty
- } catch (_error) {}
- if (gl != null) {
- singleFloatExt = gl.getExtension('OES_texture_float')
- if (singleFloatExt === null) {
- if (checkTexture(gl, gl.FLOAT)) {
- singleFloatTexturing = true
- shimExtensions.push('OES_texture_float')
- shimLookup.OES_texture_float = {
- shim: true
- }
- } else {
- singleFloatTexturing = false
- unshimExtensions.push('OES_texture_float')
- }
- } else {
- if (checkTexture(gl, gl.FLOAT)) {
- singleFloatTexturing = true
- shimExtensions.push('OES_texture_float')
- } else {
- singleFloatTexturing = false
- unshimExtensions.push('OES_texture_float')
- }
- }
- if (singleFloatTexturing) {
- extobj = gl.getExtension('WEBGL_color_buffer_float')
- if (extobj === null) {
- if (checkColorBuffer(gl, gl.FLOAT)) {
- shimExtensions.push('WEBGL_color_buffer_float')
- shimLookup.WEBGL_color_buffer_float = {
- shim: true,
- RGBA32F_EXT: 0x8814,
- RGB32F_EXT: 0x8815,
- FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211,
- UNSIGNED_NORMALIZED_EXT: 0x8c17
- }
- } else {
- unshimExtensions.push('WEBGL_color_buffer_float')
- }
- } else {
- if (checkColorBuffer(gl, gl.FLOAT)) {
- shimExtensions.push('WEBGL_color_buffer_float')
- } else {
- unshimExtensions.push('WEBGL_color_buffer_float')
- }
- }
- extobj = gl.getExtension('OES_texture_float_linear')
- if (extobj === null) {
- if (checkFloatLinear(gl, gl.FLOAT)) {
- shimExtensions.push('OES_texture_float_linear')
- shimLookup.OES_texture_float_linear = {
- shim: true
- }
- } else {
- unshimExtensions.push('OES_texture_float_linear')
- }
- } else {
- if (checkFloatLinear(gl, gl.FLOAT)) {
- shimExtensions.push('OES_texture_float_linear')
- } else {
- unshimExtensions.push('OES_texture_float_linear')
- }
- }
- }
- halfFloatExt = gl.getExtension('OES_texture_half_float')
- if (halfFloatExt === null) {
- if (checkTexture(gl, 0x8d61)) {
- halfFloatTexturing = true
- shimExtensions.push('OES_texture_half_float')
- halfFloatExt = shimLookup.OES_texture_half_float = {
- HALF_FLOAT_OES: 0x8d61,
- shim: true
- }
- } else {
- halfFloatTexturing = false
- unshimExtensions.push('OES_texture_half_float')
- }
- } else {
- if (checkTexture(gl, halfFloatExt.HALF_FLOAT_OES)) {
- halfFloatTexturing = true
- shimExtensions.push('OES_texture_half_float')
- } else {
- halfFloatTexturing = false
- unshimExtensions.push('OES_texture_half_float')
- }
- }
- if (halfFloatTexturing) {
- extobj = gl.getExtension('EXT_color_buffer_half_float')
- if (extobj === null) {
- if (checkColorBuffer(gl, halfFloatExt.HALF_FLOAT_OES)) {
- shimExtensions.push('EXT_color_buffer_half_float')
- shimLookup.EXT_color_buffer_half_float = {
- shim: true,
- RGBA16F_EXT: 0x881a,
- RGB16F_EXT: 0x881b,
- FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211,
- UNSIGNED_NORMALIZED_EXT: 0x8c17
- }
- } else {
- unshimExtensions.push('EXT_color_buffer_half_float')
- }
- } else {
- if (checkColorBuffer(gl, halfFloatExt.HALF_FLOAT_OES)) {
- shimExtensions.push('EXT_color_buffer_half_float')
- } else {
- unshimExtensions.push('EXT_color_buffer_half_float')
- }
- }
- extobj = gl.getExtension('OES_texture_half_float_linear')
- if (extobj === null) {
- if (checkFloatLinear(gl, halfFloatExt.HALF_FLOAT_OES)) {
- shimExtensions.push('OES_texture_half_float_linear')
- return (shimLookup.OES_texture_half_float_linear = {
- shim: true
- })
- } else {
- return unshimExtensions.push('OES_texture_half_float_linear')
- }
- } else {
- if (checkFloatLinear(gl, halfFloatExt.HALF_FLOAT_OES)) {
- return shimExtensions.push('OES_texture_half_float_linear')
- } else {
- return unshimExtensions.push('OES_texture_half_float_linear')
- }
- }
- }
- }
- }
- if (window.WebGLRenderingContext != null) {
- checkSupport()
- unshimLookup = {}
- for (_i = 0, _len = unshimExtensions.length; _i < _len; _i++) {
- name = unshimExtensions[_i]
- unshimLookup[name] = true
- }
- getExtension = WebGLRenderingContext.prototype.getExtension
- WebGLRenderingContext.prototype.getExtension = function(name) {
- let extobj
- extobj = shimLookup[name]
- if (extobj === void 0) {
- if (unshimLookup[name]) {
- return null
- } else {
- return getExtension.call(this, name)
- }
- } else {
- return extobj
- }
- }
- getSupportedExtensions =
- WebGLRenderingContext.prototype.getSupportedExtensions
- WebGLRenderingContext.prototype.getSupportedExtensions = function() {
- let extension, result, supported, _j, _k, _len1, _len2
- supported = getSupportedExtensions.call(this)
- result = []
- for (_j = 0, _len1 = supported.length; _j < _len1; _j++) {
- extension = supported[_j]
- if (unshimLookup[extension] === void 0) {
- result.push(extension)
- }
- }
- for (_k = 0, _len2 = shimExtensions.length; _k < _len2; _k++) {
- extension = shimExtensions[_k]
- if (__indexOf.call(result, extension) < 0) {
- result.push(extension)
- }
- }
- return result
- }
- return (WebGLRenderingContext.prototype.getFloatExtension = function(spec) {
- let candidate,
- candidates,
- half,
- halfFramebuffer,
- halfLinear,
- halfTexture,
- i,
- importance,
- preference,
- result,
- single,
- singleFramebuffer,
- singleLinear,
- singleTexture,
- use,
- _j,
- _k,
- _l,
- _len1,
- _len2,
- _len3,
- _len4,
- _m,
- _ref,
- _ref1,
- _ref2
- if (spec.prefer == null) {
- spec.prefer = ['half']
- }
- if (spec.require == null) {
- spec.require = []
- }
- if (spec.throws == null) {
- spec.throws = true
- }
- singleTexture = this.getExtension('OES_texture_float')
- halfTexture = this.getExtension('OES_texture_half_float')
- singleFramebuffer = this.getExtension('WEBGL_color_buffer_float')
- halfFramebuffer = this.getExtension('EXT_color_buffer_half_float')
- singleLinear = this.getExtension('OES_texture_float_linear')
- halfLinear = this.getExtension('OES_texture_half_float_linear')
- single = {
- texture: singleTexture !== null,
- filterable: singleLinear !== null,
- renderable: singleFramebuffer !== null,
- score: 0,
- precision: 'single',
- half: false,
- single: true,
- type: this.FLOAT
- }
- half = {
- texture: halfTexture !== null,
- filterable: halfLinear !== null,
- renderable: halfFramebuffer !== null,
- score: 0,
- precision: 'half',
- half: true,
- single: false,
- type:
- (_ref = halfTexture != null ? halfTexture.HALF_FLOAT_OES : void 0) !=
- null
- ? _ref
- : null
- }
- candidates = []
- if (single.texture) {
- candidates.push(single)
- }
- if (half.texture) {
- candidates.push(half)
- }
- result = []
- for (_j = 0, _len1 = candidates.length; _j < _len1; _j++) {
- candidate = candidates[_j]
- use = true
- _ref1 = spec.require
- for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
- name = _ref1[_k]
- if (candidate[name] === false) {
- use = false
- }
- }
- if (use) {
- result.push(candidate)
- }
- }
- for (_l = 0, _len3 = result.length; _l < _len3; _l++) {
- candidate = result[_l]
- _ref2 = spec.prefer
- for (i = _m = 0, _len4 = _ref2.length; _m < _len4; i = ++_m) {
- preference = _ref2[i]
- importance = Math.pow(2, spec.prefer.length - i - 1)
- if (candidate[preference]) {
- candidate.score += importance
- }
- }
- }
- result.sort(function(a, b) {
- if (a.score === b.score) {
- return 0
- } else if (a.score < b.score) {
- return 1
- } else if (a.score > b.score) {
- return -1
- }
- })
- if (result.length === 0) {
- if (spec.throws) {
- throw 'No floating point texture support that is ' +
- spec.require.join(', ')
- } else {
- return null
- }
- } else {
- result = result[0]
- return {
- filterable: result.filterable,
- renderable: result.renderable,
- type: result.type,
- precision: result.precision
- }
- }
- })
- }
- }
-
- nukeVendorPrefix()
-
- textureFloatShims()
-
- const Shader = (function() {
- function Shader(gl, _arg) {
- let fragment, vertex
- this.gl = gl
- vertex = _arg.vertex
- fragment = _arg.fragment
- this.program = this.gl.createProgram()
- this.vs = this.gl.createShader(this.gl.VERTEX_SHADER)
- this.fs = this.gl.createShader(this.gl.FRAGMENT_SHADER)
- this.gl.attachShader(this.program, this.vs)
- this.gl.attachShader(this.program, this.fs)
- this.compileShader(this.vs, vertex)
- this.compileShader(this.fs, fragment)
- this.link()
- this.value_cache = {}
- this.uniform_cache = {}
- this.attribCache = {}
- }
-
- Shader.prototype.attribLocation = function(name) {
- let location = this.attribCache[name]
- if (location === void 0) {
- location = this.attribCache[name] = this.gl.getAttribLocation(
- this.program,
- name
- )
- }
- return location
- }
-
- Shader.prototype.compileShader = function(shader, source) {
- this.gl.shaderSource(shader, source)
- this.gl.compileShader(shader)
- if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
- throw 'Shader Compile Error: ' + this.gl.getShaderInfoLog(shader)
- }
- }
-
- Shader.prototype.link = function() {
- this.gl.linkProgram(this.program)
- if (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {
- throw 'Shader Link Error: ' + this.gl.getProgramInfoLog(this.program)
- }
- }
-
- Shader.prototype.use = function() {
- this.gl.useProgram(this.program)
- return this
- }
-
- Shader.prototype.uniformLoc = function(name) {
- let location = this.uniform_cache[name]
- if (location === void 0) {
- location = this.uniform_cache[name] = this.gl.getUniformLocation(
- this.program,
- name
- )
- }
- return location
- }
-
- Shader.prototype.int = function(name, value) {
- let cached, loc
- cached = this.value_cache[name]
- if (cached !== value) {
- this.value_cache[name] = value
- loc = this.uniformLoc(name)
- if (loc) {
- this.gl.uniform1i(loc, value)
- }
- }
- return this
- }
-
- Shader.prototype.vec2 = function(name, a, b) {
- let loc
- loc = this.uniformLoc(name)
- if (loc) {
- this.gl.uniform2f(loc, a, b)
- }
- return this
- }
-
- Shader.prototype.float = function(name, value) {
- let cached, loc
- cached = this.value_cache[name]
- if (cached !== value) {
- this.value_cache[name] = value
- loc = this.uniformLoc(name)
- if (loc) {
- this.gl.uniform1f(loc, value)
- }
- }
- return this
- }
-
- return Shader
- })()
-
- const Framebuffer = (function() {
- function Framebuffer(gl) {
- this.gl = gl
- this.buffer = this.gl.createFramebuffer()
- }
-
- Framebuffer.prototype.destroy = function() {
- return this.gl.deleteFRamebuffer(this.buffer)
- }
-
- Framebuffer.prototype.bind = function() {
- this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.buffer)
- return this
- }
-
- Framebuffer.prototype.unbind = function() {
- this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null)
- return this
- }
-
- Framebuffer.prototype.check = function() {
- let result
- result = this.gl.checkFramebufferStatus(this.gl.FRAMEBUFFER)
- switch (result) {
- case this.gl.FRAMEBUFFER_UNSUPPORTED:
- throw 'Framebuffer is unsupported'
- // eslint-disable-next-line no-unreachable
- break
- case this.gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- throw 'Framebuffer incomplete attachment'
- // eslint-disable-next-line no-unreachable
- break
- case this.gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- throw 'Framebuffer incomplete dimensions'
- // eslint-disable-next-line no-unreachable
- break
- case this.gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- throw 'Framebuffer incomplete missing attachment'
- }
- return this
- }
-
- Framebuffer.prototype.color = function(texture) {
- this.gl.framebufferTexture2D(
- this.gl.FRAMEBUFFER,
- this.gl.COLOR_ATTACHMENT0,
- texture.target,
- texture.handle,
- 0
- )
- this.check()
- return this
- }
-
- Framebuffer.prototype.depth = function(buffer) {
- this.gl.framebufferRenderbuffer(
- this.gl.FRAMEBUFFER,
- this.gl.DEPTH_ATTACHMENT,
- this.gl.RENDERBUFFER,
- buffer.id
- )
- this.check()
- return this
- }
-
- Framebuffer.prototype.destroy = function() {
- return this.gl.deleteFramebuffer(this.buffer)
- }
-
- return Framebuffer
- })()
-
- const Texture = (function() {
- function Texture(gl, params) {
- let _ref, _ref1
- this.gl = gl
- if (params == null) {
- params = {}
- }
- this.channels = this.gl[
- ((_ref = params.channels) != null ? _ref : 'rgba').toUpperCase()
- ]
- if (typeof params.type === 'number') {
- this.type = params.type
- } else {
- this.type = this.gl[
- ((_ref1 = params.type) != null ? _ref1 : 'unsigned_byte').toUpperCase()
- ]
- }
- switch (this.channels) {
- case this.gl.RGBA:
- this.chancount = 4
- break
- case this.gl.RGB:
- this.chancount = 3
- break
- case this.gl.LUMINANCE_ALPHA:
- this.chancount = 2
- break
- default:
- this.chancount = 1
- }
- this.target = this.gl.TEXTURE_2D
- this.handle = this.gl.createTexture()
- }
-
- Texture.prototype.destroy = function() {
- return this.gl.deleteTexture(this.handle)
- }
-
- Texture.prototype.bind = function(unit) {
- if (unit == null) {
- unit = 0
- }
- if (unit > 15) {
- throw 'Texture unit too large: ' + unit
- }
- this.gl.activeTexture(this.gl.TEXTURE0 + unit)
- this.gl.bindTexture(this.target, this.handle)
- return this
- }
-
- Texture.prototype.setSize = function(width, height) {
- this.width = width
- this.height = height
- this.gl.texImage2D(
- this.target,
- 0,
- this.channels,
- this.width,
- this.height,
- 0,
- this.channels,
- this.type,
- null
- )
- return this
- }
-
- Texture.prototype.upload = function(data) {
- this.width = data.width
- this.height = data.height
- this.gl.texImage2D(
- this.target,
- 0,
- this.channels,
- this.channels,
- this.type,
- data
- )
- return this
- }
-
- Texture.prototype.linear = function() {
- this.gl.texParameteri(
- this.target,
- this.gl.TEXTURE_MAG_FILTER,
- this.gl.LINEAR
- )
- this.gl.texParameteri(
- this.target,
- this.gl.TEXTURE_MIN_FILTER,
- this.gl.LINEAR
- )
- return this
- }
-
- Texture.prototype.nearest = function() {
- this.gl.texParameteri(
- this.target,
- this.gl.TEXTURE_MAG_FILTER,
- this.gl.NEAREST
- )
- this.gl.texParameteri(
- this.target,
- this.gl.TEXTURE_MIN_FILTER,
- this.gl.NEAREST
- )
- return this
- }
-
- Texture.prototype.clampToEdge = function() {
- this.gl.texParameteri(
- this.target,
- this.gl.TEXTURE_WRAP_S,
- this.gl.CLAMP_TO_EDGE
- )
- this.gl.texParameteri(
- this.target,
- this.gl.TEXTURE_WRAP_T,
- this.gl.CLAMP_TO_EDGE
- )
- return this
- }
-
- Texture.prototype.repeat = function() {
- this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_S, this.gl.REPEAT)
- this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_T, this.gl.REPEAT)
- return this
- }
-
- return Texture
- })()
-
- const Node = (function() {
- function Node(gl, width, height) {
- let floatExt
- this.gl = gl
- this.width = width
- this.height = height
- floatExt = this.gl.getFloatExtension({
- require: ['renderable']
- })
- this.texture = new Texture(this.gl, {
- type: floatExt.type
- })
- .bind(0)
- .setSize(this.width, this.height)
- .nearest()
- .clampToEdge()
- this.fbo = new Framebuffer(this.gl)
- .bind()
- .color(this.texture)
- .unbind()
- }
-
- Node.prototype.use = function() {
- return this.fbo.bind()
- }
-
- Node.prototype.bind = function(unit) {
- return this.texture.bind(unit)
- }
-
- Node.prototype.end = function() {
- return this.fbo.unbind()
- }
-
- Node.prototype.resize = function(width, height) {
- this.width = width
- this.height = height
- return this.texture.bind(0).setSize(this.width, this.height)
- }
-
- return Node
- })()
-
- const Heights = (function() {
- function Heights(heatmap, gl, width, height) {
- let i, _i, _ref
- this.heatmap = heatmap
- this.gl = gl
- this.width = width
- this.height = height
- this.shader = new Shader(this.gl, {
- vertex:
- 'attribute vec4 position, intensity;\nvarying vec2 off, dim;\nvarying float vIntensity;\nuniform vec2 viewport;\n\nvoid main(){\n dim = abs(position.zw);\n off = position.zw;\n vec2 pos = position.xy + position.zw;\n vIntensity = intensity.x;\n gl_Position = vec4((pos/viewport)*2.0-1.0, 0.0, 1.0);\n}',
- fragment:
- '#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp int;\n precision highp float;\n#else\n precision mediump int;\n precision mediump float;\n#endif\nvarying vec2 off, dim;\nvarying float vIntensity;\nvoid main(){\n float falloff = (1.0 - smoothstep(0.0, 1.0, length(off/dim)));\n float intensity = falloff*vIntensity;\n gl_FragColor = vec4(intensity);\n}'
- })
- this.clampShader = new Shader(this.gl, {
- vertex: vertexShaderBlit,
- fragment:
- fragmentShaderBlit +
- 'uniform float low, high;\nvoid main(){\n gl_FragColor = vec4(clamp(texture2D(source, texcoord).rgb, low, high), 1.0);\n}'
- })
- this.multiplyShader = new Shader(this.gl, {
- vertex: vertexShaderBlit,
- fragment:
- fragmentShaderBlit +
- 'uniform float value;\nvoid main(){\n gl_FragColor = vec4(texture2D(source, texcoord).rgb*value, 1.0);\n}'
- })
- this.blurShader = new Shader(this.gl, {
- vertex: vertexShaderBlit,
- fragment:
- fragmentShaderBlit +
- 'uniform vec2 viewport;\nvoid main(){\n vec4 result = vec4(0.0);\n for(int x=-1; x<=1; x++){\n for(int y=-1; y<=1; y++){\n vec2 off = vec2(x,y)/viewport;\n //float factor = 1.0 - smoothstep(0.0, 1.5, length(off));\n float factor = 1.0;\n result += vec4(texture2D(source, texcoord+off).rgb*factor, factor);\n }\n }\n gl_FragColor = vec4(result.rgb/result.w, 1.0);\n}'
- })
- this.nodeBack = new Node(this.gl, this.width, this.height)
- this.nodeFront = new Node(this.gl, this.width, this.height)
- this.vertexBuffer = this.gl.createBuffer()
- this.vertexSize = 8
- this.maxPointCount = 1024 * 10
- this.vertexBufferData = new Float32Array(
- this.maxPointCount * this.vertexSize * 6
- )
- this.vertexBufferViews = []
- for (
- i = _i = 0, _ref = this.maxPointCount;
- 0 <= _ref ? _i < _ref : _i > _ref;
- i = 0 <= _ref ? ++_i : --_i
- ) {
- this.vertexBufferViews.push(
- new Float32Array(
- this.vertexBufferData.buffer,
- 0,
- i * this.vertexSize * 6
- )
- )
- }
- this.bufferIndex = 0
- this.pointCount = 0
- }
-
- Heights.prototype.resize = function(width, height) {
- this.width = width
- this.height = height
- this.nodeBack.resize(this.width, this.height)
- return this.nodeFront.resize(this.width, this.height)
- }
-
- Heights.prototype.update = function() {
- var intensityLoc, positionLoc
- if (this.pointCount > 0) {
- this.gl.enable(this.gl.BLEND)
- this.nodeFront.use()
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer)
- this.gl.bufferData(
- this.gl.ARRAY_BUFFER,
- this.vertexBufferViews[this.pointCount],
- this.gl.STREAM_DRAW
- )
- positionLoc = this.shader.attribLocation('position')
- intensityLoc = this.shader.attribLocation('intensity')
- this.gl.enableVertexAttribArray(1)
- this.gl.vertexAttribPointer(
- positionLoc,
- 4,
- this.gl.FLOAT,
- false,
- 8 * 4,
- 0
- )
- this.gl.vertexAttribPointer(
- intensityLoc,
- 4,
- this.gl.FLOAT,
- false,
- 8 * 4,
- 4 * 4
- )
- this.shader.use().vec2('viewport', this.width, this.height)
- this.gl.drawArrays(this.gl.TRIANGLES, 0, this.pointCount * 6)
- this.gl.disableVertexAttribArray(1)
- this.pointCount = 0
- this.bufferIndex = 0
- this.nodeFront.end()
- return this.gl.disable(this.gl.BLEND)
- }
- }
-
- Heights.prototype.clear = function() {
- this.nodeFront.use()
- this.gl.clearColor(0, 0, 0, 1)
- this.gl.clear(this.gl.COLOR_BUFFER_BIT)
- return this.nodeFront.end()
- }
-
- Heights.prototype.clamp = function(min, max) {
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.heatmap.quad)
- this.gl.vertexAttribPointer(0, 4, this.gl.FLOAT, false, 0, 0)
- this.nodeFront.bind(0)
- this.nodeBack.use()
- this.clampShader
- .use()
- .int('source', 0)
- .float('low', min)
- .float('high', max)
- this.gl.drawArrays(this.gl.TRIANGLES, 0, 6)
- this.nodeBack.end()
- return this.swap()
- }
-
- Heights.prototype.multiply = function(value) {
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.heatmap.quad)
- this.gl.vertexAttribPointer(0, 4, this.gl.FLOAT, false, 0, 0)
- this.nodeFront.bind(0)
- this.nodeBack.use()
- this.multiplyShader
- .use()
- .int('source', 0)
- .float('value', value)
- this.gl.drawArrays(this.gl.TRIANGLES, 0, 6)
- this.nodeBack.end()
- return this.swap()
- }
-
- Heights.prototype.blur = function() {
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.heatmap.quad)
- this.gl.vertexAttribPointer(0, 4, this.gl.FLOAT, false, 0, 0)
- this.nodeFront.bind(0)
- this.nodeBack.use()
- this.blurShader
- .use()
- .int('source', 0)
- .vec2('viewport', this.width, this.height)
- this.gl.drawArrays(this.gl.TRIANGLES, 0, 6)
- this.nodeBack.end()
- return this.swap()
- }
-
- Heights.prototype.swap = function() {
- let tmp = this.nodeFront
- this.nodeFront = this.nodeBack
- return (this.nodeBack = tmp)
- }
-
- Heights.prototype.addVertex = function(x, y, xs, ys, intensity) {
- this.vertexBufferData[this.bufferIndex++] = x
- this.vertexBufferData[this.bufferIndex++] = y
- this.vertexBufferData[this.bufferIndex++] = xs
- this.vertexBufferData[this.bufferIndex++] = ys
- this.vertexBufferData[this.bufferIndex++] = intensity
- this.vertexBufferData[this.bufferIndex++] = intensity
- this.vertexBufferData[this.bufferIndex++] = intensity
- return (this.vertexBufferData[this.bufferIndex++] = intensity)
- }
-
- Heights.prototype.addPoint = function(x, y, size, intensity) {
- let s
- if (size == null) {
- size = 50
- }
- if (intensity == null) {
- intensity = 0.2
- }
- if (this.pointCount >= this.maxPointCount - 1) {
- this.update()
- }
- y = this.height - y
- s = size / 2
- this.addVertex(x, y, -s, -s, intensity)
- this.addVertex(x, y, +s, -s, intensity)
- this.addVertex(x, y, -s, +s, intensity)
- this.addVertex(x, y, -s, +s, intensity)
- this.addVertex(x, y, +s, -s, intensity)
- this.addVertex(x, y, +s, +s, intensity)
- return (this.pointCount += 1)
- }
-
- return Heights
- })()
-
- const WebGLHeatmap = (function() {
- function WebGLHeatmap(_arg) {
- let alphaEnd,
- alphaRange,
- alphaStart,
- error,
- getColorFun,
- gradientTexture,
- image,
- intensityToAlpha,
- output,
- quad,
- textureGradient,
- _ref,
- _ref1
- ;(_ref = _arg != null ? _arg : {}),
- (this.canvas = _ref.canvas),
- (this.width = _ref.width),
- (this.height = _ref.height),
- (intensityToAlpha = _ref.intensityToAlpha),
- (gradientTexture = _ref.gradientTexture),
- (alphaRange = _ref.alphaRange)
- if (!this.canvas) {
- this.canvas = document.createElement('canvas')
- }
- try {
- this.gl = this.canvas.getContext('experimental-webgl', {
- depth: false,
- antialias: false
- })
- if (this.gl === null) {
- this.gl = this.canvas.getContext('webgl', {
- depth: false,
- antialias: false
- })
- if (this.gl === null) {
- throw 'WebGL not supported'
- }
- }
- } catch (_error) {
- error = _error
- throw 'WebGL not supported'
- }
- if (window.WebGLDebugUtils != null) {
- // eslint-disable-next-line no-undef
- this.gl = WebGLDebugUtils.makeDebugContext(this.gl, function(
- err,
- funcName,
- args
- ) {
- // eslint-disable-next-line no-undef
- throw WebGLDebugUtils.glEnumToString(err) +
- ' was caused by call to: ' +
- funcName
- })
- }
- this.gl.enableVertexAttribArray(0)
- this.gl.blendFunc(this.gl.ONE, this.gl.ONE)
- if (gradientTexture) {
- textureGradient = this.gradientTexture = new Texture(this.gl, {
- channels: 'rgba'
- })
- .bind(0)
- .setSize(2, 2)
- .nearest()
- .clampToEdge()
- if (typeof gradientTexture === 'string') {
- image = new Image()
- image.onload = function() {
- return textureGradient.bind().upload(image)
- }
- image.src = gradientTexture
- } else {
- if (gradientTexture.width > 0 && gradientTexture.height > 0) {
- textureGradient.upload(gradientTexture)
- } else {
- gradientTexture.onload = function() {
- return textureGradient.upload(gradientTexture)
- }
- }
- }
- getColorFun =
- 'uniform sampler2D gradientTexture;\nvec3 getColor(float intensity){\n return texture2D(gradientTexture, vec2(intensity, 0.0)).rgb;\n}'
- } else {
- textureGradient = null
- getColorFun =
- 'vec3 getColor(float intensity){\n vec3 blue = vec3(0.0, 0.0, 1.0);\n vec3 cyan = vec3(0.0, 1.0, 1.0);\n vec3 green = vec3(0.0, 1.0, 0.0);\n vec3 yellow = vec3(1.0, 1.0, 0.0);\n vec3 red = vec3(1.0, 0.0, 0.0);\n\n vec3 color = (\n fade(-0.25, 0.25, intensity)*blue +\n fade(0.0, 0.5, intensity)*cyan +\n fade(0.25, 0.75, intensity)*green +\n fade(0.5, 1.0, intensity)*yellow +\n smoothstep(0.75, 1.0, intensity)*red\n );\n return color;\n}'
- }
- if (intensityToAlpha == null) {
- intensityToAlpha = true
- }
- if (intensityToAlpha) {
- ;(_ref1 = alphaRange != null ? alphaRange : [0, 1]),
- (alphaStart = _ref1[0]),
- (alphaEnd = _ref1[1])
- output =
- 'vec4 alphaFun(vec3 color, float intensity){\n float alpha = smoothstep(' +
- alphaStart.toFixed(8) +
- ', ' +
- alphaEnd.toFixed(8) +
- ', intensity);\n return vec4(color*alpha, alpha);\n}'
- } else {
- output =
- 'vec4 alphaFun(vec3 color, float intensity){\n return vec4(color, 1.0);\n}'
- }
- this.shader = new Shader(this.gl, {
- vertex: vertexShaderBlit,
- fragment:
- fragmentShaderBlit +
- ('float linstep(float low, float high, float value){\n return clamp((value-low)/(high-low), 0.0, 1.0);\n}\n\nfloat fade(float low, float high, float value){\n float mid = (low+high)*0.5;\n float range = (high-low)*0.5;\n float x = 1.0 - clamp(abs(mid-value)/range, 0.0, 1.0);\n return smoothstep(0.0, 1.0, x);\n}\n\n' +
- getColorFun +
- '\n' +
- output +
- '\n\nvoid main(){\n float intensity = smoothstep(0.0, 1.0, texture2D(source, texcoord).r);\n vec3 color = getColor(intensity);\n gl_FragColor = alphaFun(color, intensity);\n}')
- })
- if (this.width == null) {
- this.width = this.canvas.offsetWidth || 2
- }
- if (this.height == null) {
- this.height = this.canvas.offsetHeight || 2
- }
- this.canvas.width = this.width
- this.canvas.height = this.height
- this.gl.viewport(0, 0, this.width, this.height)
- this.quad = this.gl.createBuffer()
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.quad)
- quad = new Float32Array([
- -1,
- -1,
- 0,
- 1,
- 1,
- -1,
- 0,
- 1,
- -1,
- 1,
- 0,
- 1,
- -1,
- 1,
- 0,
- 1,
- 1,
- -1,
- 0,
- 1,
- 1,
- 1,
- 0,
- 1
- ])
- this.gl.bufferData(this.gl.ARRAY_BUFFER, quad, this.gl.STATIC_DRAW)
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null)
- this.heights = new Heights(this, this.gl, this.width, this.height)
- }
-
- WebGLHeatmap.prototype.adjustSize = function() {
- let canvasHeight, canvasWidth
- canvasWidth = this.canvas.offsetWidth || 2
- canvasHeight = this.canvas.offsetHeight || 2
- if (this.width !== canvasWidth || this.height !== canvasHeight) {
- this.gl.viewport(0, 0, canvasWidth, canvasHeight)
- this.canvas.width = canvasWidth
- this.canvas.height = canvasHeight
- this.width = canvasWidth
- this.height = canvasHeight
- return this.heights.resize(this.width, this.height)
- }
- }
-
- WebGLHeatmap.prototype.display = function() {
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.quad)
- this.gl.vertexAttribPointer(0, 4, this.gl.FLOAT, false, 0, 0)
- this.heights.nodeFront.bind(0)
- if (this.gradientTexture) {
- this.gradientTexture.bind(1)
- }
- this.shader
- .use()
- .int('source', 0)
- .int('gradientTexture', 1)
- return this.gl.drawArrays(this.gl.TRIANGLES, 0, 6)
- }
-
- WebGLHeatmap.prototype.update = function() {
- return this.heights.update()
- }
-
- WebGLHeatmap.prototype.clear = function() {
- return this.heights.clear()
- }
-
- WebGLHeatmap.prototype.clamp = function(min, max) {
- if (min == null) {
- min = 0
- }
- if (max == null) {
- max = 1
- }
- return this.heights.clamp(min, max)
- }
-
- WebGLHeatmap.prototype.multiply = function(value) {
- if (value == null) {
- value = 0.95
- }
- return this.heights.multiply(value)
- }
-
- WebGLHeatmap.prototype.blur = function() {
- return this.heights.blur()
- }
-
- WebGLHeatmap.prototype.addPoint = function(x, y, size, intensity) {
- return this.heights.addPoint(x, y, size, intensity)
- }
-
- WebGLHeatmap.prototype.addPoints = function(items) {
- let item, _i, _len, _results
- _results = []
- for (_i = 0, _len = items.length; _i < _len; _i++) {
- item = items[_i]
- _results.push(this.addPoint(item.x, item.y, item.size, item.intensity))
- }
- return _results
- }
-
- return WebGLHeatmap
- })()
-
- export function createWebGLHeatmap(params) {
- return new WebGLHeatmap(params)
- }
|