Skip to content

Commit

Permalink
UPBGE: Implement color management option. (#777)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
panzergame authored Sep 2, 2018
1 parent 08b0874 commit 552bf8e
Show file tree
Hide file tree
Showing 29 changed files with 327 additions and 215 deletions.
10 changes: 10 additions & 0 deletions release/scripts/startup/bl_ui/properties_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,15 @@ def draw(self, context):
col.row().prop(gs, "frame_type", expand=True)
col.prop(gs, "frame_color", text="")

class RENDER_PT_game_color_management(RenderButtonsPanel, Panel):
bl_label = "Color Management"
COMPAT_ENGINES = {'BLENDER_GAME'}

def draw(self, context):
layout = self.layout
gs = context.scene.game_settings

layout.prop(gs, "color_management")

class RENDER_PT_game_debug(RenderButtonsPanel, Panel):
bl_label = "Debug"
Expand Down Expand Up @@ -1052,6 +1061,7 @@ def draw(self, context):
RENDER_PT_game_system,
RENDER_PT_game_animations,
RENDER_PT_game_display,
RENDER_PT_game_color_management,
RENDER_PT_game_debug,
SCENE_PT_game_physics,
SCENE_PT_game_physics_obstacles,
Expand Down
2 changes: 1 addition & 1 deletion release/scripts/startup/bl_ui/properties_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def draw(self, context):
class SCENE_PT_color_management(SceneButtonsPanel, Panel):
bl_label = "Color Management"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
COMPAT_ENGINES = {'BLENDER_RENDER'}

def draw(self, context):
layout = self.layout
Expand Down
6 changes: 6 additions & 0 deletions source/blender/blenkernel/intern/scene.c
Original file line number Diff line number Diff line change
Expand Up @@ -2333,6 +2333,12 @@ void BKE_scene_disable_color_management(Scene *scene)

bool BKE_scene_check_color_management_enabled(const Scene *scene)
{
#ifdef WITH_GAMEENGINE
if (BKE_scene_uses_blender_game(scene)) {
return (scene->gm.colorManagement == GAME_COLOR_MANAGEMENT_SRGB);
}
#endif

return !STREQ(scene->display_settings.display_device, "None");
}

Expand Down
6 changes: 6 additions & 0 deletions source/blender/blenloader/intern/versioning_upbge.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,5 +309,11 @@ void blo_do_versions_upbge(FileData *fd, Library *lib, Main *main)
}
}
}

if (!DNA_struct_elem_find(fd->filesdna, "GameData", "short", "colorManagement")) {
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
scene->gm.colorManagement = GAME_COLOR_MANAGEMENT_SRGB;
}
}
}
}
2 changes: 1 addition & 1 deletion source/blender/editors/space_view3d/view3d_draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -3104,7 +3104,7 @@ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
{
if (scene->world && (v3d->flag2 & V3D_SHOW_WORLD)) {
RegionView3D *rv3d = ar->regiondata;
GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
GPUMaterial *gpumat = GPU_material_world(scene, scene->world, 0);

/* calculate full shader for background */
GPU_material_bind(gpumat, 1, 1.0, true, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
Expand Down
12 changes: 9 additions & 3 deletions source/blender/gpu/GPU_material.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ typedef enum GPUBlendMode {
GPU_BLEND_ALPHA_TO_COVERAGE = 16
} GPUBlendMode;

typedef enum GPUMaterialFlag {
GPU_MATERIAL_OPENSUBDIV = (1 << 0),
GPU_MATERIAL_INSTANCING = (1 << 1),
GPU_MATERIAL_NO_COLOR_MANAGEMENT = (1 << 2)
} GPUMaterialFlag;

typedef struct GPUNodeStack {
GPUType type;
const char *name;
Expand Down Expand Up @@ -262,10 +268,10 @@ GPUBuiltin GPU_get_material_builtins(GPUMaterial *material);
GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, const float obcol[4]);

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

GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, bool use_opensubdiv, bool is_instancing);
GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma, bool use_opensubdiv);
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, GPUMaterialFlag flags);
GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma, GPUMaterialFlag flags);
void GPU_material_free(struct ListBase *gpumaterial);

