[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