Image Processing
In case you are using an ImageProcessingPostProcess on your scene, or another post process that may use ImageProcessingPostProcess under the hood, like MotionBlurPostProcess, you will notice a slightly different color output in the final image, compared to what you want to output with gl_FragColor.
This is because ImageProcessingPostProcess expects a linear color input and therefore converts every pixel to gamma color space. If you want to read more about linear color space versus gamma color space, read this.
Fix my pixel shader
To spare you the reading, basically, your gl_FragColor is put to the power 1 / 2.2, which we call a standard gamma transformation.
To counteract that, you should apply the opposite transformation, which in GLSL is:
#ifdef IMAGEPROCESSINGPOSTPROCESS gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(2.2));#endifOf course, you only want this additional line in your shader if an ImageProcessingPostProcess is active in your scene. That's why you must enclose it in a #define statement.
For convenience, we added a small shader include that does just that. You can add this after every gl_FragColor output:
#include<imageProcessingCompatibility>Now you need to toggle that define based on the presence of an ImageProcessingPostProcess.
In your material code, it should look something like this:
defines.IMAGEPROCESSINGPOSTPROCESS = scene.imageProcessingConfiguration.applyByPostProcess;And now, whether you have the post-process active or not, the color should be similar!
Further Reading
You may have a similar problem if you want to use fog in your scene with a custom shader material.
Here is a helpful page to get your shaders to be fog-ready.
Tonemapping
If you are using tonemapping on your materials, your image may appear brighter than expected. This means that several image-processing steps are being applied in your pipeline.
Some post processes internally use a prepass to gather information, and this prepass performs some image processing itself. In that case, color can be processed several times, which is incorrect. For instance, this can happen if you use pbr.imageProcessingConfiguration = myImageProcessingConfiguration; along with an SSAO2RenderingPipeline.
So if you notice that problem, try to manually deactivate the gamma transform in the prepass:
scene.enablePrePassRenderer().disableGammaTransform = true;Colors should then behave as expected from your imageProcessingConfiguration.