From 0a6d0ebecc9d0912caa4a2f24898f0a9af50a782 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Mon, 28 Dec 2015 02:55:44 +0100 Subject: [PATCH 1/4] Provide an API for render engines to get a color conversion matrix from CIE XYZ to the scene linear role --- intern/opencolorio/ocio_capi.h | 1 + release/datafiles/colormanagement/config.ocio | 25 +++++++++++ source/blender/imbuf/IMB_colormanagement.h | 5 +++ source/blender/imbuf/intern/colormanagement.c | 52 ++++++++++++++++++++++ source/blender/makesrna/intern/rna_render.c | 4 ++ source/blender/render/extern/include/RE_engine.h | 1 + .../blender/render/intern/source/external_engine.c | 7 +++ 7 files changed, 95 insertions(+) diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h index 52a8672..dea4b5f 100644 --- a/intern/opencolorio/ocio_capi.h +++ b/intern/opencolorio/ocio_capi.h @@ -37,6 +37,7 @@ struct OCIO_GLSLDrawState; #define OCIO_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name #define OCIO_ROLE_SCENE_LINEAR "scene_linear" +#define OCIO_ROLE_XYZ_LINEAR "chromaticity" #define OCIO_ROLE_COLOR_PICKING "color_picking" #define OCIO_ROLE_TEXTURE_PAINT "texture_paint" #define OCIO_ROLE_DEFAULT_BYTE "default_byte" diff --git a/release/datafiles/colormanagement/config.ocio b/release/datafiles/colormanagement/config.ocio index 1cf9a3b..3650441 100644 --- a/release/datafiles/colormanagement/config.ocio +++ b/release/datafiles/colormanagement/config.ocio @@ -29,6 +29,8 @@ roles: color_picking: Raw texture_paint: Raw + chromaticity: D65-709_XYZ + displays: sRGB: - ! {name: Default, colorspace: sRGB} @@ -284,6 +286,29 @@ colorspaces: - ! {src: Linear, dst: lg10} - ! {src: colorworks_filmlg_to_p3.3dl, interpolation: linear} + - ! + name: D65-709_XYZ + family: + equalitygroup: + bitdepth: 32f + description: | + D65 adapted REC.709 to XYZ base transform + isdata: false + allocation: lg2 + allocationvars: [-8, 5, 0.00390625] + from_reference: ! {matrix: [0.4124564, 0.3575761, 0.1804375, 0, 0.2126729, 0.7151522, 0.0721750, 0, 0.0193339, 0.1191920, 0.9503041, 0, 0, 0, 0, 1]} + + - ! + name: Linear BGR + family: + equalitygroup: + bitdepth: 32f + description: | + Reverses the R and B channels of the reference space, useful for testing since missed transforms are obvious + isdata: false + from_reference: ! {matrix: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]} + + looks: - ! name: Agfa Agfacolor Futura 100 diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h index 59df833..bd4e8ae 100644 --- a/source/blender/imbuf/IMB_colormanagement.h +++ b/source/blender/imbuf/IMB_colormanagement.h @@ -77,6 +77,9 @@ void IMB_colormanagement_transform_threaded(float *buffer, int width, int height const char *from_colorspace, const char *to_colorspace, bool predivide); void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspace, const char *to_colorspace); +void IMB_colormanagement_role_to_scene_linear_v3(float pixel[3], const char *name); +void IMB_colormanagement_scene_linear_to_role_v3(float pixel[3], const char *name); + void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], struct ColorSpace *colorspace); void IMB_colormanagement_colorspace_to_scene_linear_v4(float pixel[4], bool predivide, struct ColorSpace *colorspace); @@ -106,6 +109,8 @@ void IMB_colormanagement_buffer_make_display_space(float *buffer, unsigned char const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings); +void IMB_colormanagement_xyz_to_scene_linear_m3(float matrix[3][3]); + /* ** Public display buffers interfaces ** */ void IMB_colormanagement_display_settings_from_ctx(const struct bContext *C, diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 5a3d9b4..2ad6a28 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -74,6 +74,7 @@ /* ** list of all supported color spaces, displays and views */ static char global_role_scene_linear[MAX_COLORSPACE_NAME]; +static char global_role_xyz_linear[MAX_COLORSPACE_NAME]; static char global_role_color_picking[MAX_COLORSPACE_NAME]; static char global_role_texture_painting[MAX_COLORSPACE_NAME]; static char global_role_default_byte[MAX_COLORSPACE_NAME]; @@ -475,6 +476,7 @@ static void colormanage_load_config(OCIO_ConstConfigRcPtr *config) /* get roles */ colormanage_role_color_space_name_get(config, global_role_scene_linear, OCIO_ROLE_SCENE_LINEAR, NULL); + colormanage_role_color_space_name_get(config, global_role_xyz_linear, OCIO_ROLE_XYZ_LINEAR, NULL); colormanage_role_color_space_name_get(config, global_role_color_picking, OCIO_ROLE_COLOR_PICKING, NULL); colormanage_role_color_space_name_get(config, global_role_texture_painting, OCIO_ROLE_TEXTURE_PAINT, NULL); colormanage_role_color_space_name_get(config, global_role_default_sequencer, OCIO_ROLE_DEFAULT_SEQUENCER, OCIO_ROLE_SCENE_LINEAR); @@ -1718,6 +1720,30 @@ void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspac IMB_colormanagement_processor_free(cm_processor); } +/* convert pixel from specified color space to scene linear */ + +void IMB_colormanagement_role_to_scene_linear_v3(float pixel[3], const char *name) +{ + OCIO_ConstProcessorRcPtr *processor; + + processor = create_colorspace_transform_processor(name, global_role_scene_linear); + + if (processor) + OCIO_processorApplyRGB(processor, pixel); +} + +/* same as above, but opposite direction */ + +void IMB_colormanagement_scene_linear_to_role_v3(float pixel[3], const char *name) +{ + OCIO_ConstProcessorRcPtr *processor; + + processor = create_colorspace_transform_processor(global_role_scene_linear, name); + + if (processor) + OCIO_processorApplyRGB(processor, pixel); +} + /* convert pixel from specified by descriptor color space to scene linear * used by performance-critical areas such as renderer and baker */ @@ -1870,6 +1896,32 @@ void IMB_colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManage colormanagement_imbuf_make_display_space(ibuf, view_settings, display_settings, false); } +void IMB_colormanagement_xyz_to_scene_linear_m3(float matrix[3][3]) +{ + if (global_role_xyz_linear[0]) + { + /* we assume that both spaces are linear and so that the transformation + * must always be a 3x3 matrix which we can extract by converting + * the (1, 0, 0), (0, 1, 0), (0, 0, 1) basis vectors */ + ColormanageProcessor *cm_processor; + cm_processor = IMB_colormanagement_colorspace_processor_new(global_role_xyz_linear, global_role_scene_linear); + + unit_m3(matrix); + IMB_colormanagement_processor_apply_v3(cm_processor, matrix[0]); + IMB_colormanagement_processor_apply_v3(cm_processor, matrix[1]); + IMB_colormanagement_processor_apply_v3(cm_processor, matrix[2]); + + IMB_colormanagement_processor_free(cm_processor); + } + else + { + /* default XYZ to Rec.709 if the configuration contains no XYZ role */ + matrix[0][0] = 3.240479f; matrix[1][0] = -1.537150f; matrix[2][0] = -0.498535f; + matrix[0][1] = -0.969256f; matrix[1][1] = 1.875991f; matrix[2][1] = 0.041556f; + matrix[0][2] = 0.055648f; matrix[1][2] = -0.204043f; matrix[2][2] = 1.057311f; + } +} + /* prepare image buffer to be saved on disk, applying color management if needed * color management would be applied if image is saving as render result and if * file format is not expecting float buffer to be in linear space (currently diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index dd07f3c..d1852e4 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -520,6 +520,10 @@ static void rna_def_render_engine(BlenderRNA *brna) prop = RNA_def_float_matrix(func, "r_model_matrix", 4, 4, NULL, 0.0f, 0.0f, "Model Matrix", "Normalized camera model matrix", 0.0f, 0.0f); RNA_def_property_flag(prop, PROP_REQUIRED); + func = RNA_def_function(srna, "xyz_to_scene_linear_matrix", "RE_engine_get_xyz_to_scene_linear_matrix"); + prop = RNA_def_float_matrix(func, "matrix", 3, 3, NULL, 0.0f, 0.0f, "Matrix", "CIE XYZ to scene linear color space matrix, depending on the OpenColorIO configuration", 0.0f, 0.0f); + RNA_def_property_flag(prop, PROP_REQUIRED); + func = RNA_def_function(srna, "update_stats", "RE_engine_update_stats"); RNA_def_function_ui_description(func, "Update and signal to redraw render status text"); prop = RNA_def_string(func, "stats", NULL, 0, "Stats", ""); diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 4e48060..12003d0 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -143,6 +143,7 @@ void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result, int void RE_engine_active_view_set(RenderEngine *engine, const char *viewname); float RE_engine_get_camera_shift_x(RenderEngine *engine, struct Object *camera); void RE_engine_get_camera_model_matrix(RenderEngine *engine, struct Object *camera, float *r_modelmat); +void RE_engine_get_xyz_to_scene_linear_matrix(RenderEngine *engine, float *r_matrix); int RE_engine_test_break(RenderEngine *engine); void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info); diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 8adac7c..ef1ff7e 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -53,6 +53,8 @@ #include "BPY_extern.h" #endif +#include "IMB_colormanagement.h" + #include "RE_engine.h" #include "RE_pipeline.h" #include "RE_bake.h" @@ -389,6 +391,11 @@ void RE_engine_get_camera_model_matrix(RenderEngine *engine, Object *camera, flo BKE_camera_multiview_model_matrix(re ? &re->r : NULL, camera, re->viewname, (float (*)[4])r_modelmat); } +void RE_engine_get_xyz_to_scene_linear_matrix(RenderEngine *UNUSED(engine), float *r_matrix) +{ + IMB_colormanagement_xyz_to_scene_linear_m3((float (*)[3])r_matrix); +} + rcti* RE_engine_get_current_tiles(Render *re, int *r_total_tiles, bool *r_needs_free) { static rcti tiles_static[BLENDER_MAX_THREADS]; -- 1.9.1