Skip to content

Commit 552bf8e

Browse files
authored
UPBGE: Implement color management option. (#777)
Previously the color management was always of sRGB and the user had no control over it. To fill this gap the user should have the ability to define the final color space, linear or sRGB. First of all an option named "Color Management" in a new tab under Render panel is added, it can be "Linear" or "sRGB", the default is "sRGB", When game engine is selected changing this option will force the recompilation of all shaders and they will add or remove color space conversion at the end of the shader. In game the color space is not managed at the shader level, but at the final copy of the offscreen to the screen. Firstly the material in game must disable the color management, this is done by a new set of flags passed to GPU_material_from_blender or GPU_material_world and the flag GPU_MATERIAL_NO_COLOR_MANAGEMENT. Secondly the three shaders used to copy the offscreen to screen (normal, stipple stereo, anaglyph stereo) now have a sRGB version including a call to linearrgb_to_srgb enabled by the macro COLOR_MANAGEMENT. The color space used is stored in the rasterizer in enum variable m_colorManagement for linear and sRGB, this variable is used to select the correct shader to bind before flushing to screen. Because the linear to sRGB conversion is not anymore using a float value with the highest precision at the output of the fragment shader, the texture format GL_RGBA8 is introducing bands because of its poor resolution. Replacing it by GL_RGBA12 prevents the bands. In the same time the color management used in KX_FontObject or KX_WorldInfo is now obsolete and removed, also KX_WorldInfo is getting GPUMaterial only in new function ReloadMaterial called by the FinalizeSceneData such as material shaders and by setMaterialGLSL.
1 parent 08b0874 commit 552bf8e

29 files changed

+327
-215
lines changed

release/scripts/startup/bl_ui/properties_game.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,15 @@ def draw(self, context):
491491
col.row().prop(gs, "frame_type", expand=True)
492492
col.prop(gs, "frame_color", text="")
493493

494+
class RENDER_PT_game_color_management(RenderButtonsPanel, Panel):
495+
bl_label = "Color Management"
496+
COMPAT_ENGINES = {'BLENDER_GAME'}
497+
498+
def draw(self, context):
499+
layout = self.layout
500+
gs = context.scene.game_settings
501+
502+
layout.prop(gs, "color_management")
494503

495504
class RENDER_PT_game_debug(RenderButtonsPanel, Panel):
496505
bl_label = "Debug"
@@ -1052,6 +1061,7 @@ def draw(self, context):
10521061
RENDER_PT_game_system,
10531062
RENDER_PT_game_animations,
10541063
RENDER_PT_game_display,
1064+
RENDER_PT_game_color_management,
10551065
RENDER_PT_game_debug,
10561066
SCENE_PT_game_physics,
10571067
SCENE_PT_game_physics_obstacles,

release/scripts/startup/bl_ui/properties_scene.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ def draw(self, context):
257257
class SCENE_PT_color_management(SceneButtonsPanel, Panel):
258258
bl_label = "Color Management"
259259
bl_options = {'DEFAULT_CLOSED'}
260-
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
260+
COMPAT_ENGINES = {'BLENDER_RENDER'}
261261

262262
def draw(self, context):
263263
layout = self.layout

source/blender/blenkernel/intern/scene.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,6 +2333,12 @@ void BKE_scene_disable_color_management(Scene *scene)
23332333

23342334
bool BKE_scene_check_color_management_enabled(const Scene *scene)
23352335
{
2336+
#ifdef WITH_GAMEENGINE
2337+
if (BKE_scene_uses_blender_game(scene)) {
2338+
return (scene->gm.colorManagement == GAME_COLOR_MANAGEMENT_SRGB);
2339+
}
2340+
#endif
2341+
23362342
return !STREQ(scene->display_settings.display_device, "None");
23372343
}
23382344

source/blender/blenloader/intern/versioning_upbge.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,5 +309,11 @@ void blo_do_versions_upbge(FileData *fd, Library *lib, Main *main)
309309
}
310310
}
311311
}
312+
313+
if (!DNA_struct_elem_find(fd->filesdna, "GameData", "short", "colorManagement")) {
314+
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
315+
scene->gm.colorManagement = GAME_COLOR_MANAGEMENT_SRGB;
316+
}
317+
}
312318
}
313319
}

source/blender/editors/space_view3d/view3d_draw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3104,7 +3104,7 @@ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
31043104
{
31053105
if (scene->world && (v3d->flag2 & V3D_SHOW_WORLD)) {
31063106
RegionView3D *rv3d = ar->regiondata;
3107-
GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
3107+
GPUMaterial *gpumat = GPU_material_world(scene, scene->world, 0);
31083108

31093109
/* calculate full shader for background */
31103110
GPU_material_bind(gpumat, 1, 1.0, true, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));

source/blender/gpu/GPU_material.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ typedef enum GPUBlendMode {
132132
GPU_BLEND_ALPHA_TO_COVERAGE = 16
133133
} GPUBlendMode;
134134

135+
typedef enum GPUMaterialFlag {
136+
GPU_MATERIAL_OPENSUBDIV = (1 << 0),
137+
GPU_MATERIAL_INSTANCING = (1 << 1),
138+
GPU_MATERIAL_NO_COLOR_MANAGEMENT = (1 << 2)
139+
} GPUMaterialFlag;
140+
135141
typedef struct GPUNodeStack {
136142
GPUType type;
137143
const char *name;
@@ -262,10 +268,10 @@ GPUBuiltin GPU_get_material_builtins(GPUMaterial *material);
262268
GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, const float obcol[4]);
263269

264270
/* High level functions to create and use GPU materials */
265-
GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo);
271+
GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo, GPUMaterialFlag flags);
266272

