[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