From e2dc63c5deba4e247277f90e4d0285448f801ede Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 16 Oct 2025 19:12:16 +0200 Subject: [PATCH] Fix #147618: PyGPU incorrect colors when drawing images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 644fb2b67935b443b3ffede9412f5592b7ab24e5 fixed a long standing issue that offscreen example showed the wrong colors. However the fix assumes that input texture color space is always sRGB. This adds a shader variation that draws textures that are stored in scene referred linear color space (like all of our Image data-block). Co-authored-by: Clément Foucault Pull Request: https://projects.blender.org/blender/blender/pulls/147788 --- doc/python_api/examples/gpu.6.py | 4 +- scripts/modules/gpu_extras/presets.py | 13 +++- source/blender/gpu/GPU_shader.hh | 13 ++-- source/blender/gpu/GPU_shader_builtin.hh | 28 ++++++- source/blender/gpu/intern/gpu_shader.cc | 15 +++- .../blender/gpu/intern/gpu_shader_builtin.cc | 4 + .../gpu/intern/gpu_shader_interface.hh | 2 + .../blender/gpu/intern/gpu_shader_private.hh | 1 + .../shaders/gpu_shader_colorspace_lib.glsl | 78 +++++++++++++++---- .../shaders/gpu_shader_image_color_frag.glsl | 9 ++- .../gpu/shaders/gpu_shader_image_frag.glsl | 9 ++- .../gpu_shader_2D_image_rect_color_infos.hh | 1 + .../infos/gpu_shader_3D_image_infos.hh | 19 +++++ .../gpu_srgb_to_framebuffer_space_infos.hh | 5 ++ source/blender/python/gpu/gpu_py_shader.cc | 11 +++ 15 files changed, 178 insertions(+), 34 deletions(-) diff --git a/doc/python_api/examples/gpu.6.py b/doc/python_api/examples/gpu.6.py index a2071d2b2aa..dd9511f82ff 100644 --- a/doc/python_api/examples/gpu.6.py +++ b/doc/python_api/examples/gpu.6.py @@ -12,7 +12,7 @@ IMAGE_NAME = "Untitled" image = bpy.data.images[IMAGE_NAME] texture = gpu.texture.from_image(image) -shader = gpu.shader.from_builtin('IMAGE') +shader = gpu.shader.from_builtin('IMAGE_SCENE_LINEAR_TO_REC709_SRGB') batch = batch_for_shader( shader, 'TRI_FAN', { @@ -45,7 +45,7 @@ IMAGE_NAME = "Untitled" image = bpy.data.images[IMAGE_NAME] texture = gpu.texture.from_image(image) -shader = gpu.shader.from_builtin('IMAGE') +shader = gpu.shader.from_builtin('IMAGE_SCENE_LINEAR_TO_REC709_SRGB') batch = batch_for_shader( shader, 'TRIS', { diff --git a/scripts/modules/gpu_extras/presets.py b/scripts/modules/gpu_extras/presets.py index 0e880c8208a..2639d27c48a 100644 --- a/scripts/modules/gpu_extras/presets.py +++ b/scripts/modules/gpu_extras/presets.py @@ -58,7 +58,7 @@ def draw_circle_2d(position, color, radius, *, segments=None): batch.draw(shader) -def draw_texture_2d(texture, position, width, height): +def draw_texture_2d(texture, position, width, height, is_scene_linear_with_rec709_srgb_target=False): """ Draw a 2d texture. @@ -71,6 +71,13 @@ def draw_texture_2d(texture, position, width, height): :type width: float :arg height: Height of the image when drawn. :type height: float + :arg is_scene_linear_with_rec709_srgb_target: + True if the `texture` is stored in scene linear color space and + the destination framebuffer uses the Rec.709 sRGB color space + (which is true when drawing textures acquired from :class:`bpy.types.Image` inside a + 'PRE_VIEW', 'POST_VIEW' or 'POST_PIXEL' draw handler). + Otherwise the color space is assumed to match the one of the framebuffer. (default=False) + :type is_scene_linear_with_rec709_srgb_target: bool """ import gpu from . batch import batch_for_shader @@ -78,7 +85,8 @@ def draw_texture_2d(texture, position, width, height): coords = ((0, 0), (1, 0), (1, 1), (0, 1)) indices = ((0, 1, 2), (2, 3, 0)) - shader = gpu.shader.from_builtin('IMAGE') + shader = gpu.shader.from_builtin( + 'IMAGE_SCENE_LINEAR_TO_REC709_SRGB' if is_scene_linear_with_rec709_srgb_target else 'IMAGE') batch = batch_for_shader( shader, 'TRIS', {"pos": coords, "texCoord": coords}, @@ -89,7 +97,6 @@ def draw_texture_2d(texture, position, width, height): gpu.matrix.translate(position) gpu.matrix.scale((width, height)) - shader = gpu.shader.from_builtin('IMAGE') shader.uniform_sampler("image", texture) batch.draw(shader) diff --git a/source/blender/gpu/GPU_shader.hh b/source/blender/gpu/GPU_shader.hh index 0fb41c04034..513298c0dcf 100644 --- a/source/blender/gpu/GPU_shader.hh +++ b/source/blender/gpu/GPU_shader.hh @@ -371,13 +371,14 @@ enum GPUUniformBuiltin { GPU_UNIFORM_NORMAL, /* mat3 NormalMatrix */ GPU_UNIFORM_CLIPPLANES, /* vec4 WorldClipPlanes[] */ - GPU_UNIFORM_COLOR, /* vec4 color */ - GPU_UNIFORM_BASE_INSTANCE, /* int baseInstance */ - GPU_UNIFORM_RESOURCE_CHUNK, /* int resourceChunk */ - GPU_UNIFORM_RESOURCE_ID, /* int resourceId */ - GPU_UNIFORM_SRGB_TRANSFORM, /* bool srgbTarget */ + GPU_UNIFORM_COLOR, /* vec4 color */ + GPU_UNIFORM_BASE_INSTANCE, /* int baseInstance */ + GPU_UNIFORM_RESOURCE_CHUNK, /* int resourceChunk */ + GPU_UNIFORM_RESOURCE_ID, /* int resourceId */ + GPU_UNIFORM_SRGB_TRANSFORM, /* bool srgbTarget */ + GPU_UNIFORM_SCENE_LINEAR_XFORM, /* float3x3 gpu_scene_linear_to_xyz */ }; -#define GPU_NUM_UNIFORMS (GPU_UNIFORM_SRGB_TRANSFORM + 1) +#define GPU_NUM_UNIFORMS (GPU_UNIFORM_SCENE_LINEAR_XFORM + 1) /** * TODO: To be moved as private API. Not really used outside of gpu_matrix.cc and doesn't really diff --git a/source/blender/gpu/GPU_shader_builtin.hh b/source/blender/gpu/GPU_shader_builtin.hh index 4c379f88b00..e48413a3eb9 100644 --- a/source/blender/gpu/GPU_shader_builtin.hh +++ b/source/blender/gpu/GPU_shader_builtin.hh @@ -136,7 +136,9 @@ enum GPUBuiltinShader { GPU_SHADER_3D_POINT_UNIFORM_COLOR, /** - * Draw a texture in 3D. Take a 3D position and a 2D texture coordinate for each vertex. + * Draw a sRGB color space texture in 3D. + * Texture color space is assumed to match the framebuffer. + * Take a 3D position and a 2D texture coordinate for each vertex. * * \param image: uniform sampler2D * \param texCoord: in vec2 @@ -144,6 +146,17 @@ enum GPUBuiltinShader { */ GPU_SHADER_3D_IMAGE, /** + * Draw a scene linear color space texture in 3D. + * Texture value is transformed to the Rec.709 sRGB color space. + * Take a 3D position and a 2D texture coordinate for each vertex. + * + * \param image: uniform sampler2D + * \param texCoord: in vec2 + * \param pos: in vec3 + */ + GPU_SHADER_3D_IMAGE_SCENE_LINEAR_TO_REC709_SRGB, + /** + * Draw a sRGB color space (with Rec.709 primaries) texture in 3D. * Take a 3D position and color for each vertex with linear interpolation in window space. * * \param color: uniform vec4 @@ -152,8 +165,19 @@ enum GPUBuiltinShader { * \param pos: in vec3 */ GPU_SHADER_3D_IMAGE_COLOR, + /** + * Draw a scene linear color space texture in 3D. + * Texture value is transformed to the Rec.709 sRGB color space. + * Take a 3D position and color for each vertex with linear interpolation in window space. + * + * \param color: uniform vec4 + * \param image: uniform sampler2D + * \param texCoord: in vec2 + * \param pos: in vec3 + */ + GPU_SHADER_3D_IMAGE_COLOR_SCENE_LINEAR_TO_REC709_SRGB, }; -#define GPU_SHADER_BUILTIN_LEN (GPU_SHADER_3D_IMAGE_COLOR + 1) +#define GPU_SHADER_BUILTIN_LEN (GPU_SHADER_3D_IMAGE_COLOR_SCENE_LINEAR_TO_REC709_SRGB + 1) /** Support multiple configurations. */ enum GPUShaderConfig { diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index 6ea464574f4..e6b87ec8d3e 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -6,9 +6,10 @@ * \ingroup gpu */ +#include "BLI_colorspace.hh" #include "BLI_math_matrix.h" +#include "BLI_math_matrix_types.hh" #include "BLI_string.h" -#include "BLI_time.h" #include "GPU_capabilities.hh" #include "GPU_debug.hh" @@ -265,6 +266,9 @@ void GPU_shader_bind(blender::gpu::Shader *gpu_shader, shader->bind(constants_state); GPU_matrix_bind(gpu_shader); Shader::set_srgb_uniform(ctx, gpu_shader); + /* Blender working color space do not change during the drawing of the frame. + * So we can just set the uniform once. */ + Shader::set_scene_linear_to_xyz_uniform(gpu_shader); } else { if (constants_state) { @@ -634,6 +638,15 @@ void Shader::set_srgb_uniform(Context *ctx, blender::gpu::Shader *shader) ctx->shader_builtin_srgb_is_dirty = false; } +void Shader::set_scene_linear_to_xyz_uniform(blender::gpu::Shader *shader) +{ + int32_t loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_SCENE_LINEAR_XFORM); + if (loc != -1) { + GPU_shader_uniform_float_ex( + shader, loc, 9, 1, blender::colorspace::scene_linear_to_rec709.ptr()[0]); + } +} + void Shader::set_framebuffer_srgb_target(int use_srgb_to_linear) { Context *ctx = Context::get(); diff --git a/source/blender/gpu/intern/gpu_shader_builtin.cc b/source/blender/gpu/intern/gpu_shader_builtin.cc index 15c420a258d..a6445fbcfaf 100644 --- a/source/blender/gpu/intern/gpu_shader_builtin.cc +++ b/source/blender/gpu/intern/gpu_shader_builtin.cc @@ -35,8 +35,12 @@ static const char *builtin_shader_create_info_name(GPUBuiltinShader shader) return "gpu_shader_simple_lighting"; case GPU_SHADER_3D_IMAGE: return "gpu_shader_3D_image"; + case GPU_SHADER_3D_IMAGE_SCENE_LINEAR_TO_REC709_SRGB: + return "gpu_shader_3D_image_scene_linear"; case GPU_SHADER_3D_IMAGE_COLOR: return "gpu_shader_3D_image_color"; + case GPU_SHADER_3D_IMAGE_COLOR_SCENE_LINEAR_TO_REC709_SRGB: + return "gpu_shader_3D_image_color_scene_linear"; case GPU_SHADER_2D_CHECKER: return "gpu_shader_2D_checker"; case GPU_SHADER_2D_DIAG_STRIPES: diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh index 932992f6c1d..118b6d53ca3 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.hh +++ b/source/blender/gpu/intern/gpu_shader_interface.hh @@ -220,6 +220,8 @@ inline const char *ShaderInterface::builtin_uniform_name(GPUUniformBuiltin u) return "drw_ResourceID"; case GPU_UNIFORM_SRGB_TRANSFORM: return "srgbTarget"; + case GPU_UNIFORM_SCENE_LINEAR_XFORM: + return "gpu_scene_linear_to_rec709"; default: return nullptr; diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh index 9e930352945..7bfb4cb0e69 100644 --- a/source/blender/gpu/intern/gpu_shader_private.hh +++ b/source/blender/gpu/intern/gpu_shader_private.hh @@ -115,6 +115,7 @@ class Shader { return parent_shader_; } + static void set_scene_linear_to_xyz_uniform(gpu::Shader *shader); static void set_srgb_uniform(Context *ctx, gpu::Shader *shader); static void set_framebuffer_srgb_target(int use_srgb_to_linear); diff --git a/source/blender/gpu/shaders/gpu_shader_colorspace_lib.glsl b/source/blender/gpu/shaders/gpu_shader_colorspace_lib.glsl index 1174ca40514..14aeecc4ff2 100644 --- a/source/blender/gpu/shaders/gpu_shader_colorspace_lib.glsl +++ b/source/blender/gpu/shaders/gpu_shader_colorspace_lib.glsl @@ -2,6 +2,10 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ +/** + + */ + #pragma once #include "infos/gpu_srgb_to_framebuffer_space_infos.hh" @@ -11,20 +15,66 @@ SHADER_LIBRARY_CREATE_INFO(gpu_srgb_to_framebuffer_space) /* Undefine the macro that avoids compilation errors. */ #undef blender_srgb_to_framebuffer_space -/* Raw python shaders don't have create infos and thus don't generate the needed `srgbTarget` - * uniform automatically. For API compatibility, we sill define this loose uniform, but it will - * not be parsed by the Metal or Vulkan backend. */ -#ifdef GPU_RAW_PYTHON_SHADER -uniform bool srgbTarget = false; -#endif - -float4 blender_srgb_to_framebuffer_space(float4 in_color) +/** + * Input is Rec.709 sRGB. + * Output is Rec.709 linear if hardware will add a Linear to sRGB comversion, noop otherwise. + * NOTE: Old naming convention, but avoids breaking compatibility for python shaders. + * + * As per GPU API design, all framebuffers with SRGBA_8_8_8_8 attachments will always enable SRGB + * rendering. In this mode the shader output is expected to be in a linear color space. This allows + * to do the blending stage with linear values (more correct) and then store the result in 8bpc + * keeping accurate colors. + * + * To ensure consistent result (blending excluded) between a framebuffer using SRGBA_8_8_8_8 and + * one using RGBA_8_8_8_8, we need to do the sRGB > linear conversion to counteract the hardware + * encoding during framebuffer output. + * + * For reference: https://wikis.khronos.org/opengl/framebuffer#Colorspace + */ +float4 blender_srgb_to_framebuffer_space(float4 srgb_color) { - if (srgbTarget) { - float3 c = max(in_color.rgb, float3(0.0f)); - float3 c1 = c * (1.0f / 12.92f); - float3 c2 = pow((c + 0.055f) * (1.0f / 1.055f), float3(2.4f)); - in_color.rgb = mix(c1, c2, step(float3(0.04045f), c)); + /** + * IMPORTANT: srgbTarget denote that the output is expected to be in __linear__ space. + * https://wikis.khronos.org/opengl/framebuffer#Colorspace + */ + if (!srgbTarget) { + /* Input should already be in sRGB. */ + return srgb_color; } - return in_color; + /* Note that this is simply counteracting the hardware Linear > sRGB conversion. */ + float3 c = max(srgb_color.rgb, float3(0.0f)); + float3 c1 = c * (1.0f / 12.92f); + float3 c2 = pow((c + 0.055f) * (1.0f / 1.055f), float3(2.4f)); + float4 linear_color; + linear_color.rgb = mix(c1, c2, step(float3(0.04045f), c)); + linear_color.a = srgb_color.a; + return linear_color; +} + +/** + * Input is Rec.709 sRGB. + * Output is Rec.709 linear if hardware will add a Linear to sRGB comversion, noop otherwise. + */ +float4 blender_rec709_srgb_to_output_space(float4 srgb_color) +{ + return blender_srgb_to_framebuffer_space(srgb_color); +} + +/* Input is Blender Scene Linear. Output is Rec.709 sRGB. */ +float4 blender_scene_linear_to_rec709_srgb(float3x3 scene_linear_to_rec709, + float4 scene_linear_color) +{ + float3 rec709_linear = scene_linear_to_rec709 * scene_linear_color.rgb; + + /* TODO(fclem): For wide gamut (extended sRGB), we need to encode negative values in a certain + * way here. */ + + /* Linear to sRGB transform. */ + float3 c = max(rec709_linear, float3(0.0f)); + float3 c1 = c * 12.92f; + float3 c2 = 1.055f * pow(c, float3(1.0f / 2.4f)) - 0.055f; + float4 srgb_color; + srgb_color.rgb = mix(c1, c2, step(float3(0.0031308f), c)); + srgb_color.a = scene_linear_color.a; + return srgb_color; } diff --git a/source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl index adb9e0a02d3..3cfed05a807 100644 --- a/source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl @@ -2,14 +2,17 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "infos/gpu_shader_2D_image_rect_color_infos.hh" +#include "infos/gpu_shader_3D_image_infos.hh" -FRAGMENT_SHADER_CREATE_INFO(gpu_shader_2D_image_rect_color) +FRAGMENT_SHADER_CREATE_INFO(gpu_shader_3D_image_color_scene_linear) #include "gpu_shader_colorspace_lib.glsl" void main() { fragColor = texture(image, texCoord_interp) * color; - fragColor = blender_srgb_to_framebuffer_space(fragColor); +#ifdef BLENDER_SCENE_LINEAR_TO_REC709 + fragColor = blender_scene_linear_to_rec709_srgb(gpu_scene_linear_to_rec709, fragColor); +#endif + fragColor = blender_rec709_srgb_to_output_space(fragColor); } diff --git a/source/blender/gpu/shaders/gpu_shader_image_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_frag.glsl index 8f181c2ddbf..59008a3e0e2 100644 --- a/source/blender/gpu/shaders/gpu_shader_image_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_image_frag.glsl @@ -2,14 +2,17 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "infos/gpu_shader_2D_image_infos.hh" +#include "infos/gpu_shader_3D_image_infos.hh" -FRAGMENT_SHADER_CREATE_INFO(gpu_shader_2D_image_common) +FRAGMENT_SHADER_CREATE_INFO(gpu_shader_3D_image) #include "gpu_shader_colorspace_lib.glsl" void main() { fragColor = texture(image, texCoord_interp); - fragColor = blender_srgb_to_framebuffer_space(fragColor); +#ifdef BLENDER_SCENE_LINEAR_TO_REC709 + fragColor = blender_scene_linear_to_rec709_srgb(gpu_scene_linear_to_rec709, fragColor); +#endif + fragColor = blender_rec709_srgb_to_output_space(fragColor); } diff --git a/source/blender/gpu/shaders/infos/gpu_shader_2D_image_rect_color_infos.hh b/source/blender/gpu/shaders/infos/gpu_shader_2D_image_rect_color_infos.hh index ef9a98aa230..f73ac844239 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_2D_image_rect_color_infos.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_2D_image_rect_color_infos.hh @@ -28,6 +28,7 @@ PUSH_CONSTANT(float4, rect_geom) SAMPLER(0, sampler2D, image) VERTEX_SOURCE("gpu_shader_2D_image_rect_vert.glsl") FRAGMENT_SOURCE("gpu_shader_image_color_frag.glsl") +COMPILATION_CONSTANT(bool, is_scene_linear_image, false) ADDITIONAL_INFO(gpu_srgb_to_framebuffer_space) DO_STATIC_COMPILATION() GPU_SHADER_CREATE_END() diff --git a/source/blender/gpu/shaders/infos/gpu_shader_3D_image_infos.hh b/source/blender/gpu/shaders/infos/gpu_shader_3D_image_infos.hh index 3e48e39da9f..ea9453b92a5 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_3D_image_infos.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_3D_image_infos.hh @@ -31,12 +31,31 @@ GPU_SHADER_CREATE_END() GPU_SHADER_CREATE_INFO(gpu_shader_3D_image) ADDITIONAL_INFO(gpu_shader_3D_image_common) +COMPILATION_CONSTANT(bool, is_scene_linear_image, false) +FRAGMENT_SOURCE("gpu_shader_image_frag.glsl") +DO_STATIC_COMPILATION() +GPU_SHADER_CREATE_END() + +GPU_SHADER_CREATE_INFO(gpu_shader_3D_image_scene_linear) +ADDITIONAL_INFO(gpu_shader_3D_image_common) +ADDITIONAL_INFO(gpu_scene_linear_to_rec709_space) +COMPILATION_CONSTANT(bool, is_scene_linear_image, true) FRAGMENT_SOURCE("gpu_shader_image_frag.glsl") DO_STATIC_COMPILATION() GPU_SHADER_CREATE_END() GPU_SHADER_CREATE_INFO(gpu_shader_3D_image_color) ADDITIONAL_INFO(gpu_shader_3D_image_common) +COMPILATION_CONSTANT(bool, is_scene_linear_image, false) +PUSH_CONSTANT(float4, color) +FRAGMENT_SOURCE("gpu_shader_image_color_frag.glsl") +DO_STATIC_COMPILATION() +GPU_SHADER_CREATE_END() + +GPU_SHADER_CREATE_INFO(gpu_shader_3D_image_color_scene_linear) +ADDITIONAL_INFO(gpu_shader_3D_image_common) +ADDITIONAL_INFO(gpu_scene_linear_to_rec709_space) +COMPILATION_CONSTANT(bool, is_scene_linear_image, true) PUSH_CONSTANT(float4, color) FRAGMENT_SOURCE("gpu_shader_image_color_frag.glsl") DO_STATIC_COMPILATION() diff --git a/source/blender/gpu/shaders/infos/gpu_srgb_to_framebuffer_space_infos.hh b/source/blender/gpu/shaders/infos/gpu_srgb_to_framebuffer_space_infos.hh index 8f7177e2c58..26b77b0f74a 100644 --- a/source/blender/gpu/shaders/infos/gpu_srgb_to_framebuffer_space_infos.hh +++ b/source/blender/gpu/shaders/infos/gpu_srgb_to_framebuffer_space_infos.hh @@ -19,3 +19,8 @@ GPU_SHADER_CREATE_INFO(gpu_srgb_to_framebuffer_space) PUSH_CONSTANT(bool, srgbTarget) DEFINE("blender_srgb_to_framebuffer_space(a) a") GPU_SHADER_CREATE_END() + +GPU_SHADER_CREATE_INFO(gpu_scene_linear_to_rec709_space) +PUSH_CONSTANT(float3x3, gpu_scene_linear_to_rec709) +DEFINE("BLENDER_SCENE_LINEAR_TO_REC709") +GPU_SHADER_CREATE_END() diff --git a/source/blender/python/gpu/gpu_py_shader.cc b/source/blender/python/gpu/gpu_py_shader.cc index 62cd9d28ed2..4a1b04afe3e 100644 --- a/source/blender/python/gpu/gpu_py_shader.cc +++ b/source/blender/python/gpu/gpu_py_shader.cc @@ -42,9 +42,17 @@ "``IMAGE``\n" \ " :Attributes: vec3 pos, vec2 texCoord\n" \ " :Uniforms: sampler2D image\n" \ + "``IMAGE_SCENE_LINEAR_TO_REC709_SRGB``\n" \ + " :Attributes: vec3 pos, vec2 texCoord\n" \ + " :Uniforms: sampler2D image\n" \ + " :Note: Expect texture to be in scene linear color space\n" \ "``IMAGE_COLOR``\n" \ " :Attributes: vec3 pos, vec2 texCoord\n" \ " :Uniforms: sampler2D image, vec4 color\n" \ + "``IMAGE_COLOR_SCENE_LINEAR_TO_REC709_SRGB``\n" \ + " :Attributes: vec3 pos, vec2 texCoord\n" \ + " :Uniforms: sampler2D image, vec4 color\n" \ + " :Note: Expect texture to be in scene linear color space\n" \ "``SMOOTH_COLOR``\n" \ " :Attributes: vec3 pos, vec4 color\n" \ " :Uniforms: none\n" \ @@ -70,7 +78,10 @@ static const PyC_StringEnumItems pygpu_shader_builtin_items[] = { {GPU_SHADER_3D_FLAT_COLOR, "FLAT_COLOR"}, {GPU_SHADER_3D_IMAGE, "IMAGE"}, + {GPU_SHADER_3D_IMAGE_SCENE_LINEAR_TO_REC709_SRGB, "IMAGE_SCENE_LINEAR_TO_REC709_SRGB"}, {GPU_SHADER_3D_IMAGE_COLOR, "IMAGE_COLOR"}, + {GPU_SHADER_3D_IMAGE_COLOR_SCENE_LINEAR_TO_REC709_SRGB, + "IMAGE_COLOR_SCENE_LINEAR_TO_REC709_SRGB"}, {GPU_SHADER_3D_SMOOTH_COLOR, "SMOOTH_COLOR"}, {GPU_SHADER_3D_UNIFORM_COLOR, "UNIFORM_COLOR"}, {GPU_SHADER_3D_POLYLINE_FLAT_COLOR, "POLYLINE_FLAT_COLOR"},