Python BGL Colors are broken since 2.83 : Brighter and Low Constrast #79788

Open
opened 2020-08-14 19:20:00 +02:00 by Enguerrand Quilliard · 26 comments

System Information
Operating system: Linux-4.15.0-112-generic-x86_64-with-debian-buster-sid 64 Bits
Graphics card: GeForce RTX 2080 Ti/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 440.64

Blender Version
Broken: version: 2.91.0 Alpha, branch: master, commit date: 2020-08-13 18:18, hash: blender/blender@275f1039d2
Broken: version: 2.83.4, branch: master, commit date: 2020-08-05 06:00, hash: blender/blender@c113af8288
Worked: version: 2.82 (sub 7), branch: master, commit date: 2020-02-12 16:20, hash: blender/blender@77d23b0bd7
bgl_2.83_bug_example_.blend

Short description of error
Colors are not "True" colors in BGL renders (viewport or any other screen in UI)
They are much brighter and less contrasted.
See attached PNG images for comparaison.
bgl_2.82_ok.png
bgl_2.83_bug.png
See attached GIF file for an animated comparaison between 2.82 and 2.83
comparaison.gif
The problem remains in 2.91 as well
I tried to change the color management settings if the bpy.data.image object on loading images, but it does not fix the problem.
Anyway the colors are different as well for text (BLF) and plain color polygons.

Exact steps for others to reproduce the error
Basically, error is reproduced by doing any kind of display in UI using python and BGL : lines, surfaces, or even 2D images
Colors are not the "right" ones.

The .blend file is ready to be launched "Run Script" to reproduce the bug, and contains both image and python script.
bgl_2.83_bug_example_.blend

If external python file is prefered, python file is attached as well for reproducing. Same than the .blend except the path to image is external.
The car image for example is attached as well
color_issue_2.83_bgl_example.py
car.png

The code to reproduce issue is inspired from official examples available here :
https://docs.blender.org/api/blender2.8/gpu.html
https://docs.blender.org/api/blender2.8/blf.html

