From 5a91df32713b7ad9be6befa7124b31890063d91b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 13 Dec 2013 12:36:45 +0600 Subject: 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 --- intern/opencolorio/ocio_impl_glsl.cc | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'intern/opencolorio/ocio_impl_glsl.cc') 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 #include #include @@ -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::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); -- cgit v1.2.3