Closed anicolao closed 2 years ago
maybe i can try to answer that with how we decided to make it a default in fiber. for most cases yes, filmic is what gives you high dynamic range and less banding/clipping, it's the 🔑 for good looking scenes. w/o that everything can have that 90s era plastic cgi toy look because colors blow open.
the problem is that colors are subjective, you have colors on your site and you expect them to be the same in your canvas, but the website isn't lit. in three lights, environments, shadows, must change a colors tone. there's no defined "green" any longer just like in the real world (hold an apple near the window, underneath the table, dawn, etc).
toneMapped=false on materials is usually a better way to flag certain materials to fall outside the norm, for instance an image or a videotexture. in vanilla three that is reversed, but people struggle a lot to create professional grade scenes.
While I happen to agree that a different tone mapping is needed for theatrical or realistic game scenes, I would have thought that artists making that kind of content would quickly realize the tone mapping was wrong and fix it up while they are getting their scene correct.
Meanwhile, since threlte
claims to provide a very thin wrapper around three.js
and have 'sensible defaults', I think it was quite reasonable for me to assume that the tone mapping default was the usual default (there is no documentation to the contrary) and having it be something else was definitely unreasonable. At a minimum the wrong default should be documented and explained; though it makes much more sense to me to have an example of why you might want to set the default differently in your canvas while pointing out that the existing default is in fact the most logical one for a scene that is by default painted on a transparent background and therefore has its colours mixed right in with the background colour of the page, and good luck to you if you can't figure out why objects in the scene that are meant to match the page do not...
Hi @anicolao,
I understand your frustrations. Color management can be tough to master, especially in complex applications many moving parts involved that in the end don't match what you're after. I still stand by the decision that threltes (and r3f's) approach is what most people are after and therefore it's set as the default but I also see that the documentation is lacking in that respect. Maybe we also have to find a better naming for the respective props on <Canvas />
.
Sorry if I sounded frustrated, that was not my intention. I am actually trying to be helpful.
I think we'll have to agree to disagree on what 'most people' want, because I don't have any source of information on who is using webgl for what. If I'd had to guess, I would have put candy crush-style games at the top of the list (basically any 2D video game, all of which are made of bright saturated colours: candy crush, tetris, cut the rope, and even "3d" games like clash of clans); second I would have imagined people using it as a substitute for 3D CSS (especially because threlte makes it very practical to write nice UI component that interact with the rest of the universe in a very slick way) and demos of what is possible with webgl in a vain attempt to convince people to do "real 3d graphics" in the browser when everyone who is writing AAA content is writing directly to metal or vulkan, or even more likely using a game engine like unity to produce their content (which obviously will have it's own default). If I'm wrong about what 'most people' are doing, I have no source of evidence one way or another, it's all just opinions...
So let's accept my opinion is wrong. Then a transparent background is also very much the wrong default. You do not want your 3D photo-realistic world on a backdrop of bright white or perfect black, you need to render the scene into your box without any blown out colours anywhere. So that too ought to change.
This bug I think should be closed as 'won't fix' and then we can file a new feature request against the docs to talk about colour defaults up front somewhere that people will see it.
In case you can make use of the debugging, I was building a simple 3D rubik's cube in threlte, and of the about 8 hours I spent on it, I spent more than 5 hours on the colour problem. The first hour or so went into figuring out that I was in the wrong colour space; as I remember it I was allowed to specify colours as CSS strings and these were being interpreted in linear colour space instead of sRGB. I spent the bulk of that hour fiddling with the lights assuming they were causing my colour issue before realizing the colours were just way too off and I checked what colour space I was in to realize it was linear and I had to convert the colours. That got things so very close I almost stopped there (I actually don't necessarily want flat, but I couldn't let go of the fact that I didn't understand why my colours were still not what I expected). So I went back and spent more time fiddling with the lighting, looped someone else in, and after another hour or two they found the option on canvas for this and it was fixed.
So for me, helpful things would have been:
Canvas
is first introduced;note that CSS colours aren't in sRGB all the time
This can be fixed by setting...
// should be set before initializing THREE.Color objects.
THREE.ColorManagement.enabled = true;
... beginning in three.js r150. In earlier releases it was named THREE.ColorManagement.legacyMode = false
. With that change, hexadecimal and CSS colors are interpreted as sRGB by default, and converted automatically to the Linear-sRGB colors required for rendering. RGB components (color.r, color.g, color.b) and other methods of working with color remain in Linear-sRGB. We felt that hexadecimal and CSS colors were exceptions by convention, and Blender does something very similar.
About tone mapping — a general rule of thumb is that some form of tone mapping should generally be used if your scene has lighting. The scene contains light values on the open domain [0, ∞], and without tone mapping values are abruptly cropped at [0,1]. Without lighting, or when rendering unlit materials, illustrated styles, and photogrammetry that already has light information baked into the texture, it is better to disable tone mapping, as there's nothing outside the [0,1] range to tone map.
Aside — I've slowly come to the conclusion that color management is one area where it's helpful to use more precise and/or verbose names than we normally do in JavaScript APIs. For example, using "linear" to refer to a colorspace will become ambiguous with upcoming WebGL wide-color-gamut support: do you mean Linear sRGB? Linear Display P3? What is the white point? The color spaces defined by CSS Color Module Level 4 are a good start, though we'll need to include a few more for WebGL / WebGPU purposes.
I spent multiple hours today trying to get colours to match with colours in my web page to no avail before discovering that the tone mapping default isn't the normal three.js tone mapping default.