Felt obliged to share the corrected version per @max 's comments code for anyone interested.
There is method Save on the following script that takes a boolean true/false if you would like to download the screen grab and a callback that returns a base64 represntation of the image. Before taking the image, all entities without the tag shareable are hidden.
This method doesn’t need the Preserve Drawing Buffer property to be enabled.
var Share = pc.createScript('Share');
// initialize code called once per entity
Share.prototype.initialize = function() {
// prepare allocations for screen grab
//
// Create a render target with a depth buffer
this.colorBuffer = new pc.Texture(this.app.graphicsDevice, {
width: this.app.graphicsDevice.canvas.width,
height: this.app.graphicsDevice.canvas.height,
format: pc.PIXELFORMAT_R8_G8_B8
});
this.renderTarget = new pc.RenderTarget(this.app.graphicsDevice, this.colorBuffer, {
depth: true
});
this.gl = this.app.graphicsDevice.gl;
this.fb = this.gl.createFramebuffer();
this.pixels = new Uint8Array(this.colorBuffer.width * this.colorBuffer.height * 4);
this.canvas = document.createElement("canvas");
this.canvasFinal = document.createElement("canvas");
//////////
this.entityCamera = this.app.root.findByName('Camera');
};
Share.prototype.save = function(downloadImage, callback){
this.nonSharableEntities = this.app.root.find(function(node) {
return node.tags.has('shareable') === false;
});
this.enableEntities(false);
this.renderToTexture(downloadImage, function(base64){
this.enableEntities(true);
if (typeof callback === "function") {
callback(base64);
}
}.bind(this) );
};
Share.prototype.enableEntities = function(state){
if( this.nonSharableEntities.length !== undefined){
this.nonSharableEntities.forEach(function(entity, index){
if( entity.model !== undefined ){
if( state === false ){
entity.oldModelState = entity.model.enabled;
entity.model.enabled = state;
}else{
entity.model.enabled = entity.oldModelState;
}
}
}, this);
}
};
Share.prototype.renderToTexture = function(downloadImage, reEnableEntities) {
this.entityCamera.camera.renderTarget = this.renderTarget;
this.app.render(this.app.scene, this.entityCamera.camera);
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.fb);
this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, this.colorBuffer._glTextureId, 0);
this.gl.readPixels(0, 0, this.colorBuffer.width, this.colorBuffer.height, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.pixels);
this.entityCamera.camera.renderTarget = null;
var ctx = this.canvas.getContext("2d"),
img = this.pixels;
this.canvas.width = this.colorBuffer.width;
this.canvas.height = this.colorBuffer.height;
// Get a pointer to the current location in the image.
var palette = ctx.getImageData(0,0,this.colorBuffer.width, this.colorBuffer.height); //x,y,w,h
// Wrap your array as a Uint8ClampedArray
palette.data.set(new Uint8ClampedArray(img)); // assuming values 0..255, RGBA, pre-mult.
// Repost the data.
ctx.putImageData(palette,0,0);
// rotate
var ctxFinal = this.canvasFinal.getContext("2d");
this.canvasFinal.width = this.colorBuffer.width;
this.canvasFinal.height = this.colorBuffer.height;
ctxFinal.scale(1,-1);
ctxFinal.translate(0,-this.canvas.height);
ctxFinal.drawImage(this.canvas, 0,0);
var image = this.canvasFinal.toDataURL('image/png');
reEnableEntities(image);
if( downloadImage === true ){
window.location.href = image.replace('image/png', 'image/octet-stream');
}
};