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

Lukas Tönne lukas.toenne at gmail.com
Fri Dec 13 12:34:06 CET 2013


I already noticed arc is not capable of producing a good commit message on
its own, always have to copy-paste the original by hand ...


On Fri, Dec 13, 2013 at 7:43 AM, Sergey Sharybin <sergey.vfx at gmail.com>wrote:

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


More information about the Bf-committers mailing list