Measure light intensity

Hi guys,
I’m new here, and I’m just starting in the three.js world, so it’s a pleasure to say hi to you all! :slight_smile:

I’m trying to get the light intensity at any point of the canvas through using an offScreenCanvas, getting its context 2d and then using “getImageData” (that way I could get the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255 values).

The thing is that I could only make it work on a friend’s computer where I could print values on the array (i.e. [ 123, 123, 123, 255 ]). In the rest of computers I couldn’t print more values, it always says [ 0, 0, 0, 255 ].

I don’t know if it might have something to do with the graphics card. I’ve updated my computer and the browser just in case.

I’ve uploaded the code to jsfiddle: Shadow Light Intensity - JSFiddle - Code Playground
Also, it’s my first time using jsfiddle as well, and I can’t make the scene appear :frowning:

However, below I attach a picture.

Thanks!!

1 Like

AFAIK, what you do is not the intended work of extracting pixel values. Others tried it and failed, too. E.g. javascript - Read pixel information from a WebGL 3D canvas return all [0, 0, 0, 255] - Stack Overflow.

You normally extract pixel values with the readPixels() WebGL API. To avoid setting the renderer parameter preserveDrawingBuffer to true, you should always render into a render target (a custom framebuffer) and then extract the color value via WebGLRenderer.readRenderTargetPixels(). Preversing the drawing buffer is necessary if you want to work with the canvas (e.g. saving the contents as a screenshot) which is however bad for performance.

I suggest you use the following example as a template: three.js webgl - read float pixels

1 Like

Javier that’s not going to tell me anything. OS/Browser name version?

Here is a demo that uses WebGL readPixels() to get pixel data under mouse:
Z_Model.html (101.4 KB)

To activate keyboard commands make the mouse is over the canvas and has focus.

  • Press C key on keyboard to launch readPixels().
  • Press E key Chrome 95+ to launch EyeDropper().

1 Like

Or you could call render(), mush simpler approach.

Again call render() to repopulate the buffer. No need to run renderer with reserveDrawingBuffer flag on for sake of taking a snap_shot.

1 Like

About the Fiddle not showing the 3D scene, you could try to move your import statements to the HTML section (then hit “Run”): Shadow Light Intensity - JSFiddle - Code Playground

1 Like

That example you sent me works well on my computer.
I’m using MacOS Monterrey 12.3.1 with an Intel Iris Plus Graphics 640 1536 MB, and Chrome 101.0.4951.54.
Thanks for your time

Hi there,
I couldn’t solve this problem. At the end, what I did was using this code to capture the color of any pixel in the canvas (by collecting the information of each pixel on the screen using a “render target”).

var rtTexture = new THREE.WebGLRenderTarget(
    sizes.width,
    sizes.height,
    {minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat, type: THREE.FloatType})

function capture()
{
    renderer.clear()
    renderer.setRenderTarget( rtTexture )
    renderer.render( scene, camera )

    renderer.setRenderTarget( null )
    renderer.render( scene, camera )

    var read = new Float32Array( 4 )
    renderer.readRenderTargetPixels( rtTexture, sizes.width / 2 , sizes.height / 2, 1, 1, read )

    return read
}