[Bf-committers] [Bf-blender-cvs] [5a91df3] master: Implement GPU-side dither

Sergey Sharybin sergey.vfx at gmail.com
Fri Dec 13 07:43:16 CET 2013


Sheesis. arc lang f*cked up my commit message to original WIP one. Bummer!!

Proper message is:

    Implement GPU-side dither

    Summary:
    Uses some magic pseudo-random which is actually a texture coordinate
    hashing function for dithering.

    This is easy to be implemented on GPU and gives reasonable results.

    Also changed CPU-side dither to match CPU with GPU.

    Possible optimization is to use pre-computed LUT for sine values on CPU.

    Gives from 0 to 3 bits of noise.

    This will now use the same pattern for all the frames, which might look
a
    bit odd, but using different patterns on different frames can also be
    distracting. Let's see how static pattern behaves.

    TODO: Dither pattern would be different during rendering and final
          result. This is because coord hash is different when doing
          partial buffer update. This is not a new issue, so perhaps
          not so crucial for now.

    Reviewers: brecht



On Fri, Dec 13, 2013 at 12:36 PM, Sergey Sharybin
<noreply at git.blender.org>wrote:

> 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
> Bf-blender-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>



-- 
With best regards, Sergey Sharybin


More information about the Bf-committers mailing list