Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-12-13 10:36:45 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-12-13 10:36:45 +0400
commit5a91df32713b7ad9be6befa7124b31890063d91b (patch)
tree11309c67510bb0ffd29438318896cf86b8024c02 /intern/opencolorio
parent669b5902298f0f80159395d020657d6630a532ac (diff)
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
Diffstat (limited to 'intern/opencolorio')
-rw-r--r--intern/opencolorio/fallback_impl.cc3
-rw-r--r--intern/opencolorio/gpu_shader_display_transform.glsl40
-rw-r--r--intern/opencolorio/ocio_capi.cc4
-rw-r--r--intern/opencolorio/ocio_capi.h2
-rw-r--r--intern/opencolorio/ocio_impl.h6
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc23
6 files changed, 67 insertions, 11 deletions
diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc
index 6383bbbb07f..c0797cbc37f 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 6ba3fa55e8f..8a85d6cbffe 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 47ee3afddfd..a4f2db456e8 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 5abe104fcd4..d667dece62a 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 4e7c1bcc832..47e6d829902 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 2af3befc8a9..3a23c266345 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);