Skip to content

Commit 3b3992c

Browse files
committed
Use float textures by default when available
1 parent ff213f1 commit 3b3992c

3 files changed

Lines changed: 74 additions & 41 deletions

File tree

src/backend/GPUCore.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ var GPUCore = (function() {
1414

1515
function GPUCore() {
1616
// var gl, canvas;
17-
//
17+
//
1818
// canvas = undefined;
1919
// if (gl === undefined) {
2020
// canvas = GPUUtils.init_canvas();
2121
// gl = GPUUtils.init_webgl(canvas);
2222
// }
23-
//
23+
//
2424
// this.webgl = gl;
2525
// this.canvas = canvas;
2626
this.programCache = {};
@@ -152,11 +152,16 @@ var GPUCore = (function() {
152152
opt.floatTextures = flag;
153153
return ret;
154154
};
155+
156+
ret.floatOutput = function(flag) {
157+
opt.floatOutput = flag;
158+
return ret;
159+
};
155160

156161
ret.mode = function(mode) {
157162
opt.mode = mode;
158163
return gpu.createKernel(
159-
gpu._kernelFunction,
164+
gpu._kernelFunction,
160165
gpu._kernelParamObj
161166
);
162167
};

src/backend/mode_gpu.js

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
numTexels *= dimensions[i];
66
}
77

8-
if (opt.floatTextures && !output) {
8+
if (opt.floatTextures && (!output || opt.floatOutput)) {
99
numTexels = Math.ceil(numTexels / 4);
1010
}
1111

@@ -133,8 +133,10 @@
133133
var programUniformLocationCache = [];
134134

135135
function ret() {
136-
if (opt.floatTextures && !gpu.OES_texture_float) {
136+
if (opt.floatTextures === true && !GPUUtils.OES_texture_float) {
137137
throw "Float textures are not supported on this browser";
138+
} else if (opt.floatTextures === undefined && GPUUtils.OES_texture_float) {
139+
opt.floatTextures = true;
138140
}
139141

140142
if (!opt.dimensions || opt.dimensions.length === 0) {
@@ -152,14 +154,20 @@
152154
}
153155
}
154156

155-
var texSize = dimToTexSize(gpu, opt.dimensions, true);
156-
157+
var texSize = dimToTexSize(opt, opt.dimensions, true);
158+
157159
if (opt.graphical) {
158160
if (opt.dimensions.length != 2) {
159161
throw "Output must have 2 dimensions on graphical mode";
160162
}
161163

164+
if (opt.floatOutput) {
165+
throw "Cannot use graphical mode and float output at the same time";
166+
}
167+
162168
texSize = GPUUtils.clone(opt.dimensions);
169+
} else if (opt.floatOutput === undefined && GPUUtils.OES_texture_float) {
170+
opt.floatOutput = true;
163171
}
164172

165173
canvas.width = texSize[0];
@@ -387,12 +395,20 @@
387395
'',
388396
'void main(void) {',
389397
' index = floor(vTexCoord.s * float(uTexSize.x)) + floor(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;',
398+
(opt.floatOutput ? 'index *= 4.0;' : ''),
390399
' threadId = indexTo3D(index, uOutputDim);',
391400
' kernel();',
392401
' if (outputToColor == true) {',
393402
' gl_FragColor = actualColor;',
394403
' } else {',
395-
' gl_FragColor = encode32(kernelResult);',
404+
(opt.floatOutput ? '' : 'gl_FragColor = encode32(kernelResult);'),
405+
(opt.floatOutput ? 'gl_FragColor.r = kernelResult;' : ''),
406+
(opt.floatOutput ? 'index += 1.0; threadId = indexTo3D(index, uOutputDim); kernel();' : ''),
407+
(opt.floatOutput ? 'gl_FragColor.g = kernelResult;' : ''),
408+
(opt.floatOutput ? 'index += 1.0; threadId = indexTo3D(index, uOutputDim); kernel();' : ''),
409+
(opt.floatOutput ? 'gl_FragColor.b = kernelResult;' : ''),
410+
(opt.floatOutput ? 'index += 1.0; threadId = indexTo3D(index, uOutputDim); kernel();' : ''),
411+
(opt.floatOutput ? 'gl_FragColor.a = kernelResult;' : ''),
396412
' }',
397413
'}'
398414
].join('\n');
@@ -407,17 +423,20 @@
407423
gl.compileShader(fragShader);
408424

409425
if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {
410-
console.error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(vertShader));
411426
console.log(vertShaderSrc);
427+
console.error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(vertShader));
412428
throw "Error compiling vertex shader";
413429
}
414430
if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {
415-
console.error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(fragShader));
416431
console.log(fragShaderSrc);
432+
console.error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(fragShader));
417433
throw "Error compiling fragment shader";
418434
}
419435