**System Information** Operating system: Linux-4.15.0-112-generic-x86_64-with-debian-buster-sid 64 Bits Graphics card: GeForce RTX 2080 Ti/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 440.64 **Blender Version** Broken: version: 2.91.0 Alpha, branch: master, commit date: 2020-08-13 18:18, hash: `blender/blender@275f1039d2` Broken: version: 2.83.4, branch: master, commit date: 2020-08-05 06:00, hash: `blender/blender@c113af8288` Worked: version: 2.82 (sub 7), branch: master, commit date: 2020-02-12 16:20, hash: `blender/blender@77d23b0bd7` [bgl_2.83_bug_example_.blend](https://archive.blender.org/developer/F8780768/bgl_2.83_bug_example_.blend) **Short description of error** Colors are not "True" colors in BGL renders (viewport or any other screen in UI) They are much brighter and less contrasted. See attached PNG images for comparaison. ![bgl_2.82_ok.png](https://archive.blender.org/developer/F8780766/bgl_2.82_ok.png) ![bgl_2.83_bug.png](https://archive.blender.org/developer/F8780765/bgl_2.83_bug.png) See attached GIF file for an animated comparaison between 2.82 and 2.83 ![comparaison.gif](https://archive.blender.org/developer/F8780764/comparaison.gif) The problem remains in 2.91 as well I tried to change the color management settings if the bpy.data.image object on loading images, but it does not fix the problem. Anyway the colors are different as well for text (BLF) and plain color polygons. **Exact steps for others to reproduce the error** Basically, error is reproduced by doing any kind of display in UI using python and BGL : lines, surfaces, or even 2D images Colors are not the "right" ones. The .blend file is ready to be launched "Run Script" to reproduce the bug, and contains both image and python script. [bgl_2.83_bug_example_.blend](https://archive.blender.org/developer/F8780781/bgl_2.83_bug_example_.blend) If external python file is prefered, python file is attached as well for reproducing. Same than the .blend except the path to image is external. The car image for example is attached as well [color_issue_2.83_bgl_example.py](https://archive.blender.org/developer/F8780775/color_issue_2.83_bgl_example.py) ![car.png](https://archive.blender.org/developer/F8780767/car.png) The code to reproduce issue is inspired from official examples available here : https://docs.blender.org/api/blender2.8/gpu.html https://docs.blender.org/api/blender2.8/blf.html

Added subscriber: @Tricotou

Added subscriber: @Tricotou

Added subscribers: @brecht, @rjg

Added subscribers: @brecht, @rjg

@brecht I vaguely remember (might be misremembering) that the color management approach for OpenGL / viewport drawing was changed between versions in the overlay refactor. Could this be an issue of outdated documentation, e.g. a missing command that is now required to use the correct color management on an image buffer, or is this a bug?

@brecht I vaguely remember (might be misremembering) that the color management approach for OpenGL / viewport drawing was changed between versions in the overlay refactor. Could this be an issue of outdated documentation, e.g. a missing command that is now required to use the correct color management on an image buffer, or is this a bug?
Found the relevant changes: - https://developer.blender.org/T74139 - https://developer.blender.org/rB21c658b718b9
Member

Added subscriber: @EAW

Added subscriber: @EAW
Member

Relevant part in the release notes:

Custom shaders need to be patched using the function blender_srgb_to_framebuffer_space. This ensure the output color is transformed to the correct color space. (21c658b718, blender/blender#74139)

Example of a patched fragment shader:


void main() {
 vec4 srgb_color = vec4(0.5);
out_color = blender_srgb_to_framebuffer_space(srgb_color);
}```

https://wiki.blender.org/wiki/Reference/Release_Notes/2.83/Python_API

It is also at the bottom of:
https://www.blender.org/download/releases/2-83/

Custom shaders need to be patched using the function blender_srgb_to_framebuffer_space. This ensure the output color is transformed to the correct color space. (commit, task)

Relevant part in the release notes: > Custom shaders need to be patched using the function `blender_srgb_to_framebuffer_space`. This ensure the output color is transformed to the correct color space. (21c658b718, blender/blender#74139) > > Example of a patched fragment shader: > >``` out vec4 out_color; > > void main() { > vec4 srgb_color = vec4(0.5); > out_color = blender_srgb_to_framebuffer_space(srgb_color); >}``` https://wiki.blender.org/wiki/Reference/Release_Notes/2.83/Python_API It is also at the bottom of: https://www.blender.org/download/releases/2-83/ >Custom shaders need to be patched using the function blender_srgb_to_framebuffer_space. This ensure the output color is transformed to the correct color space. ([commit](https:*developer.blender.org/rB21c658b718b9), [task](https:*developer.blender.org/T74139))

@EAW thanks for your advice, indeed I did not see this note in the 2.83 release.
A few things :

  • I was not using absolute "custom" shaders, but the default ones from gpu.shader.from_builtin( ).

  • I had a look in the GLSL code of all the default builtin shaders, using gpu.shader.code_from_builtin( ) with '2D_UNIFORM_COLOR', '2D_FLAT_COLOR', '2D_SMOOTH_COLOR', '2D_IMAGE', '3D_UNIFORM_COLOR', '3D_FLAT_COLOR', '3D_SMOOTH_COLOR' ... In fact the blender_srgb_to_framebuffer_space function is already used in all of them, EXCEPT the 2D_IMAGE that I was actually using for the image in my example, which is not normal, I suppose.

  • So, one bug is the lack of blender_srgb_to_framebuffer_space function in the default 2D_IMAGE builtin fragment shader :
    Current state :

in vec2 texCoord_interp;
out vec4 fragColor;
uniform sampler2D image;
void main()
{
    fragColor = texture(image, texCoord_interp);
}

Fix proposal :

in vec2 texCoord_interp;
out vec4 fragColor;
uniform sampler2D image;
void main()
{
    vec4 srgb_color = texture(image, texCoord_interp);
    fragColor = blender_srgb_to_framebuffer_space(srgb_color);
}

The above solution works fine for image rending in BGL.

That said :

  • There is still a big difference for the 2D_UNIFORM_COLOR shader (which is already using the blender_srgb_to_framebuffer_space function)
  • How to deal with font rendering ? Because as far as I know, I use the code from this page : https://docs.blender.org/api/blender2.8/blf.html So here there is really no use of any custom shader for blf. Color is still very different from 2.82 to 2.83 (see the GIF in the first post, color almost going from blue to white). I think the blf shaders should be binded with blender_srgb_to_framebuffer_space as well.
@EAW thanks for your advice, indeed I did not see this note in the 2.83 release. A few things : - I was not using absolute "custom" shaders, but the default ones from **gpu.shader.from_builtin( )**. - I had a look in the **GLSL** code of all the default builtin shaders, using **gpu.shader.code_from_builtin( )** with '2D_UNIFORM_COLOR', '2D_FLAT_COLOR', '2D_SMOOTH_COLOR', '2D_IMAGE', '3D_UNIFORM_COLOR', '3D_FLAT_COLOR', '3D_SMOOTH_COLOR' ... In fact the **blender_srgb_to_framebuffer_space** function is already used in all of them, EXCEPT the **2D_IMAGE** that I was actually using for the image in my example, which is not normal, I suppose. - So, one bug is the **lack of blender_srgb_to_framebuffer_space function in the default 2D_IMAGE builtin fragment shader** : Current state : ``` in vec2 texCoord_interp; out vec4 fragColor; uniform sampler2D image; void main() { fragColor = texture(image, texCoord_interp); } ``` Fix proposal : ``` in vec2 texCoord_interp; out vec4 fragColor; uniform sampler2D image; void main() { vec4 srgb_color = texture(image, texCoord_interp); fragColor = blender_srgb_to_framebuffer_space(srgb_color); } ``` The above solution works fine for image rending in BGL. That said : - There is still a big difference for the **2D_UNIFORM_COLOR** shader (which is already using the **blender_srgb_to_framebuffer_space** function) - How to deal with font rendering ? Because as far as I know, I use the code from this page : https://docs.blender.org/api/blender2.8/blf.html So here there is really no use of any custom shader for blf. Color is still very different from 2.82 to 2.83 (see the GIF in the first post, color almost going from blue to white). I think the blf shaders should be binded with **blender_srgb_to_framebuffer_space** as well.

Added subscriber: @fclem

Added subscriber: @fclem

CC @fclem.

CC @fclem.
Member

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'
Member

Added subscriber: @Jeroen-Bakker

Added subscriber: @Jeroen-Bakker
Member

I will report this as a Bug due to API limitations and confusion

I will report this as a Bug due to API limitations and confusion
Member

Added subscriber: @VilemDuha

Added subscriber: @VilemDuha
Member

Not sure this is related, but alpha in bgl is broken in 2.91 -
image.png

Not sure this is related, but alpha in bgl is broken in 2.91 - ![image.png](https://archive.blender.org/developer/F8935170/image.png)
Member

Added subscriber: @lichtwerk

Added subscriber: @lichtwerk
Member

In #79788#1025211, @VilemDuha wrote:
Not sure this is related, but alpha in bgl is broken in 2.91 -
image.png

Without exactly knowing your code, but this could be the fact that you need to call glClearColor prior to glClear in 2.9?

bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)

see blender/blender#79491 (GL_BLEND ignores texture alpha channel)

> In #79788#1025211, @VilemDuha wrote: > Not sure this is related, but alpha in bgl is broken in 2.91 - > ![image.png](https://archive.blender.org/developer/F8935170/image.png) Without exactly knowing your code, but this could be the fact that you need to call `glClearColor` prior to `glClear` in 2.9? ``` bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) ``` see blender/blender#79491 (GL_BLEND ignores texture alpha channel)
Member

These functions tend to clear too much (actually the whole viewport) and I'm using code from these basic samples:

https://docs.blender.org/api/current/gpu.html

for both image and rectangle. Pasting here the image draw example:

import bpy
import gpu
import bgl
from gpu_extras.batch import batch_for_shader

IMAGE_NAME = "Untitled"
image = bpy.data.images['.arrow_left.png']

shader = gpu.shader.from_builtin('2D_IMAGE')
batch = batch_for_shader(
    shader, 'TRI_FAN',
    {
        "pos": ((100, 100), (200, 100), (200, 200), (100, 200)),
        "texCoord": ((0, 0), (1, 0), (1, 1), (0, 1)),
    },
)

if image.gl_load():
    raise Exception()


def draw():
    bgl.glActiveTexture(bgl.GL_TEXTURE0)
    bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode)

    shader.bind()
    shader.uniform_int("image", 0)
    batch.draw(shader)


bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')

image.png

These functions tend to clear too much (actually the whole viewport) and I'm using code from these basic samples: https://docs.blender.org/api/current/gpu.html for both image and rectangle. Pasting here the image draw example: ``` import bpy import gpu import bgl from gpu_extras.batch import batch_for_shader IMAGE_NAME = "Untitled" image = bpy.data.images['.arrow_left.png'] shader = gpu.shader.from_builtin('2D_IMAGE') batch = batch_for_shader( shader, 'TRI_FAN', { "pos": ((100, 100), (200, 100), (200, 200), (100, 200)), "texCoord": ((0, 0), (1, 0), (1, 1), (0, 1)), }, ) if image.gl_load(): raise Exception() def draw(): bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode) shader.bind() shader.uniform_int("image", 0) batch.draw(shader) bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') ``` ![image.png](https://archive.blender.org/developer/F8935401/image.png)
Member