267-
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, bool use_opensubdiv, bool is_instancing);
268-
GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma, bool use_opensubdiv);
273+
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, GPUMaterialFlag flags);
274+
GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma, GPUMaterialFlag flags);
269275
void GPU_material_free(struct ListBase *gpumaterial);
270276

271277
void GPU_materials_free(struct Main *bmain);

source/blender/gpu/GPU_shader.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,15 @@ typedef enum GPUBuiltinShader {
112112
GPU_SHADER_BLACK = 6,
113113
GPU_SHADER_BLACK_INSTANCING = 7,
114114
GPU_SHADER_DRAW_FRAME_BUFFER = 8,
115-
GPU_SHADER_STEREO_STIPPLE = 9,
116-
GPU_SHADER_STEREO_ANAGLYPH = 10,
117-
GPU_SHADER_FRUSTUM_LINE = 11,
118-
GPU_SHADER_FRUSTUM_SOLID = 12,
119-
GPU_SHADER_FLAT_COLOR = 13,
120-
GPU_SHADER_2D_BOX = 14,
115+
GPU_SHADER_DRAW_FRAME_BUFFER_SRGB = 9,
116+
GPU_SHADER_STEREO_STIPPLE = 10,
117+
GPU_SHADER_STEREO_STIPPLE_SRGB = 11,
118+
GPU_SHADER_STEREO_ANAGLYPH = 12,
119+
GPU_SHADER_STEREO_ANAGLYPH_SRGB = 13,
120+
GPU_SHADER_FRUSTUM_LINE = 14,
121+
GPU_SHADER_FRUSTUM_SOLID = 15,
122+
GPU_SHADER_FLAT_COLOR = 16,
123+
GPU_SHADER_2D_BOX = 17,
121124
} GPUBuiltinShader;
122125

123126
GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader);

source/blender/gpu/intern/gpu_draw.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,7 +1687,7 @@ void GPU_begin_object_materials(
16871687
/* viewport material, setup in space_view3d, defaults to matcap using ma->preview now */
16881688
if (use_matcap) {
16891689
GMS.gmatbuf[0] = v3d->defmaterial;
1690-
GPU_material_matcap(scene, v3d->defmaterial, use_opensubdiv);
1690+
GPU_material_matcap(scene, v3d->defmaterial, use_opensubdiv ? GPU_MATERIAL_OPENSUBDIV : 0);
16911691

16921692
/* do material 1 too, for displists! */
16931693
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
@@ -1705,7 +1705,7 @@ void GPU_begin_object_materials(
17051705

17061706
if (glsl) {
17071707
GMS.gmatbuf[0] = &defmaterial;
1708-
GPU_material_from_blender(GMS.gscene, &defmaterial, GMS.is_opensubdiv, false);
1708+
GPU_material_from_blender(GMS.gscene, &defmaterial, GMS.is_opensubdiv ? GPU_MATERIAL_OPENSUBDIV : 0);
17091709
}
17101710

17111711
GMS.alphablend[0] = GPU_BLEND_SOLID;
@@ -1719,7 +1719,7 @@ void GPU_begin_object_materials(
17191719
if (ma == NULL) ma = &defmaterial;
17201720

17211721
/* create glsl material if requested */
1722-
gpumat = glsl ? GPU_material_from_blender(GMS.gscene, ma, GMS.is_opensubdiv, false) : NULL;
1722+
gpumat = glsl ? GPU_material_from_blender(GMS.gscene, ma, GMS.is_opensubdiv ? GPU_MATERIAL_OPENSUBDIV : 0) : NULL;
17231723

17241724
if (gpumat) {
17251725
/* do glsl only if creating it succeed, else fallback */
@@ -1835,7 +1835,7 @@ int GPU_object_material_bind(int nr, void *attribs)
18351835
/* unbind glsl material */
18361836
if (GMS.gboundmat) {
18371837
if (GMS.is_alpha_pass) glDepthMask(0);
1838-
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv, false));
1838+
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv ? GPU_MATERIAL_OPENSUBDIV : 0));
18391839
GMS.gboundmat = NULL;
18401840
}
18411841

@@ -1863,7 +1863,7 @@ int GPU_object_material_bind(int nr, void *attribs)
18631863

18641864
float auto_bump_scale;
18651865

1866-
GPUMaterial *gpumat = GPU_material_from_blender(GMS.gscene, mat, GMS.is_opensubdiv, false);
1866+
GPUMaterial *gpumat = GPU_material_from_blender(GMS.gscene, mat, GMS.is_opensubdiv ? GPU_MATERIAL_OPENSUBDIV : 0);
18671867
GPU_material_vertex_attributes(gpumat, gattribs);
18681868

18691869
if (GMS.dob) {
@@ -1968,7 +1968,7 @@ void GPU_object_material_unbind(void)
19681968
glDisable(GL_CULL_FACE);
19691969

19701970
if (GMS.is_alpha_pass) glDepthMask(0);
1971-
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv, false));
1971+
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv ? GPU_MATERIAL_OPENSUBDIV : 0));
19721972
GMS.gboundmat = NULL;
19731973
}
19741974
else

source/blender/gpu/intern/gpu_framebuffer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -610,11 +610,11 @@ GPURenderBuffer *GPU_renderbuffer_create(int width, int height, int samples, GPU
610610
rb->depth = true;
611611
}
612612
else {
613-
GLenum internalformat = GL_RGBA8;
613+
GLenum internalformat = GL_RGBA12;
614614
switch (hdrtype) {
615615
case GPU_HDR_NONE:
616616
{
617-
internalformat = GL_RGBA8;
617+
internalformat = GL_RGBA12;
618618
break;
619619
}
620620
/* the following formats rely on ARB_texture_float or OpenGL 3.0 */

0 commit comments

Comments
 (0)