Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save robertleeplummerjr/52b31665faf62662dd38d0e51e6cc7a1 to your computer and use it in GitHub Desktop.
Save robertleeplummerjr/52b31665faf62662dd38d0e51e6cc7a1 to your computer and use it in GitHub Desktop.
100-over.js
function kernel(context = null) {
const gl = context;
const glVariables0 = gl.getExtension('OES_texture_float');
const glVariables1 = gl.getExtension('OES_texture_float_linear');
const glVariables2 = gl.getExtension('OES_element_index_uint');
const glVariables3 = gl.getExtension('WEBGL_draw_buffers');
const glVariables4 = gl.getExtension('WEBGL_color_buffer_float');
const glVariable5 = gl.createTexture();
const glVariable6 = gl.createTexture();
gl.enable(gl.SCISSOR_TEST);
gl.viewport(0, 0, 1, 1);
const glVariable7 = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(glVariable7, `precision highp float;
precision highp int;
precision highp sampler2D;
attribute vec2 aPos;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
uniform vec2 ratio;
void main(void) {
gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);
vTexCoord = aTexCoord;
}`);
gl.compileShader(glVariable7);
const glVariable8 = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(glVariable8, `#extension GL_EXT_draw_buffers : require
precision highp float;
precision highp int;
precision highp sampler2D;
const int LOOP_MAX = 1000;
uniform ivec3 uOutputDim;
uniform ivec2 uTexSize;
varying vec2 vTexCoord;
vec4 round(vec4 x) {
return floor(x + 0.5);
}
float round(float x) {
return floor(x + 0.5);
}
vec2 integerMod(vec2 x, float y) {
vec2 res = floor(mod(x, y));
return res * step(1.0 - floor(y), -res);
}
vec3 integerMod(vec3 x, float y) {
vec3 res = floor(mod(x, y));
return res * step(1.0 - floor(y), -res);
}
vec4 integerMod(vec4 x, vec4 y) {
vec4 res = floor(mod(x, y));
return res * step(1.0 - floor(y), -res);
}
float integerMod(float x, float y) {
float res = floor(mod(x, y));
return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);
}
int integerMod(int x, int y) {
return x - (y * int(x / y));
}
float div_with_int_check(float x, float y) {
if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {
return float(int(x)/int(y));
}
return x / y;
}
// Here be dragons!
// DO NOT OPTIMIZE THIS CODE
// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE
// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME
const vec2 MAGIC_VEC = vec2(1.0, -256.0);
const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);
const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536
float decode32(vec4 texel) {
texel *= 255.0;
vec2 gte128;
gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;
gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;
float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);
float res = exp2(round(exponent));
texel.b = texel.b - 128.0 * gte128.x;
res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;
res *= gte128.y * -2.0 + 1.0;
return res;
}
float decode16(vec4 texel, int index) {
int channel = integerMod(index, 2);
if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;
if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;
return 0.0;
}
float decode8(vec4 texel, int index) {
int channel = integerMod(index, 4);
if (channel == 0) return texel.r * 255.0;
if (channel == 1) return texel.g * 255.0;
if (channel == 2) return texel.b * 255.0;
if (channel == 3) return texel.a * 255.0;
return 0.0;
}
vec4 encode32(float f) {
float F = abs(f);
float sign = f < 0.0 ? 1.0 : 0.0;
float exponent = floor(log2(F));
float mantissa = (exp2(-exponent) * F);
// exponent += floor(log2(mantissa));
vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;
texel.rg = integerMod(texel.rg, 256.0);
texel.b = integerMod(texel.b, 128.0);
texel.a = exponent*0.5 + 63.5;
texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;
texel = floor(texel);
texel *= 0.003921569; // 1/255
return texel;
}
// Dragons end here
int index;
ivec3 threadId;
ivec3 indexTo3D(int idx, ivec3 texDim) {
int z = int(idx / (texDim.x * texDim.y));
idx -= z * int(texDim.x * texDim.y);
int y = int(idx / texDim.x);
int x = int(integerMod(idx, texDim.x));
return ivec3(x, y, z);
}
float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
ivec3 xyz = ivec3(x, y, z);
int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);
int w = texSize.x;
vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
vec4 texel = texture2D(tex, st / vec2(texSize));
return decode32(texel);
}
float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
ivec3 xyz = ivec3(x, y, z);
int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);
int w = texSize.x * 2;
vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));
return decode16(texel, index);
}
float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
ivec3 xyz = ivec3(x, y, z);
int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);
int w = texSize.x * 4;
vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));
return decode8(texel, index);
}
float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
ivec3 xyz = ivec3(x, y, z);
int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);
int channel = integerMod(index, 4);
index = index / 4;
int w = texSize.x;
vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
vec4 texel = texture2D(tex, st / vec2(texSize));
if (channel == 0) return texel.r;
if (channel == 1) return texel.g;
if (channel == 2) return texel.b;
if (channel == 3) return texel.a;
return 0.0;
}
vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
ivec3 xyz = ivec3(x, y, z);
int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);
int w = texSize.x;
vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
return texture2D(tex, st / vec2(texSize));
}
float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
return result[0];
}
vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
return vec2(result[0], result[1]);
}
vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
return vec3(result[0], result[1], result[2]);
}
vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
return getImage2D(tex, texSize, texDim, z, y, x);
}
vec4 actualColor;
void color(float r, float g, float b, float a) {
actualColor = vec4(r,g,b,a);
}
void color(float r, float g, float b) {
color(r,g,b,1.0);
}
void color(sampler2D image) {
actualColor = texture2D(image, vTexCoord);
}
uniform sampler2D user_a;
ivec2 user_aSize = ivec2(1, 1);
ivec3 user_aDim = ivec3(1, 1, 1);
uniform sampler2D user_b;
ivec2 user_bSize = ivec2(1, 1);
ivec3 user_bDim = ivec3(1, 1, 1);
float kernelResult;
float subKernelResult_value1 = 0.0;
float subKernelResult_value2 = 0.0;
float value2(float user_value) {
subKernelResult_value2 = (user_value+50.0);return subKernelResult_value2;
}
float value1(float user_value) {
subKernelResult_value1 = (user_value+10.0);return subKernelResult_value1;
}
void kernel() {
value1(get32(user_a, user_aSize, user_aDim, 0, 0, threadId.x));
kernelResult = (value2(get32(user_b, user_bSize, user_bDim, 0, 0, threadId.x))+100.0);return;
}
void main(void) {
index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;
threadId = indexTo3D(index, uOutputDim);
kernel();
gl_FragData[0] = encode32(kernelResult);
gl_FragData[1] = encode32(subKernelResult_value1);
gl_FragData[2] = encode32(subKernelResult_value2);
}`);
gl.compileShader(glVariable8);
const glVariable9 = gl.getShaderParameter(glVariable7, gl.COMPILE_STATUS);
const glVariable10 = gl.getShaderParameter(glVariable8, gl.COMPILE_STATUS);
const glVariable11 = gl.createProgram();
gl.attachShader(glVariable11, glVariable7);
gl.attachShader(glVariable11, glVariable8);
gl.linkProgram(glVariable11);
const glVariable12 = gl.createFramebuffer();
const glVariable13 = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, glVariable13);
gl.bufferData(gl.ARRAY_BUFFER, 64, gl.STATIC_DRAW);
const glVariable14 = new Float32Array([-1,-1,1,-1,-1,1,1,1]);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, glVariable14);
const glVariable15 = new Float32Array([0,0,1,0,0,1,1,1]);
gl.bufferSubData(gl.ARRAY_BUFFER, 32, glVariable15);
const glVariable16 = gl.getAttribLocation(glVariable11, 'aPos');
gl.enableVertexAttribArray(glVariable16);
gl.vertexAttribPointer(glVariable16, 2, gl.FLOAT, false, 0, 0);
const glVariable17 = gl.getAttribLocation(glVariable11, 'aTexCoord');
gl.enableVertexAttribArray(glVariable17);
gl.vertexAttribPointer(glVariable17, 2, gl.FLOAT, false, 0, 32);
gl.bindFramebuffer(gl.FRAMEBUFFER, glVariable12);
gl.useProgram(glVariable11);
/** start of injected functions **/
function flattenTo(array, target) {
if (/*utils.*/isArray(array[0])) {
if (/*utils.*/isArray(array[0][0])) {
/*utils.*/flatten3dArrayTo(array, target);
} else {
/*utils.*/flatten2dArrayTo(array, target);
}
} else {
target.set(array);
}
}
function flatten2dArrayTo(array, target) {
let offset = 0;
for (let y = 0; y < array.length; y++) {
target.set(array[y], offset);
offset += array[y].length;
}
}
function flatten3dArrayTo(array, target) {
let offset = 0;
for (let z = 0; z < array.length; z++) {
for (let y = 0; y < array[z].length; y++) {
target.set(array[z][y], offset);
offset += array[z][y].length;
}
}
}
function isArray(array) {
return !isNaN(array.length);
}
class Texture {
constructor(settings) {
const {
texture,
size,
dimensions,
output,
context,
gpu,
type = 'NumberTexture',
} = settings;
if (!output) throw new Error('settings property "output" required.');
if (!context) throw new Error('settings property "context" required.');
this.texture = texture;
this.size = size;
this.dimensions = dimensions;
this.output = output;
this.context = context;
this.gpu = gpu;
this.kernel = null;
this.type = type;
}
toArray(gpu) {
let {
kernel
} = this;
if (kernel) return kernel(this);
gpu = gpu || this.gpu;
if (!gpu) throw new Error('settings property "gpu" or argument required.');
kernel = gpu.createKernel(function(x) {
return x[this.thread.z][this.thread.y][this.thread.x];
}, {
output: this.output,
precision: this.getPrecision(),
optimizeFloatMemory: this.type === 'MemoryOptimizedNumberTexture',
});
this.kernel = kernel;
return kernel(this);
}
getPrecision() {
switch (this.type) {
case 'NumberTexture':
return 'unsigned';
case 'MemoryOptimizedNumberTexture':
case 'ArrayTexture(1)':
case 'ArrayTexture(2)':
case 'ArrayTexture(3)':
case 'ArrayTexture(4)':
return 'single';
default:
throw new Error('Unknown texture type');
}
}
delete() {
return this.context.deleteTexture(this.texture);
}
}
const renderOutput = function renderTexture() {
return new Texture({
texture: null,
size: new Int32Array([1,1]),
dimensions: new Int32Array([1,1,1]),
output: new Int32Array(undefined),
context: gl,
gpu: null,
type: 'NumberTexture',
});
};
/** end of injected functions **/
return function (a, b) {
/** start setup uploads for kernel values **/
const uploadValue_a = a;
const uploadValue_b = b;
/** end setup uploads for kernel values **/
gl.useProgram(glVariable11);
gl.scissor(0, 0, 1, 1);
const glVariable18 = gl.getUniformLocation(glVariable11, 'uOutputDim');
const glVariable19 = new Array(1,1,1);
gl.uniform3iv(glVariable18, glVariable19);
const glVariable20 = gl.getUniformLocation(glVariable11, 'uTexSize');
const glVariable21 = new Int32Array([1,1]);
gl.uniform2iv(glVariable20, glVariable21);
const glVariable22 = gl.getUniformLocation(glVariable11, 'ratio');
gl.uniform2f(glVariable22, 1, 1);
gl.bindFramebuffer(gl.FRAMEBUFFER, glVariable12);
const glVariable23 = gl.createTexture();
gl.activeTexture(33986);
gl.bindTexture(gl.TEXTURE_2D, glVariable23);
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, glVariable23, 0);
const glVariable24 = gl.createTexture();
gl.activeTexture(33986);
gl.bindTexture(gl.TEXTURE_2D, glVariable24);
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, 36065, gl.TEXTURE_2D, glVariable24, 0);
const glVariable25 = gl.createTexture();
gl.activeTexture(33987);
gl.bindTexture(gl.TEXTURE_2D, glVariable25);
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, 36066, gl.TEXTURE_2D, glVariable25, 0);
glVariables3.drawBuffersWEBGL([gl.COLOR_ATTACHMENT0, 36065, 36066]);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
return renderOutput(undefined);
}; }
function kernel(context = null) {
const gl = context;
const glVariables0 = gl.getExtension('OES_texture_float');
const glVariables1 = gl.getExtension('OES_texture_float_linear');
const glVariables2 = gl.getExtension('OES_element_index_uint');
const glVariables3 = gl.getExtension('WEBGL_draw_buffers');
const glVariables4 = gl.getExtension('WEBGL_color_buffer_float');
const glVariable5 = gl.createTexture();
const glVariable6 = gl.createTexture();
gl.enable(gl.SCISSOR_TEST);
gl.viewport(0, 0, 1, 1);
const glVariable7 = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(glVariable7, `precision highp float;
precision highp int;
precision highp sampler2D;
attribute vec2 aPos;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
uniform vec2 ratio;
void main(void) {
gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);
vTexCoord = aTexCoord;
}`);
gl.compileShader(glVariable7);
const glVariable8 = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(glVariable8, `#extension GL_EXT_draw_buffers : require
precision highp float;
precision highp int;
precision highp sampler2D;
const int LOOP_MAX = 1000;
uniform ivec3 uOutputDim;
uniform ivec2 uTexSize;
varying vec2 vTexCoord;
vec4 round(vec4 x) {
return floor(x + 0.5);
}
float round(float x) {
return floor(x + 0.5);
}
vec2 integerMod(vec2 x, float y) {
vec2 res = floor(mod(x, y));
return res * step(1.0 - floor(y), -res);
}
vec3 integerMod(vec3 x, float y) {
vec3 res = floor(mod(x, y));
return res * step(1.0 - floor(y), -res);
}
vec4 integerMod(vec4 x, vec4 y) {
vec4 res = floor(mod(x, y));
return res * step(1.0 - floor(y), -res);
}
float integerMod(float x, float y) {
float res = floor(mod(x, y));
return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);
}
int integerMod(int x, int y) {
return x - (y * int(x / y));
}
float div_with_int_check(float x, float y) {
if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {
return float(int(x)/int(y));
}
return x / y;
}
// Here be dragons!
// DO NOT OPTIMIZE THIS CODE
// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE
// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME
const vec2 MAGIC_VEC = vec2(1.0, -256.0);
const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);
const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536
float decode32(vec4 texel) {
texel *= 255.0;
vec2 gte128;
gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;
gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;
float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);
float res = exp2(round(exponent));
texel.b = texel.b - 128.0 * gte128.x;
res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;
res *= gte128.y * -2.0 + 1.0;
return res;
}
float decode16(vec4 texel, int index) {
int channel = integerMod(index, 2);
if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;
if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;
return 0.0;
}
float decode8(vec4 texel, int index) {
int channel = integerMod(index, 4);
if (channel == 0) return texel.r * 255.0;
if (channel == 1) return texel.g * 255.0;
if (channel == 2) return texel.b * 255.0;
if (channel == 3) return texel.a * 255.0;
return 0.0;
}
vec4 encode32(float f) {
float F = abs(f);
float sign = f < 0.0 ? 1.0 : 0.0;
float exponent = floor(log2(F));
float mantissa = (exp2(-exponent) * F);
// exponent += floor(log2(mantissa));
vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;
texel.rg = integerMod(texel.rg, 256.0);
texel.b = integerMod(texel.b, 128.0);
texel.a = exponent*0.5 + 63.5;
texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;
texel = floor(texel);
texel *= 0.003921569; // 1/255
return texel;
}
// Dragons end here
int index;
ivec3 threadId;
ivec3 indexTo3D(int idx, ivec3 texDim) {
int z = int(idx / (texDim.x * texDim.y));
idx -= z * int(texDim.x * texDim.y);
int y = int(idx / texDim.x);
int x = int(integerMod(idx, texDim.x));
return ivec3(x, y, z);
}
float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
ivec3 xyz = ivec3(x, y, z);
int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);
int w = texSize.x;
vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
vec4 texel = texture2D(tex, st / vec2(texSize));
return decode32(texel);
}
float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
ivec3 xyz = ivec3(x, y, z);
int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);
int w = texSize.x * 2;
vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));
return decode16(texel, index);
}
float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
ivec3 xyz = ivec3(x, y, z);
int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);
int w = texSize.x * 4;
vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));
return decode8(texel, index);
}
float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
ivec3 xyz = ivec3(x, y, z);
int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);
int channel = integerMod(index, 4);
index = index / 4;
int w = texSize.x;
vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
vec4 texel = texture2D(tex, st / vec2(texSize));
if (channel == 0) return texel.r;
if (channel == 1) return texel.g;
if (channel == 2) return texel.b;
if (channel == 3) return texel.a;
return 0.0;
}
vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
ivec3 xyz = ivec3(x, y, z);
int index = xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z);
int w = texSize.x;
vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;
return texture2D(tex, st / vec2(texSize));
}
float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
return result[0];
}
vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
return vec2(result[0], result[1]);
}
vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
vec4 result = getImage2D(tex, texSize, texDim, z, y, x);
return vec3(result[0], result[1], result[2]);
}
vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
return getImage2D(tex, texSize, texDim, z, y, x);
}
vec4 actualColor;
void color(float r, float g, float b, float a) {
actualColor = vec4(r,g,b,a);
}
void color(float r, float g, float b) {
color(r,g,b,1.0);
}
void color(sampler2D image) {
actualColor = texture2D(image, vTexCoord);
}
uniform sampler2D user_a;
ivec2 user_aSize = ivec2(2, 2);
ivec3 user_aDim = ivec3(1, 1, 1);
uniform sampler2D user_b;
ivec2 user_bSize = ivec2(2, 2);
ivec3 user_bDim = ivec3(1, 1, 1);
float kernelResult;
float subKernelResult_value1 = 0.0;
float subKernelResult_value2 = 0.0;
float value2(float user_value) {
subKernelResult_value2 = (user_value+50.0);return subKernelResult_value2;
}
float value1(float user_value) {
subKernelResult_value1 = (user_value+10.0);return subKernelResult_value1;
}
void kernel() {
value1(get32(user_a, user_aSize, user_aDim, 0, 0, threadId.x));
kernelResult = (value2(get32(user_b, user_bSize, user_bDim, 0, 0, threadId.x))+100.0);return;
}
void main(void) {
index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;
threadId = indexTo3D(index, uOutputDim);
kernel();
gl_FragData[0] = encode32(kernelResult);
gl_FragData[1] = encode32(subKernelResult_value1);
gl_FragData[2] = encode32(subKernelResult_value2);
}`);
gl.compileShader(glVariable8);
const glVariable9 = gl.getShaderParameter(glVariable7, gl.COMPILE_STATUS);
const glVariable10 = gl.getShaderParameter(glVariable8, gl.COMPILE_STATUS);
const glVariable11 = gl.createProgram();
gl.attachShader(glVariable11, glVariable7);
gl.attachShader(glVariable11, glVariable8);
gl.linkProgram(glVariable11);
const glVariable12 = gl.createFramebuffer();
const glVariable13 = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, glVariable13);
gl.bufferData(gl.ARRAY_BUFFER, 64, gl.STATIC_DRAW);
const glVariable14 = new Float32Array([-1,-1,1,-1,-1,1,1,1]);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, glVariable14);
const glVariable15 = new Float32Array([0,0,1,0,0,1,1,1]);
gl.bufferSubData(gl.ARRAY_BUFFER, 32, glVariable15);
const glVariable16 = gl.getAttribLocation(glVariable11, 'aPos');
gl.enableVertexAttribArray(glVariable16);
gl.vertexAttribPointer(glVariable16, 2, gl.FLOAT, false, 0, 0);
const glVariable17 = gl.getAttribLocation(glVariable11, 'aTexCoord');
gl.enableVertexAttribArray(glVariable17);
gl.vertexAttribPointer(glVariable17, 2, gl.FLOAT, false, 0, 32);
gl.bindFramebuffer(gl.FRAMEBUFFER, glVariable12);
gl.useProgram(glVariable11);
/** start of injected functions **/
function flattenTo(array, target) {
if (/*utils.*/isArray(array[0])) {
if (/*utils.*/isArray(array[0][0])) {
/*utils.*/flatten3dArrayTo(array, target);
} else {
/*utils.*/flatten2dArrayTo(array, target);
}
} else {
target.set(array);
}
}
function flatten2dArrayTo(array, target) {
let offset = 0;
for (let y = 0; y < array.length; y++) {
target.set(array[y], offset);
offset += array[y].length;
}
}
function flatten3dArrayTo(array, target) {
let offset = 0;
for (let z = 0; z < array.length; z++) {
for (let y = 0; y < array[z].length; y++) {
target.set(array[z][y], offset);
offset += array[z][y].length;
}
}
}
function isArray(array) {
return !isNaN(array.length);
}
class Texture {
constructor(settings) {
const {
texture,
size,
dimensions,
output,
context,
gpu,
type = 'NumberTexture',
} = settings;
if (!output) throw new Error('settings property "output" required.');
if (!context) throw new Error('settings property "context" required.');
this.texture = texture;
this.size = size;
this.dimensions = dimensions;
this.output = output;
this.context = context;
this.gpu = gpu;
this.kernel = null;
this.type = type;
}
toArray(gpu) {
let {
kernel
} = this;
if (kernel) return kernel(this);
gpu = gpu || this.gpu;
if (!gpu) throw new Error('settings property "gpu" or argument required.');
kernel = gpu.createKernel(function(x) {
return x[this.thread.z][this.thread.y][this.thread.x];
}, {
output: this.output,
precision: this.getPrecision(),
optimizeFloatMemory: this.type === 'MemoryOptimizedNumberTexture',
});
this.kernel = kernel;
return kernel(this);
}
getPrecision() {
switch (this.type) {
case 'NumberTexture':
return 'unsigned';
case 'MemoryOptimizedNumberTexture':
case 'ArrayTexture(1)':
case 'ArrayTexture(2)':
case 'ArrayTexture(3)':
case 'ArrayTexture(4)':
return 'single';
default:
throw new Error('Unknown texture type');
}
}
delete() {
return this.context.deleteTexture(this.texture);
}
}
const renderOutput = function renderTexture() {
return new Texture({
texture: null,
size: new Int32Array([1,1]),
dimensions: new Int32Array([1,1,1]),
output: new Int32Array(undefined),
context: gl,
gpu: null,
type: 'NumberTexture',
});
};
/** end of injected functions **/
return function (a, b) {
/** start setup uploads for kernel values **/
const preUploadValue_a = new Float32Array(4);
const uploadValue_a = new Uint8Array(preUploadValue_a.buffer);
flattenTo(a, preUploadValue_a);
const preUploadValue_b = new Float32Array(4);
const uploadValue_b = new Uint8Array(preUploadValue_b.buffer);
flattenTo(b, preUploadValue_b);
/** end setup uploads for kernel values **/
gl.useProgram(glVariable11);
gl.scissor(0, 0, 1, 1);
const glVariable18 = gl.getUniformLocation(glVariable11, 'uOutputDim');
const glVariable19 = new Array(1,1,1);
gl.uniform3iv(glVariable18, glVariable19);
const glVariable20 = gl.getUniformLocation(glVariable11, 'uTexSize');
const glVariable21 = new Int32Array([1,1]);
gl.uniform2iv(glVariable20, glVariable21);
const glVariable22 = gl.getUniformLocation(glVariable11, 'ratio');
gl.uniform2f(glVariable22, 1, 1);
const glVariable23 = gl.getUniformLocation(glVariable11, 'user_a');
gl.uniform1i(glVariable23, 0);
const glVariable24 = gl.getUniformLocation(glVariable11, 'user_b');
gl.uniform1i(glVariable24, 1);
gl.bindFramebuffer(gl.FRAMEBUFFER, glVariable12);
const glVariable25 = gl.createTexture();
gl.activeTexture(33986);
gl.bindTexture(gl.TEXTURE_2D, glVariable25);
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, glVariable25, 0);
const glVariable26 = gl.createTexture();
gl.activeTexture(33986);
gl.bindTexture(gl.TEXTURE_2D, glVariable26);
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, 36065, gl.TEXTURE_2D, glVariable26, 0);
const glVariable27 = gl.createTexture();
gl.activeTexture(33987);
gl.bindTexture(gl.TEXTURE_2D, glVariable27);
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, 36066, gl.TEXTURE_2D, glVariable27, 0);
glVariables3.drawBuffersWEBGL([gl.COLOR_ATTACHMENT0, 36065, 36066]);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
return renderOutput(undefined);
}; }
function value1(value) {
return value + 10;
}
function value2(value) {
return value + 50;
}
const gpu = new GPU({ mode });
const kernel = gpu.createKernelMap(
{
valueOutput1: value1,
valueOutput2: value2
},
function (a, b) {
value1(a[this.thread.x]);
return value2(b[this.thread.x]) + 100;
},
{
output: [1],
immutable: true,
pipeline: true,
precision: 'unsigned',
}
);
// start with a value on CPU
const output1 = kernel([10], [20]);
// reuse that output, simulating that this value will be monitored, and updated via the same kernel
// this is often used in neural networks
const output2 = kernel(output1.result, output1.valueOutput2);
const output3 = kernel(output2.result, output2.valueOutput2);
function toArray(value) {
return value.toArray ? value.toArray() : value;
}
assert.equal(toArray(output1.valueOutput1)[0], 20); // 10 + 10
assert.equal(toArray(output1.valueOutput2)[0], 70); // 20 + 50
assert.equal(toArray(output1.result)[0], 170); // (20 + 50) + 100
assert.equal(toArray(output2.valueOutput1)[0], 180); // 170 + 10
assert.equal(toArray(output2.valueOutput2)[0], 120); // 70 + 50
assert.equal(toArray(output2.result)[0], 220); // (70 + 50) + 100
assert.equal(toArray(output3.valueOutput1)[0], 230); // 220 + 10
assert.equal(toArray(output3.valueOutput2)[0], 170); // 120 + 50
assert.equal(toArray(output3.result)[0], 270); // (120 + 50) + 100
gpu.destroy();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment