Fix T47207: Material shading incorrectly handles colorramp node
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 2 Feb 2016 11:48:18 +0000 (12:48 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 2 Feb 2016 11:50:56 +0000 (12:50 +0100)
The issue was introduced by a fix for T44713 which only made GLSL
consistent with Cycles.

Now we do have conditional averaging or proper luma weighting based
on whether we're new old old shading system. Not totally ideal but
should work for until we re-design viewport possibly breaking how
Blender Internal does implicit conversion.

source/blender/gpu/GPU_shader.h
source/blender/gpu/intern/gpu_codegen.c
source/blender/gpu/intern/gpu_codegen.h
source/blender/gpu/intern/gpu_material.c
source/blender/gpu/intern/gpu_shader.c
source/blender/gpu/shaders/gpu_shader_material.glsl

index 468cc2f0f6e072cc9b025db91d801b66f8c87c53..0317976f9d0046144112ef80793cd89144155313 100644 (file)
@@ -46,6 +46,7 @@ struct GPUTexture;
 enum {
        GPU_SHADER_FLAGS_NONE = 0,
        GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV = (1 << 0),
+       GPU_SHADER_FLAGS_NEW_SHADING        = (1 << 1),
 };
 
 GPUShader *GPU_shader_create(
index c3f79bc9492bfa7be84c3631bcc93ffd3637ad29..7cd05eff64e038bd1bcb06adf5c625be04b4d73c 100644 (file)
@@ -318,7 +318,9 @@ static void codegen_convert_datatype(DynStr *ds, int from, int to, const char *t
                BLI_dynstr_append(ds, name);
        }
        else if (to == GPU_FLOAT) {
-               if (from == GPU_VEC4 || from == GPU_VEC3)
+               if (from == GPU_VEC4)
+                       BLI_dynstr_appendf(ds, "convert_rgba_to_float(%s)", name);
+               else if (from == GPU_VEC3)
                        BLI_dynstr_appendf(ds, "(%s.r + %s.g + %s.b) / 3.0", name, name, name);
                else if (from == GPU_VEC2)
                        BLI_dynstr_appendf(ds, "%s.r", name);
@@ -1641,7 +1643,9 @@ static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
 GPUPass *GPU_generate_pass(
         ListBase *nodes, GPUNodeLink *outlink,
         GPUVertexAttribs *attribs, int *builtins,
-        const GPUMatType type, const char *UNUSED(name), const bool use_opensubdiv)
+        const GPUMatType type, const char *UNUSED(name),
+        const bool use_opensubdiv,
+        const bool use_new_shading)
 {
        GPUShader *shader;
        GPUPass *pass;
@@ -1664,6 +1668,14 @@ GPUPass *GPU_generate_pass(
        fragmentcode = code_generate_fragment(nodes, outlink->output);
        vertexcode = code_generate_vertex(nodes, type);
        geometrycode = code_generate_geometry(nodes, use_opensubdiv);
+
+       int flags = GPU_SHADER_FLAGS_NONE;
+       if (use_opensubdiv) {
+               flags |= GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV;
+       }
+       if (use_new_shading) {
+               flags |= GPU_SHADER_FLAGS_NEW_SHADING;
+       }
        shader = GPU_shader_create_ex(vertexcode,
                                      fragmentcode,
                                      geometrycode,
@@ -1672,8 +1684,7 @@ GPUPass *GPU_generate_pass(
                                      0,
                                      0,
                                      0,
-                                     use_opensubdiv ? GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV
-                                                    : GPU_SHADER_FLAGS_NONE);
+                                     flags);
 
        /* failed? */
        if (!shader) {
index 75102658c88d4109976f394b9bb51ef474b03d16..417e46a83eea49c9ac63779e7971b27186dc4e98 100644 (file)
@@ -172,7 +172,9 @@ typedef struct GPUPass GPUPass;
 
 GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
                            struct GPUVertexAttribs *attribs, int *builtin,
-                           const GPUMatType type, const char *name, const bool use_opensubdiv);
+                           const GPUMatType type, const char *name,
+                           const bool use_opensubdiv,
+                           const bool use_new_shading);
 
 struct GPUShader *GPU_pass_shader(GPUPass *pass);
 
index 4d9fa54939c2ba85139c718f87c5f6bed7888955..67f30be6a12898088fde3f89d3b71597b8022981 100644 (file)
@@ -226,7 +226,9 @@ static int GPU_material_construct_end(GPUMaterial *material, const char *passnam
                GPUNodeLink *outlink = material->outlink;
                material->pass = GPU_generate_pass(&material->nodes, outlink,
                        &material->attribs, &material->builtins, material->type,
-                       passname, material->is_opensubdiv);
+                       passname,
+                       material->is_opensubdiv,
+                       GPU_material_use_new_shading_nodes(material));
 
                if (!material->pass)
                        return 0;
index 5bef3df928ce516cacc3c89cc3940e2e912f1676..f0bab2bb983ead27ed33f41a09c1c8bcdecdb418 100644 (file)
@@ -183,7 +183,9 @@ static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH],
        }
 }
 
-static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH], bool use_opensubdiv)
+static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH],
+                                        bool use_opensubdiv,
+                                        bool use_new_shading)
 {
        /* some useful defines to detect GPU type */
        if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
@@ -222,6 +224,10 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH], bool us
        UNUSED_VARS(use_opensubdiv);
 #endif
 
+       if (use_new_shading) {
+               strcat(defines, "#define USE_NEW_SHADING\n");
+       }
+
        return;
 }
 
@@ -296,7 +302,9 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
                return NULL;
        }
 
-       gpu_shader_standard_defines(standard_defines, use_opensubdiv);
+       gpu_shader_standard_defines(standard_defines,
+                                   use_opensubdiv,
+                                   (flags & GPU_SHADER_FLAGS_NEW_SHADING) != 0);
        gpu_shader_standard_extensions(standard_extensions, geocode != NULL);
 
        if (vertexcode) {
index 4429770f998a4668285bf725e2e68696363a518b..df14392610be280b825cee8850503dcd0c6744b8 100644 (file)
@@ -1,3 +1,13 @@
+/* Converters */
+
+float convert_rgba_to_float(vec4 color)
+{
+#ifdef USE_NEW_SHADING
+       return color.r*0.2126 + color.g*0.7152 + color.b*0.0722;
+#else
+       return (color.r + color.g + color.b) / 3.0;
+#endif
+}
 
 float exp_blender(float f)
 {
@@ -743,7 +753,11 @@ void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha
 
 void rgbtobw(vec4 color, out float outval)  
 {
+#ifdef USE_NEW_SHADING
+       outval = color.r*0.2126 + color.g*0.7152 + color.b*0.0722;
+#else
        outval = color.r*0.35 + color.g*0.45 + color.b*0.2; /* keep these factors in sync with texture.h:RGBTOBW */
+#endif
 }
 
 void invert(float fac, vec4 col, out vec4 outcol)