420436
if (opt.debug) {
437+
console.log('Options:');
438+
console.dir(opt);
439+
console.log('GLSL Shader Output:');
421440
console.log(fragShaderSrc);
422441
}
423442

@@ -470,7 +489,7 @@
470489
var argType = GPUUtils.getArgumentType(arguments[textureCount]);
471490
if (argType == "Array") {
472491
paramDim = getDimensions(arguments[textureCount], true);
473-
paramSize = dimToTexSize(gpu, paramDim);
492+
paramSize = dimToTexSize(opt, paramDim);
474493

475494
texture = gl.createTexture();
476495
gl.activeTexture(gl["TEXTURE"+textureCount]);
@@ -531,38 +550,46 @@
531550
throw "Input type not supported (GPU): " + arguments[textureCount];
532551
}
533552
}
534-
535-
if (opt.outputToTexture) {
536-
var outputTexture = gl.createTexture();
537-
gl.activeTexture(gl["TEXTURE"+textureCount]);
538-
gl.bindTexture(gl.TEXTURE_2D, outputTexture);
539-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
540-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
541-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
542-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
553+
554+
var outputTexture = gl.createTexture();
555+
gl.activeTexture(gl["TEXTURE"+textureCount]);
556+
gl.bindTexture(gl.TEXTURE_2D, outputTexture);
557+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
558+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
559+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
560+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
561+
if (opt.floatOutput) {
562+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
563+
} else {
543564
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
565+
}
544566

545-
var framebuffer = gl.createFramebuffer();
546-
framebuffer.width = texSize[0];
547-
framebuffer.height = texSize[1];
548-
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
549-
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outputTexture, 0);
550-
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
567+
var framebuffer = gl.createFramebuffer();
568+
framebuffer.width = texSize[0];
569+
framebuffer.height = texSize[1];
570+
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
571+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, outputTexture, 0);
572+
573+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
574+
575+
if (opt.outputToTexture) {
551576
return new GPUTexture(gpu, outputTexture, texSize, opt.dimensions);
552577
} else {
553-
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
554-
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
555-
556-
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
557-
558578
if (opt.graphical) {
559579
return;
560580
}
561581

562-
var bytes = new Uint8Array(texSize[0]*texSize[1]*4);
563-
gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes);
564-
var result = Array.prototype.slice.call(new Float32Array(bytes.buffer));
565-
result.length = threadDim[0] * threadDim[1] * threadDim[2];
582+
var result;
583+
if (opt.floatOutput) {
584+
result = new Float32Array(texSize[0]*texSize[1]*4);
585+
gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.FLOAT, result);
586+
} else {
587+
var bytes = new Uint8Array(texSize[0]*texSize[1]*4);
588+
gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, bytes);
589+
result = Float32Array.prototype.slice.call(new Float32Array(bytes.buffer));
590+
}
591+
592+
result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);
566593

567594
if (opt.dimensions.length == 1) {
568595
return result;

src/utils.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ var GPUUtils = (function() {
254254
/// {Boolean} TRUE if the object is a DOM canvas
255255
///
256256
function isCanvas( canvasObj ) {
257-
return (
257+
return (
258258
canvasObj != null &&
259259
canvasObj.nodeName &&
260260
canvasObj.getContext &&
@@ -336,7 +336,7 @@ var GPUUtils = (function() {
336336
/// {Boolean} TRUE if the object is a webgl context object
337337
///
338338
function isWebgl( webglObj ) {
339-
return (
339+
return (
340340
webglObj != null &&
341341
webglObj.getExtension
342342
);
@@ -363,6 +363,7 @@ var GPUUtils = (function() {
363363

364364
// Default webgl options to use
365365
var init_webgl_defaultOptions = {
366+
alpha: false,
366367
depth: false,
367368
antialias: false
368369
}
@@ -393,7 +394,7 @@ var GPUUtils = (function() {
393394

394395
// Create a new canvas DOM
395396
var webgl = (
396-
canvasObj.getContext("experimental-webgl", init_webgl_defaultOptions) ||
397+
canvasObj.getContext("experimental-webgl", init_webgl_defaultOptions) ||
397398
canvasObj.getContext("webgl", init_webgl_defaultOptions)
398399
);
399400

@@ -406,9 +407,9 @@ var GPUUtils = (function() {
406407
}
407408

408409
// Get the extension that is needed
409-
webgl.getExtension('OES_texture_float');
410-
webgl.getExtension('OES_texture_float_linear');
411-
webgl.getExtension('OES_element_index_uint');
410+
GPUUtils.OES_texture_float = webgl.getExtension('OES_texture_float');
411+
GPUUtils.OES_texture_float_linear = webgl.getExtension('OES_texture_float_linear');
412+
GPUUtils.OES_element_index_uint = webgl.getExtension('OES_element_index_uint');
412413

413414
// Returns the canvas
414415
return webgl;

0 commit comments

Comments
 (0)