void GPU_materials_free(struct Main *bmain);
Expand Down
15 changes: 9 additions & 6 deletions source/blender/gpu/GPU_shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,15 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_BLACK = 6,
GPU_SHADER_BLACK_INSTANCING = 7,
GPU_SHADER_DRAW_FRAME_BUFFER = 8,
GPU_SHADER_STEREO_STIPPLE = 9,
GPU_SHADER_STEREO_ANAGLYPH = 10,
GPU_SHADER_FRUSTUM_LINE = 11,
GPU_SHADER_FRUSTUM_SOLID = 12,
GPU_SHADER_FLAT_COLOR = 13,
GPU_SHADER_2D_BOX = 14,
GPU_SHADER_DRAW_FRAME_BUFFER_SRGB = 9,
GPU_SHADER_STEREO_STIPPLE = 10,
GPU_SHADER_STEREO_STIPPLE_SRGB = 11,
GPU_SHADER_STEREO_ANAGLYPH = 12,
GPU_SHADER_STEREO_ANAGLYPH_SRGB = 13,
GPU_SHADER_FRUSTUM_LINE = 14,
GPU_SHADER_FRUSTUM_SOLID = 15,
GPU_SHADER_FLAT_COLOR = 16,
GPU_SHADER_2D_BOX = 17,
} GPUBuiltinShader;

GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader);
Expand Down
12 changes: 6 additions & 6 deletions source/blender/gpu/intern/gpu_draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1687,7 +1687,7 @@ void GPU_begin_object_materials(
/* viewport material, setup in space_view3d, defaults to matcap using ma->preview now */
if (use_matcap) {
GMS.gmatbuf[0] = v3d->defmaterial;
GPU_material_matcap(scene, v3d->defmaterial, use_opensubdiv);
GPU_material_matcap(scene, v3d->defmaterial, use_opensubdiv ? GPU_MATERIAL_OPENSUBDIV : 0);

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

if (glsl) {
GMS.gmatbuf[0] = &defmaterial;
GPU_material_from_blender(GMS.gscene, &defmaterial, GMS.is_opensubdiv, false);
GPU_material_from_blender(GMS.gscene, &defmaterial, GMS.is_opensubdiv ? GPU_MATERIAL_OPENSUBDIV : 0);
}

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

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

if (gpumat) {
/* do glsl only if creating it succeed, else fallback */
Expand Down Expand Up @@ -1835,7 +1835,7 @@ int GPU_object_material_bind(int nr, void *attribs)
/* unbind glsl material */
if (GMS.gboundmat) {
if (GMS.is_alpha_pass) glDepthMask(0);
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv, false));
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv ? GPU_MATERIAL_OPENSUBDIV : 0));
GMS.gboundmat = NULL;
}

Expand Down Expand Up @@ -1863,7 +1863,7 @@ int GPU_object_material_bind(int nr, void *attribs)

float auto_bump_scale;

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

if (GMS.dob) {
Expand Down Expand Up @@ -1968,7 +1968,7 @@ void GPU_object_material_unbind(void)
glDisable(GL_CULL_FACE);

if (GMS.is_alpha_pass) glDepthMask(0);
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv, false));
GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv ? GPU_MATERIAL_OPENSUBDIV : 0));
GMS.gboundmat = NULL;
}
else
Expand Down
4 changes: 2 additions & 2 deletions source/blender/gpu/intern/gpu_framebuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,11 +610,11 @@ GPURenderBuffer *GPU_renderbuffer_create(int width, int height, int samples, GPU
rb->depth = true;
}
else {
GLenum internalformat = GL_RGBA8;
GLenum internalformat = GL_RGBA12;
switch (hdrtype) {
case GPU_HDR_NONE:
{
internalformat = GL_RGBA8;
internalformat = GL_RGBA12;
break;
}
/* the following formats rely on ARB_texture_float or OpenGL 3.0 */
Expand Down
Loading

0 comments on commit 552bf8e

Please sign in to comment.