[Bf-blender-cvs] [a0283355fcf] draw-colormanagement: OpenColorIO: Improve/Cleanup Implementation
Clément Foucault
noreply at git.blender.org
Wed Jan 22 19:39:38 CET 2020
Commit: a0283355fcf4d0064224a13140e08c2ab880213a
Author: Clément Foucault
Date: Wed Jan 22 14:55:38 2020 +0100
Branches: draw-colormanagement
https://developer.blender.org/rBa0283355fcf4d0064224a13140e08c2ab880213a
OpenColorIO: Improve/Cleanup Implementation
This split the shader cache into caches for Shader, Lut and CurveMapping.
This way we can have smoother updates when tweaking/animating the color
managment (i.e. exposure and gamma should only recompile the shader).
The curvemapping, predivide and dither options are no longer compile time
optimized but use uniforms. I did not measure any performance difference.
===================================================================
M intern/opencolorio/gpu_shader_display_transform.glsl
M intern/opencolorio/ocio_impl_glsl.cc
===================================================================
diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl
index 9787398e2ae..bc8f5006dda 100644
--- a/intern/opencolorio/gpu_shader_display_transform.glsl
+++ b/intern/opencolorio/gpu_shader_display_transform.glsl
@@ -1,70 +1,65 @@
+/* Blender OpenColorIO implementation */
+
+uniform sampler1D curve_mapping_texture;
uniform sampler2D image_texture;
uniform sampler3D lut3d_texture;
-#ifdef USE_DITHER
uniform float dither;
-#endif
-
-in vec2 texCoord_interp;
-out vec4 fragColor;
+uniform bool predivide;
+uniform bool curve_mapping;
-#ifdef USE_CURVE_MAPPING
-/* Curve mapping parameters
- *
- * See documentation for OCIO_CurveMappingSettings to get fields descriptions.
- * (this ones pretyt much copies stuff from C structure.)
- */
-uniform sampler1D curve_mapping_texture;
-uniform int curve_mapping_lut_size;
-uniform int use_curve_mapping_extend_extrapolate;
-uniform vec4 curve_mapping_mintable;
-uniform vec4 curve_mapping_range;
-uniform vec4 curve_mapping_ext_in_x;
-uniform vec4 curve_mapping_ext_in_y;
-uniform vec4 curve_mapping_ext_out_x;
-uniform vec4 curve_mapping_ext_out_y;
-uniform vec4 curve_mapping_first_x;
-uniform vec4 curve_mapping_first_y;
-uniform vec4 curve_mapping_last_x;
-uniform vec4 curve_mapping_last_y;
-uniform vec3 curve_mapping_black;
-uniform vec3 curve_mapping_bwmul;
+layout(std140) uniform OCIO_GLSLCurveMappingParameters
+{
+ /* Curve mapping parameters
+ *
+ * See documentation for OCIO_CurveMappingSettings to get fields descriptions.
+ * (this ones pretty much copies stuff from C structure.)
+ */
+ vec4 curve_mapping_mintable;
+ vec4 curve_mapping_range;
+ vec4 curve_mapping_ext_in_x;
+ vec4 curve_mapping_ext_in_y;
+ vec4 curve_mapping_ext_out_x;
+ vec4 curve_mapping_ext_out_y;
+ vec4 curve_mapping_first_x;
+ vec4 curve_mapping_first_y;
+ vec4 curve_mapping_last_x;
+ vec4 curve_mapping_last_y;
+ vec4 curve_mapping_black;
+ vec4 curve_mapping_bwmul;
+ int curve_mapping_lut_size;
+ int curve_mapping_use_extend_extrapolate;
+};
float read_curve_mapping(int table, int index)
{
- /* TODO(sergey): Without -1 here image is getting darken after applying unite curve.
- * But is it actually correct to subtract 1 here?
- */
- float texture_index = float(index) / float(curve_mapping_lut_size - 1);
- return texture(curve_mapping_texture, texture_index)[table];
+ return texelFetch(curve_mapping_texture, index, 0)[table];
}
float curvemap_calc_extend(int table, float x, vec2 first, vec2 last)
{
if (x <= first[0]) {
- if (use_curve_mapping_extend_extrapolate == 0) {
+ if (curve_mapping_use_extend_extrapolate == 0) {
/* horizontal extrapolation */
return first[1];
}
else {
- if (curve_mapping_ext_in_x[table] == 0.0)
- return first[1] + curve_mapping_ext_in_y[table] * 10000.0;
- else
- return first[1] +
- curve_mapping_ext_in_y[table] * (x - first[0]) / curve_mapping_ext_in_x[table];
+ float fac = (curve_mapping_ext_in_x[table] != 0.0) ?
+ ((x - first[0]) / curve_mapping_ext_in_x[table]) :
+ 10000.0;
+ return first[1] + curve_mapping_ext_in_y[table] * fac;
}
}
else if (x >= last[0]) {
- if (use_curve_mapping_extend_extrapolate == 0) {
+ if (curve_mapping_use_extend_extrapolate == 0) {
/* horizontal extrapolation */
return last[1];
}
else {
- if (curve_mapping_ext_out_x[table] == 0.0)
- return last[1] - curve_mapping_ext_out_y[table] * 10000.0;
- else
- return last[1] +
- curve_mapping_ext_out_y[table] * (x - last[0]) / curve_mapping_ext_out_x[table];
+ float fac = (curve_mapping_ext_out_x[table] != 0.0) ?
+ ((x - last[0]) / curve_mapping_ext_out_x[table]) :
+ -10000.0;
+ return last[1] + curve_mapping_ext_out_y[table] * fac;
}
}
return 0.0;
@@ -92,80 +87,91 @@ float curvemap_evaluateF(int table, float value)
vec2(curve_mapping_last_x[table], curve_mapping_last_y[table]));
}
else {
- if (i < 0)
+ if (i < 0) {
return read_curve_mapping(table, 0);
- if (i >= CM_TABLE)
+ }
+ if (i >= CM_TABLE) {
return read_curve_mapping(table, CM_TABLE);
-
+ }
fi = fi - float(i);
- return (1.0 - fi) * read_curve_mapping(table, i) + fi * read_curve_mapping(table, i + 1);
+ float cm1 = read_curve_mapping(table, i);
+ float cm2 = read_curve_mapping(table, i + 1);
+ return mix(cm1, cm2, fi);
}
}
vec4 curvemapping_evaluate_premulRGBF(vec4 col)
{
- vec4 result = col;
- result[0] = curvemap_evaluateF(0, (col[0] - curve_mapping_black[0]) * curve_mapping_bwmul[0]);
- result[1] = curvemap_evaluateF(1, (col[1] - curve_mapping_black[1]) * curve_mapping_bwmul[1]);
- result[2] = curvemap_evaluateF(2, (col[2] - curve_mapping_black[2]) * curve_mapping_bwmul[2]);
- result[3] = col[3];
+ col.rgb = (col.rgb - curve_mapping_black.rgb) * curve_mapping_bwmul.rgb;
+
+ vec4 result;
+ result.r = curvemap_evaluateF(0, col.r);
+ result.g = curvemap_evaluateF(1, col.g);
+ result.b = curvemap_evaluateF(2, col.b);
+ result.a = col.a;
return result;
}
-#endif
-#ifdef USE_DITHER
float dither_random_value(vec2 co)
{
return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453) * 0.005 * dither;
}
-vec2 round_to_pixel(vec2 st)
+vec2 round_to_pixel(sampler2D tex, vec2 uv)
{
- vec2 result;
- vec2 size = textureSize(image_texture, 0);
- result.x = float(int(st.x * size.x)) / size.x;
- result.y = float(int(st.y * size.y)) / size.y;
- return result;
+ vec2 size = textureSize(tex, 0);
+ return vec2(ivec2(uv * size)) / size;
}
-vec4 apply_dither(vec2 st, vec4 col)
+vec4 apply_dither(vec4 col, vec2 uv)
{
- vec4 result;
- float random_value = dither_random_value(round_to_pixel(st));
- result.r = col.r + random_value;
- result.g = col.g + random_value;
- result.b = col.b + random_value;
- result.a = col.a;
- return result;
+ col.rgb += dither_random_value(uv);
+ return col;
}
-#endif
-void main()
+vec4 OCIO_ProcessColor(vec4 col, vec2 noise_uv)
{
- vec4 col = texture(image_texture, texCoord_interp.st);
-#ifdef USE_CURVE_MAPPING
- col = curvemapping_evaluate_premulRGBF(col);
-#endif
+ if (curve_mapping) {
+ col = curvemapping_evaluate_premulRGBF(col);
+ }
-#ifdef USE_PREDIVIDE
- if (col[3] > 0.0 && col[3] < 1.0) {
- float inv_alpha = 1.0 / col[3];
- col[0] *= inv_alpha;
- col[1] *= inv_alpha;
- col[2] *= inv_alpha;
+ if (predivide) {
+ if (col.a > 0.0 && col.a < 1.0) {
+ col.rgb *= 1.0 / col.a;
+ }
}
-#endif
/* NOTE: This is true we only do de-premul here and NO premul
* and the reason is simple -- opengl is always configured
* for straight alpha at this moment
*/
- vec4 result = OCIODisplay(col, lut3d_texture);
+ col = OCIODisplay(col, lut3d_texture);
-#ifdef USE_DITHER
- result = apply_dither(texCoord_interp.st, result);
-#endif
+ if (dither > 0.0) {
+ col = apply_dither(col, noise_uv);
+ }
+
+ return col;
+}
+
+/* ------------------------------------------------------------------------ */
+
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+/* Standard Implementation. */
+void main()
+{
+ vec4 col = texture(image_texture, texCoord_interp.st);
+ vec2 noise_uv = round_to_pixel(image_texture, texCoord_interp.st);
- fragColor = result;
+ fragColor = OCIO_ProcessColor(col, noise_uv);
}
+
+#if 0 /* In-place transformation. No extra buffer required. */
+void main()
+{
+ /* TODO(fclem) use imageLoad/Store to do in-place color-management. */
+}
+#endif
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index a80e29a2dec..45bb4ae27a7 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -56,62 +56,107 @@ using namespace OCIO_NAMESPACE;
#include "ocio_impl.h"
static const int LUT3D_EDGE_SIZE = 64;
+static const int LUT3D_TEXTURE_SIZE = sizeof(float) * 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE *
+ LUT3D_EDGE_SIZE;
static const int SHADER_CACHE_SIZE = 4;
+#define UBO_BIND_LOC 0
+
extern "C" char datatoc_gpu_shader_display_transform_glsl[];
extern "C" char datatoc_gpu_shader_display_transform_vertex_glsl[];
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
-typedef struct OCIO_GLSLShader {
- /* Cache ID */
- std::string lut3dCacheID;
- std::string shaderCacheID;
-
- /* LUT */
- bool lut3d_texture_allocated; /* boolean flag indicating whether
- * lut texture is allocated
- */
- bool lut3d_texture_valid;
-
- GLuint lut3d_texture; /* OGL texture ID for 3D LUT */
-
- float *lut3d; /* 3D LUT table */
-
- /* Dither */
- bool use_dither;
-
- /* Curve Mapping */
- bool use_curve_mapping;
- bool curve_mapping_texture_allocated;
- bool curve_mapping_texture_valid;
- GLuint curve_mapping_texture;
- size_t curve_mapping_cache_id;
-
- /* Alpha Predivide */
- bool use_predivide;
+/* Curve mapping parameters
+ *
+ * See documentation for OCIO_CurveMappingSettings to get fields descriptions.
+ * (this ones pretty much copies stuff from C structure.)
+ */
+typedef struct OCIO_GLSLCurveMappingParameters {
+ float curve_mapping_mintable[4];
+ float curve_mapping_range[4];
+ float curve_mapping_ext_in_x[4];
+ float curve_mapping_ext_in_y[4];
+ float curve_mapping_ext_out_x[4];
+ float curve_mapping_ext_out_y[4];
+ float curve_mapping_first_x[4];
+ float curve_mapping_first_y[4];
+ float curve_mapping_last_x[4];
+ float curve_mapping_last_y[4];
+ float curve_mapping_black[4];
+ float curve_mapping_bwmul[4];
+ int curve_mapping_lut_size;
+ int curve_mapping_use_extend_extrapolate;
+ int _pad[2];
+ /** WARNING: Needs to be 16byte aligned. Used as UBO data. */
+} OCIO_GLSLCurveMappingParameters;
- /* GLSL stuff */
- GLuint ocio_shader;
- GLuint vert_shader;
+typedef struct OCIO_GLSLShader {
+ /** Cache IDs */
+ std::string cacheId;
+ /** IMM shader interface. TOD
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list