Get pixel of RenderTexture

I am doing scratch game and trying to detect percent of scratched area. I am using renderTexture to make scratch effect:

userCanvas = this.add.renderTexture(0, 0, 800, 600);

this.input.on('pointermove', function (pointer) {
if (pointer.isDown) {
  userCanvas.draw('brush', pointer.x - 32, pointer.y - 32);

  var pixel = userCanvas.texture.getPixel(100, 100);
  document.getElementById('color').textContent =  "rgb(" + pixel.r + "," + pixel.g + "," + pixel.b + ")";
}}, this);

But there is not possible to get color of individual pixels. Its always return zero.
I tried to saveTexture with some key, extract it and then get color - but result is the same.
What I am doing wrong ?

Full example: https://codepen.io/hoshinokoe/pen/MWyBzYb

Texture has no getPIxel method. Use it on the canvas.

Please provide code sample.

var rgb = userCanvas.context.getImageData(100, 100, 1, 1);
console.log(rgb.data);

It works only for game type = Phaser.CANVAS.
if I set type = Phaser.AUTO then it using webgl rendering and returns always zero.
How to get pixel in this case?

Example updated: https://codepen.io/hoshinokoe/pen/MWyBzYb

Thanks for answer. It can get one pixel inside callback, but its not enough to detect scratched area.

this.game.renderer.snapshotPixel(pointer.x, pointer.y, function (pixel)
{
    g.clear();
    g.fillStyle(pixel.color);
    g.fillRect(0, 0, 128, 128);

});

There is another method to get area, but it also returns data inside callback.

this.game.renderer.snapshotArea(pointer.x, pointer.y, 128, 128, function (image)     {
    document.body.appendChild(image);
    if (textureManager.exists('area'))
    {
        textureManager.remove('area');
    }
    textureManager.addImage('area', image);
    particles.setTexture('area');
});

And again, my goal is way to detect scratched area of existing renderTexture object. Idea was to get all pixels and check color. I don’t understand how to do that with folowing methods.

You are a moving target :slight_smile:

It returns final image of game, not only renderTexture. E.g. if game has background image, it will contains.
So main question still open.

userCanvas.snapshotArea(…)

Tested. No, it returns global game image. I think renderer is global object.

I think you have to use CanvasTexture for this. Or else make a snapshot, copy the image to a canvas and then get pixels.

userCanvas.renderer.snapshotArea works fine for me.

Without ‘renderer’ it doesn’t, which is a bug I think…

I tested RenderTexture#snapshot and RenderTexture#snapshotArea, both worked correctly.

The renderer methods are global, those are different.

snapshot snapshotArea

Strange. I tested on the OP’s CodePen. The global method works, the RenderTexture one doesn’t.
If I look at the Phaser code, it shouldn’t make any difference? It just passes through, based on Canvas or WebGL…

In that pen, userCanvas.snapshotArea(…) does snapshot correctly, but I think userCanvas.context.getImageData(…) will always get a blank pixel in WEBGL mode.

userCanvas.snapshotArea(…)

It capture correctly, it was my mistake.

So full solution will be:

  1. for canvas render just use getImageData() and check pixels
  2. for webGl render
  • get snapshot area
  • save image to canvas
  • getImageData() and check pixels

Thanks for help. if somebody knows more easier solution, I will appreciate.

  var gl = userCanvas.gl.canvas.getContext('experimental-webgl');
  var pixels = new Uint8Array(1 * 1 * 4);
  gl.readPixels(100, 100, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

I found in sources of snapshot method how webGl gets all pixels. But it always return zeros. What is wrong ?

Demo updated: https://codepen.io/hoshinokoe/pen/MWyBzYb

I think, your problem is described here: https://stackoverflow.com/questions/7156971/webgl-readpixels-is-always-returning-0-0-0-0

You get zeroes as drawing buffer got cleared.

Did anybody manage to get the pixel data of RenderTexture with snapshotPixel method correctly?
Other thing is, that although the game.renderer.snapshotPixel method correctly returns the color value of the pixel rom the game canvas image, the alpha value is max 1 for non-transparent pixel (should be 255), and alphaGL is max 0.00392156862745098 (should be 1).

Tested with Phaser 3.55.2

Greg.