From ec6a9322e8723b906089f02ff76b04a7bb7d136f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 9 Nov 2020 17:23:32 +0100 Subject: Fix T78956: banding artifacts of vertex colors in Cycles Byte colors must be encoded in sRGB and converted to linear on lookup, to avoid precision loss. --- intern/cycles/blender/blender_mesh.cpp | 9 +++++---- intern/cycles/kernel/geom/geom_patch.h | 3 ++- intern/cycles/kernel/geom/geom_subd_triangle.h | 19 ++++++++++--------- intern/cycles/kernel/geom/geom_triangle.h | 12 ++++++++---- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index e40e1f5f001..b78a2c30b5e 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -346,7 +346,7 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, for (int i = 0; i < n; i++) { float4 color = get_float4(l->data[p->loop_start() + i].color()); /* Compress/encode vertex color using the sRGB curve. */ - *(cdata++) = color_float4_to_uchar4(color_srgb_to_linear_v4(color)); + *(cdata++) = color_float4_to_uchar4(color); } } } @@ -368,9 +368,10 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, float4 c3 = get_float4(l->data[li[2]].color()); /* Compress/encode vertex color using the sRGB curve. */ - cdata[0] = color_float4_to_uchar4(color_srgb_to_linear_v4(c1)); - cdata[1] = color_float4_to_uchar4(color_srgb_to_linear_v4(c2)); - cdata[2] = color_float4_to_uchar4(color_srgb_to_linear_v4(c3)); + cdata[0] = color_float4_to_uchar4(c1); + cdata[1] = color_float4_to_uchar4(c2); + cdata[2] = color_float4_to_uchar4(c3); + cdata += 3; } } diff --git a/intern/cycles/kernel/geom/geom_patch.h b/intern/cycles/kernel/geom/geom_patch.h index 8b4b91b96c8..b996294c51f 100644 --- a/intern/cycles/kernel/geom/geom_patch.h +++ b/intern/cycles/kernel/geom/geom_patch.h @@ -405,7 +405,8 @@ ccl_device float4 patch_eval_uchar4(KernelGlobals *kg, *dv = make_float4(0.0f, 0.0f, 0.0f, 0.0f); for (int i = 0; i < num_control; i++) { - float4 v = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, offset + indices[i])); + float4 v = color_srgb_to_linear_v4( + color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, offset + indices[i]))); val += v * weights[i]; if (du) diff --git a/intern/cycles/kernel/geom/geom_subd_triangle.h b/intern/cycles/kernel/geom/geom_subd_triangle.h index 3eef9857ae3..317f3984a9a 100644 --- a/intern/cycles/kernel/geom/geom_subd_triangle.h +++ b/intern/cycles/kernel/geom/geom_subd_triangle.h @@ -581,14 +581,14 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals *kg, int corners[4]; subd_triangle_patch_corners(kg, patch, corners); - float4 f0 = color_uchar4_to_float4( - kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset)); - float4 f1 = color_uchar4_to_float4( - kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset)); - float4 f2 = color_uchar4_to_float4( - kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset)); - float4 f3 = color_uchar4_to_float4( - kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset)); + float4 f0 = color_srgb_to_linear_v4( + color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset))); + float4 f1 = color_srgb_to_linear_v4( + color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset))); + float4 f2 = color_srgb_to_linear_v4( + color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset))); + float4 f3 = color_srgb_to_linear_v4( + color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset))); if (subd_triangle_patch_num_corners(kg, patch) != 4) { f1 = (f1 + f0) * 0.5f; @@ -614,7 +614,8 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals *kg, if (dy) *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - return color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, desc.offset)); + return color_srgb_to_linear_v4( + color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, desc.offset))); } else { if (dx) diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h index 0278f3ade8e..5ecc2566815 100644 --- a/intern/cycles/kernel/geom/geom_triangle.h +++ b/intern/cycles/kernel/geom/geom_triangle.h @@ -317,9 +317,12 @@ ccl_device float4 triangle_attribute_float4(KernelGlobals *kg, if (desc.element == ATTR_ELEMENT_CORNER_BYTE) { int tri = desc.offset + sd->prim * 3; - f0 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 0)); - f1 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 1)); - f2 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 2)); + f0 = color_srgb_to_linear_v4( + color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 0))); + f1 = color_srgb_to_linear_v4( + color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 1))); + f2 = color_srgb_to_linear_v4( + color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 2))); } else { uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); @@ -343,7 +346,8 @@ ccl_device float4 triangle_attribute_float4(KernelGlobals *kg, if (dy) *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - return color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, desc.offset)); + return color_srgb_to_linear_v4( + color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, desc.offset))); } else { if (dx) -- cgit v1.2.3