Dont you have to enable GL_BLEND?

bgl.glEnable(bgl.GL_BLEND)

(in the middle of something else, can check later, too...)

Dont you have to enable GL_BLEND? ``` bgl.glEnable(bgl.GL_BLEND) ``` (in the middle of something else, can check later, too...)
Member

Checked on the alpha issue, enabling GL_BLEND works, but only to a degree (looks wrong), reported separately to not hijack this task, see blender/blender#81289 (Python gpu bgl image drawing alpha problem)

Checked on the alpha issue, enabling GL_BLEND works, but only to a degree (looks wrong), reported separately to not hijack this task, see blender/blender#81289 (Python gpu bgl image drawing alpha problem)
  • For the image shader issue it's because it is expecting linear color images after sampling.
To fix your script you only need to change the texture format to `bgl.GL_SRGB8_ALPHA8`. This needs to be written in the documentation somewhere.
  • For BGL, this has been fixed already. The slight change in color might be caused by the difference in color accuracy.
  • The Squares have the correct color but the blending is now done in linear space instead of sRGB space, which leads to discrepency when using alpha blending. This is expected (see https://developer.blender.org/T74139#910015) but never mentioned in the release notes.
- For the image shader issue it's because it is expecting linear color images after sampling. ``` To fix your script you only need to change the texture format to `bgl.GL_SRGB8_ALPHA8`. This needs to be written in the documentation somewhere. ``` - For BGL, this has been fixed already. The slight change in color might be caused by the difference in color accuracy. - The Squares have the correct color but the blending is now done in linear space instead of sRGB space, which leads to discrepency when using alpha blending. This is expected (see https://developer.blender.org/T74139#910015) but never mentioned in the release notes.

Added subscriber: @ideasman42

Added subscriber: @ideasman42

Can this be resolved by updating docs?

Can this be resolved by updating docs?

Added subscriber: @JacobMerrill-1

Added subscriber: @JacobMerrill-1

will gpu module be getting all it's own approximations of these functions for vulkan etc?

I seem to remember bgl was being depreciated ?

will gpu module be getting all it's own approximations of these functions for vulkan etc? I seem to remember bgl was being depreciated ?

Added subscriber: @letg

Added subscriber: @letg

In #79788#1034183, @fclem wrote:

  • For the image shader issue it's because it is expecting linear color images after sampling.
    To fix your script you only need to change the texture format to bgl.GL_SRGB8_ALPHA8. This needs to be written in the documentation somewhere.
  • For BGL, this has been fixed already. The slight change in color might be caused by the difference in color accuracy.
  • The Squares have the correct color but the blending is now done in linear space instead of sRGB space, which leads to discrepency when using alpha blending. This is expected (see https://developer.blender.org/T74139#910015) but never mentioned in the release notes.

imagec_001.png

imagec_002.png

imagec_003.png

(The image is the exported png) (1)

When I loaded an image as texture with shader.uniform_sampler or with glTexImage2D or glBindTexture, it is always not represented correctly, mostly a bit too bright. (3) (my draw function is draw_handler_add(drawf, (), 'WINDOW', 'POST_VIEW'))

I tried already to use GL_SRGB8_ALPHA8 (with glTexImage2D) and blender_srgb_to_framebuffer_space. These both made it too dark and a bit saturated. (2) (Both look very similar)
I even tried a Gamma Correction in the GLSL Shader.

I tried to tweak some of the blender_srgb_to_framebuffer_space glsl code when I used my own version of this source/blender/gpu/shaders/gpu_shader_colorspace_lib.glsl implementation.

Perhaps the location where the image editor loads its image could be helpful too. Then I can see how this part displays the color correctly even for different display devices.

Thank you in Advance.

> In #79788#1034183, @fclem wrote: > - For the image shader issue it's because it is expecting linear color images after sampling. > To fix your script you only need to change the texture format to `bgl.GL_SRGB8_ALPHA8`. This needs to be written in the documentation somewhere. > - For BGL, this has been fixed already. The slight change in color might be caused by the difference in color accuracy. > - The Squares have the correct color but the blending is now done in linear space instead of sRGB space, which leads to discrepency when using alpha blending. This is expected (see https://developer.blender.org/T74139#910015) but never mentioned in the release notes. ![imagec_001.png](https://archive.blender.org/developer/F13305805/imagec_001.png) ![imagec_002.png](https://archive.blender.org/developer/F13305807/imagec_002.png) ![imagec_003.png](https://archive.blender.org/developer/F13305809/imagec_003.png) (The image is the exported png) (1) When I loaded an image as texture with shader.uniform_sampler or with glTexImage2D or glBindTexture, it is always not represented correctly, mostly a bit too bright. (3) (my draw function is draw_handler_add(drawf, (), 'WINDOW', 'POST_VIEW')) I tried already to use GL_SRGB8_ALPHA8 (with glTexImage2D) and blender_srgb_to_framebuffer_space. These both made it too dark and a bit saturated. (2) (Both look very similar) I even tried a Gamma Correction in the GLSL Shader. I tried to tweak some of the blender_srgb_to_framebuffer_space glsl code when I used my own version of this source/blender/gpu/shaders/gpu_shader_colorspace_lib.glsl implementation. Perhaps the location where the image editor loads its image could be helpful too. Then I can see how this part displays the color correctly even for different display devices. Thank you in Advance.
Aaron Carlisle removed the
Module
Eevee & Viewport
Module
Python API
labels 2023-02-08 04:59:48 +01:00
Aaron Carlisle added the
Module
Eevee & Viewport
label 2023-08-13 15:15:51 +02:00
Aaron Carlisle added
Module
Python API
and removed
Module
Eevee & Viewport
labels 2023-08-13 15:30:49 +02:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
11 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-manual#79788
No description provided.