Commit: 5a91df32713b7ad9be6befa7124b31890063d91b Author: Sergey Sharybin Date: Fri Dec 13 12:36:45 2013 +0600 http://developer.blender.org/rB5a91df32713b7ad9be6befa7124b31890063d91b
Implement GPU-side dither Summary: Uses some magic pseudo-random which is actually a texture coordinate hashing function. TODOs: - Dither noise is the same for all the frames. - It's different from Floyd's dither we've been using before. - Currently CPU and GPU dithering used different implementation. Ideally we need to use the same dither in CPU. Reviewers: brecht Reviewed By: brecht Differential Revision: http://developer.blender.org/D58 =================================================================== M intern/opencolorio/fallback_impl.cc M intern/opencolorio/gpu_shader_display_transform.glsl M intern/opencolorio/ocio_capi.cc M intern/opencolorio/ocio_capi.h M intern/opencolorio/ocio_impl.h M intern/opencolorio/ocio_impl_glsl.cc M source/blender/editors/render/render_internal.c M source/blender/editors/screen/glutil.c M source/blender/editors/space_sequencer/sequencer_draw.c M source/blender/imbuf/IMB_colormanagement.h M source/blender/imbuf/intern/colormanagement.c M source/blender/imbuf/intern/divers.c M source/blender/makesrna/intern/rna_render.c =================================================================== diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc index 6383bbb..c0797cb 100644 --- a/intern/opencolorio/fallback_impl.cc +++ b/intern/opencolorio/fallback_impl.cc @@ -419,7 +419,8 @@ bool FallbackImpl::supportGLSLDraw(void) } bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/, OCIO_ConstProcessorRcPtr * /*processor*/, - OCIO_CurveMappingSettings * /*curve_mapping_settings*/, bool /*predivide*/) + OCIO_CurveMappingSettings * /*curve_mapping_settings*/, + float /*dither*/, bool /*predivide*/) { return false; } diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl index 6ba3fa5..8a85d6c 100644 --- a/intern/opencolorio/gpu_shader_display_transform.glsl +++ b/intern/opencolorio/gpu_shader_display_transform.glsl @@ -2,6 +2,10 @@ uniform sampler2D image_texture; uniform sampler3D lut3d_texture; uniform bool predivide; +#ifdef USE_DITHER +uniform float dither; +#endif + #ifdef USE_CURVE_MAPPING /* Curve mapping parameters * @@ -102,6 +106,33 @@ vec4 curvemapping_evaluate_premulRGBF(vec4 col) } #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 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; +} + +vec4 apply_dither(vec2 st, vec4 col) +{ + 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; +} +#endif + void main() { vec4 col = texture2D(image_texture, gl_TexCoord[0].st); @@ -119,5 +150,12 @@ void main() * and the reason is simple -- opengl is always configured * for straight alpha at this moment */ - gl_FragColor = OCIODisplay(col, lut3d_texture); + + vec4 result = OCIODisplay(col, lut3d_texture); + +#ifdef USE_DITHER + result = apply_dither(gl_TexCoord[0].st, result); +#endif + + gl_FragColor = result; } diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc index 47ee3af..a4f2db4 100644 --- a/intern/opencolorio/ocio_capi.cc +++ b/intern/opencolorio/ocio_capi.cc @@ -324,9 +324,9 @@ int OCIO_supportGLSLDraw(void) } int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, - OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide) + OCIO_CurveMappingSettings *curve_mapping_settings, float dither, bool predivide) { - return (int) impl->setupGLSLDraw(state_r, processor, curve_mapping_settings, predivide); + return (int) impl->setupGLSLDraw(state_r, processor, curve_mapping_settings, dither, predivide); } void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state) diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h index 5abe104..d667dec 100644 --- a/intern/opencolorio/ocio_capi.h +++ b/intern/opencolorio/ocio_capi.h @@ -189,7 +189,7 @@ void OCIO_matrixTransformScale(float *m44, float *offset4, const float *scale4); int OCIO_supportGLSLDraw(void); int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, - OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide); + OCIO_CurveMappingSettings *curve_mapping_settings, float dither, bool predivide); void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state); void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state); diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h index 4e7c1bc..47e6d82 100644 --- a/intern/opencolorio/ocio_impl.h +++ b/intern/opencolorio/ocio_impl.h @@ -107,7 +107,7 @@ public: virtual bool supportGLSLDraw(void) = 0; virtual bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, - OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide) = 0; + OCIO_CurveMappingSettings *curve_mapping_settings, float dither, bool predivide) = 0; virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0; virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0; @@ -194,7 +194,7 @@ public: bool supportGLSLDraw(void); bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, - OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide); + OCIO_CurveMappingSettings *curve_mapping_settings, float dither, bool predivide); void finishGLSLDraw(struct OCIO_GLSLDrawState *state); void freeGLState(struct OCIO_GLSLDrawState *state_r); @@ -282,7 +282,7 @@ public: bool supportGLSLDraw(void); bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, - OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide); + OCIO_CurveMappingSettings *curve_mapping_settings, float dither, bool predivide); void finishGLSLDraw(struct OCIO_GLSLDrawState *state); void freeGLState(struct OCIO_GLSLDrawState *state_r); diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc index 2af3bef..3a23c26 100644 --- a/intern/opencolorio/ocio_impl_glsl.cc +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -33,6 +33,7 @@ * */ +#include <limits> #include <sstream> #include <string.h> @@ -62,6 +63,8 @@ typedef struct OCIO_GLSLDrawState { float *lut3d; /* 3D LUT table */ + bool dither_used; + bool curve_mapping_used; bool curve_mapping_texture_allocated; bool curve_mapping_texture_valid; @@ -229,10 +232,12 @@ bool OCIOImpl::supportGLSLDraw() * restore OpenGL context to it's pre-GLSL draw state. */ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, - OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide) + OCIO_CurveMappingSettings *curve_mapping_settings, + float dither, bool predivide) { ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor; bool use_curve_mapping = curve_mapping_settings != NULL; + bool use_dither = dither > std::numeric_limits<float>::epsilon(); /* Create state if needed. */ OCIO_GLSLDrawState *state; @@ -267,7 +272,7 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc /* Step 1: Create a GPU Shader Description */ GpuShaderDesc shaderDesc; - shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0); + shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_3); shaderDesc.setFunctionName("OCIODisplay"); shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); @@ -297,7 +302,8 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc); if (state->program == 0 || shaderCacheID != state->shadercacheid || - use_curve_mapping != state->curve_mapping_used) + use_curve_mapping != state->curve_mapping_used || + use_dither != state->dither_used) { state->shadercacheid = shaderCacheID; @@ -311,6 +317,12 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc std::ostringstream os; + os << "#version 130\n"; + + if (use_dither) { + os << "#define USE_DITHER\n"; + } + if (use_curve_mapping) { os << "#define USE_CURVE_MAPPING\n"; } @@ -325,6 +337,7 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc } state->curve_mapping_used = use_curve_mapping; + state->dither_used = use_dither; } if (state->program) { @@ -344,6 +357,10 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc glUniform1i(glGetUniformLocation(state->program, "lut3d_texture"), 1); glUniform1i(glGetUniformLocation(state->program, "predivide"), predivide); + if (use_dither) { + glUniform1f(glGetUniformLocation(state->program, "dither"), dither); + } + if (use_curve_mapping) { glUniform1i(glGetUniformLocation(state->program, "curve_mapping_texture"), 2); glUniform1i(glGetUniformLocation(state->program, "curve_mapping_lut_size"), curve_mapping_settings->lut_size); diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index e1a271e..1b090cb 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -1150,7 +1150,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C) /* Try using GLSL display transform. */ if (force_fallback == false) { - if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, true)) { + if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, 0.0f, true)) { glEnable(GL_BLEND); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glaDrawPixelsTex(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_FLOAT, diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 57d9717..af5f9d3 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -1044,9 +1044,6 @@ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; - /* Dithering is not supported on GLSL yet */ - force_fallback |= ibuf->dither != 0.0f; - /* Single channel images could not be transformed using GLSL yet */ force_fallback |= ibuf->channels == 1; @@ -1093,15 +1090,18 @@ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, if (ibuf->rect_float) { if (ibuf->float_colorspace) { ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, displa @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-blender-cvs
