Skip to content

Commit

Permalink
Merge pull request #305 from gpujs/297-array-images
Browse files Browse the repository at this point in the history
Closes #297 array of images
  • Loading branch information
robertleeplummerjr authored Jun 6, 2018
2 parents 419be53 + b0ccde2 commit 26e14d9
Show file tree
Hide file tree
Showing 27 changed files with 630 additions and 149 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ myFunc();
* 2d Array
* 3d Array
* HTML Image
* Array of HTML Images
To define an argument, simply add it to the kernel function like regular JavaScript.

### Input Examples
Expand All @@ -193,6 +194,34 @@ myFunc([1, 2, 3]);
// Result: [1, 2, 3, 1, ... 1 ]
```

An HTML Image:

```js
const myFunc = gpu.createKernel(function(image) {
const pixel = image[this.thread.y][this.thread.x];
this.color(pixel[0], pixel[1], pixel[2], pixel[3]);
})
.setGraphical(true)
.setOutput([100]);

myFunc([1, 2, 3]);
// Result: colorful image
```

An Array of HTML Images:

```js
const myFunc = gpu.createKernel(function(image) {
const pixel = image[this.thread.z][this.thread.y][this.thread.x];
this.color(pixel[0], pixel[1], pixel[2], pixel[3]);
})
.setGraphical(true)
.setOutput([100]);

myFunc([1, 2, 3]);
// Result: colorful image
```

## Graphical Output

Sometimes, you want to produce a `canvas` image instead of doing numeric computations. To achieve this, set the `graphical` flag to `true` and the output dimensions to `[width, height]`. The thread identifiers will now refer to the `x` and `y` coordinate of the pixel you are producing. Inside your kernel function, use `this.color(r,g,b)` or `this.color(r,g,b,a)` to specify the color of the pixel.
Expand Down
4 changes: 2 additions & 2 deletions bin/gpu-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
*
* GPU Accelerated JavaScript
*
* @version 1.3.0
* @date Mon Jun 04 2018 20:06:27 GMT-0400 (EDT)
* @version 1.4.0
* @date Tue Jun 05 2018 20:28:34 GMT-0400 (EDT)
*
* @license MIT
* The MIT License
Expand Down
4 changes: 2 additions & 2 deletions bin/gpu-core.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

156 changes: 131 additions & 25 deletions bin/gpu.js

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions bin/gpu.min.js

Large diffs are not rendered by default.

26 changes: 20 additions & 6 deletions dist/backend/cpu/kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,13 @@ module.exports = function (_KernelBase) {
value: function _processInputs() {
var result = [];
for (var i = 0; i < this.paramTypes.length; i++) {
if (this.paramTypes[i] === 'HTMLImage') {
result.push(' user_' + this.paramNames[i] + ' = this._imageTo2DArray(user_' + this.paramNames[i] + ')');
switch (this.paramTypes[i]) {
case 'HTMLImage':
result.push(' user_' + this.paramNames[i] + ' = this._imageTo2DArray(user_' + this.paramNames[i] + ')');
break;
case 'HTMLImageArray':
result.push(' user_' + this.paramNames[i] + ' = this._imageTo3DArray(user_' + this.paramNames[i] + ')');
break;
}
}
return result.join(';\n');
Expand All @@ -347,15 +352,24 @@ module.exports = function (_KernelBase) {
value: function _imageTo2DArray(image) {
this._canvasCtx.drawImage(image, 0, 0, image.width, image.height);
var pixelsData = this._canvasCtx.getImageData(0, 0, image.width, image.height).data;
var result = new Array(image.height);
var imageArray = new Array(image.height);
var index = 0;
for (var y = 0; y < image.height; y++) {
result[y] = new Array(image.width);
imageArray[y] = new Array(image.width);
for (var x = 0; x < image.width; x++) {
result[y][x] = [pixelsData[index++] / 255, pixelsData[index++] / 255, pixelsData[index++] / 255, pixelsData[index++] / 255];
imageArray[y][x] = [pixelsData[index++] / 255, pixelsData[index++] / 255, pixelsData[index++] / 255, pixelsData[index++] / 255];
}
}
return result;
return imageArray;
}
}, {
key: '_imageTo3DArray',
value: function _imageTo3DArray(images) {
var imagesArray = new Array(images.length);
for (var i = 0; i < images.length; i++) {
imagesArray[i] = this._imageTo2DArray(images[i]);
}
return imagesArray;
}
}], [{
key: 'compileKernel',
Expand Down
23 changes: 21 additions & 2 deletions dist/backend/web-gl/function-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ module.exports = function (_FunctionNodeBase) {
}
var retDeclaration = [];
this.astGeneric(declaration, retDeclaration, funcParam);
if (retDeclaration[2] === 'getImage(') {
if (retDeclaration[2] === 'getImage2D(' || retDeclaration[2] === 'getImage3D(') {
if (i === 0) {
retArr.push('vec4 ');
}
Expand Down Expand Up @@ -993,9 +993,28 @@ module.exports = function (_FunctionNodeBase) {
retArr.push(mNode.property.raw);
retArr.push(']');
break;
case 'HTMLImageArray':
// Get from image
retArr.push('getImage3D(');
this.astGeneric(mNode.object, retArr, funcParam);
retArr.push(', vec2(');
this.astGeneric(mNode.object, retArr, funcParam);
retArr.push('Size[0],');
this.astGeneric(mNode.object, retArr, funcParam);
retArr.push('Size[1]), vec3(');
this.astGeneric(mNode.object, retArr, funcParam);
retArr.push('Dim[0],');
this.astGeneric(mNode.object, retArr, funcParam);
retArr.push('Dim[1],');
this.astGeneric(mNode.object, retArr, funcParam);
retArr.push('Dim[2]');
retArr.push('), ');
this.astGeneric(mNode.property, retArr, funcParam);
retArr.push(')');
break;
case 'HTMLImage':
// Get from image
retArr.push('getImage(');
retArr.push('getImage2D(');
this.astGeneric(mNode.object, retArr, funcParam);
retArr.push(', vec2(');
this.astGeneric(mNode.object, retArr, funcParam);
Expand Down
2 changes: 2 additions & 0 deletions dist/backend/web-gl/kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,8 @@ module.exports = function (_KernelBase) {
result.push('uniform highp sampler2D user_' + paramName, 'uniform highp vec2 user_' + paramName + 'Size', 'uniform highp vec3 user_' + paramName + 'Dim');
} else if (paramType === 'Number') {
result.push('uniform highp float user_' + paramName);
} else {
throw new Error('Param type ' + paramType + ' not supported in WebGL, only WebGL2');
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion dist/backend/web-gl/shader-frag.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dist/backend/web-gl2/function-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var FunctionBuilderBase = require('../function-builder-base');
var WebGLFunctionNode = require('./function-node');
var WebGL2FunctionNode = require('./function-node');

/**
* @class WebGLFunctionBuilder
Expand All @@ -25,7 +25,7 @@ module.exports = function (_FunctionBuilderBase) {

var _this = _possibleConstructorReturn(this, (WebGL2FunctionBuilder.__proto__ || Object.getPrototypeOf(WebGL2FunctionBuilder)).call(this));

_this.Node = WebGLFunctionNode;
_this.Node = WebGL2FunctionNode;
return _this;
}

Expand Down
Loading

0 comments on commit 26e14d9

Please sign in to comment.