With ShaderMaterial, color on screen is different from gl_FragColor?

I am on the verge of going insane, I hope the gurus here can shed some light on what I’m experiencing. I’m trying to output precise RGB values to a canvas, and I noticed that the RGB values I’m getting in the output are different from what I specify in gl_FragColor.

Here is a simple Codepen that demonstrates this: https://codepen.io/gugray/pen/QWxEWoB

Specifically, with the line below:

gl_FragColor.rgb = vec3(1.0, 1.0, 1.0);

I get white (255, 255, 255) as expected. Black also works.

Things make no sense whatsoever with any of the values in between:

gl_FragColor.rgb = vec3(1.0, 0.0, 0.0); // Yields 234, 51, 35. Expected: 255, 0, 0
gl_FragColor.rgb = vec3(0.5, 0.5, 1.0); // Yields 128, 128, 247. Expected: 128, 128, 255
gl_FragColor.rgb = vec3(0.5, 1.0, 1.0); // Yields 161, 252, 254. Expected: 128, 255, 255. 

What is happening here? There must be something mind-bogglingly trivial that I’m missing, but I cannot for the life of me figure out what. Any help is life-saving at this point and appreciated as such!

When you say “Yields 234, 51, 35”, how are you measuring that? Checking the output with Digital Color Meter on macOS, with sRGB color space selected, it looks like what you’d expect:

Keep in mind that some newer displays (e.g. MacBook Pro) use Display P3 natively. If your color meter uses Display P3, the RGB values will be different. The values you’re reporting do appear to be in Display P3 color space.

As of this writing, a WebGL canvas values are always specified in sRGB (e.g by your shader) and will be later adapted to the display color space by the browser and/or operating system.


Thak you for the response! It seems to be exactly as you write. I measured the values by taking a screenshot and picking pixels in an image viewer. I do indeed use a recent Macbook Air. Never heard of Display P3 until today. Now I’m that much smarter.

So I went on and retrieved the canvas’s pixel from code, and the bytes in the array are exactly as I expect them to be.

I only included this step as a sanity check along the way before building more complex stuff on top of it… And it it turned out to be the perfect banana to slip on. :person_facepalming:!