From 4e9ed1dae9647bf45a30d3af546f5a08e7a9b3e3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 30 Jun 2020 14:07:49 +0200 Subject: [PATCH] Fix T78447: Cycles vertex color node not working with hair --- intern/cycles/blender/blender_curves.cpp | 8 +-- intern/cycles/kernel/geom/geom_curve.h | 60 ++++++++++++++++++++++ intern/cycles/kernel/geom/geom_primitive.h | 5 ++ intern/cycles/render/curves.h | 2 +- 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 7eb76c8bd8f..82c99631a89 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -262,7 +262,7 @@ static bool ObtainCacheParticleVcol(Hair *hair, BL::Mesh::vertex_colors_iterator l; b_mesh->vertex_colors.begin(l); - float3 vcol = make_float3(0.0f, 0.0f, 0.0f); + float4 vcol = make_float4(0.0f, 0.0f, 0.0f, 1.0f); if (b_mesh->vertex_colors.length()) b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x); CData->curve_vcol.push_back_slow(vcol); @@ -578,16 +578,16 @@ void BlenderSync::sync_particle_hair( ObtainCacheParticleVcol(hair, &b_mesh, &b_ob, &CData, !preview, vcol_num); Attribute *attr_vcol = hair->attributes.add( - ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE); + ustring(l->name().c_str()), TypeRGBA, ATTR_ELEMENT_CURVE); - float3 *fdata = attr_vcol->data_float3(); + float4 *fdata = attr_vcol->data_float4(); if (fdata) { size_t i = 0; /* Encode vertex color using the sRGB curve. */ for (size_t curve = 0; curve < CData.curve_vcol.size(); curve++) { - fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]); + fdata[i++] = color_srgb_to_linear_v4(CData.curve_vcol[curve]); } } } diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h index a7a262c029f..6ff0c7f2044 100644 --- a/intern/cycles/kernel/geom/geom_curve.h +++ b/intern/cycles/kernel/geom/geom_curve.h @@ -198,6 +198,66 @@ ccl_device float3 curve_attribute_float3(KernelGlobals *kg, } } +ccl_device float4 curve_attribute_float4(KernelGlobals *kg, + const ShaderData *sd, + const AttributeDescriptor desc, + float4 *dx, + float4 *dy) +{ + if (desc.element == ATTR_ELEMENT_CURVE) { + /* idea: we can't derive any useful differentials here, but for tiled + * mipmap image caching it would be useful to avoid reading the highest + * detail level always. maybe a derivative based on the hair density + * could be computed somehow? */ +# ifdef __RAY_DIFFERENTIALS__ + if (dx) + *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (dy) + *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); +# endif + + return kernel_tex_fetch(__attributes_float3, desc.offset + sd->prim); + } + else if (desc.element == ATTR_ELEMENT_CURVE_KEY || + desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) { + float4 curvedata = kernel_tex_fetch(__curves, sd->prim); + int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type); + int k1 = k0 + 1; + + float4 f0 = kernel_tex_fetch(__attributes_float3, desc.offset + k0); + float4 f1 = kernel_tex_fetch(__attributes_float3, desc.offset + k1); + +# ifdef __RAY_DIFFERENTIALS__ + if (dx) + *dx = sd->du.dx * (f1 - f0); + if (dy) + *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); +# endif + + return (1.0f - sd->u) * f0 + sd->u * f1; + } + else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) { +# ifdef __RAY_DIFFERENTIALS__ + if (dx) + *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (dy) + *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); +# endif + + return kernel_tex_fetch(__attributes_float3, desc.offset); + } + else { +# ifdef __RAY_DIFFERENTIALS__ + if (dx) + *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (dy) + *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); +# endif + + return make_float4(0.0f, 0.0f, 0.0f, 0.0f); + } +} + /* Curve thickness */ ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd) diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h index 9a91da79f58..997abf438d0 100644 --- a/intern/cycles/kernel/geom/geom_primitive.h +++ b/intern/cycles/kernel/geom/geom_primitive.h @@ -174,6 +174,11 @@ ccl_device_inline float4 primitive_attribute_float4(KernelGlobals *kg, else return subd_triangle_attribute_float4(kg, sd, desc, dx, dy); } +#ifdef __HAIR__ + else if (sd->type & PRIMITIVE_ALL_CURVE) { + return curve_attribute_float4(kg, sd, desc, dx, dy); + } +#endif else { if (dx) *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h index 71c09ba2d2b..c52fcb9c882 100644 --- a/intern/cycles/render/curves.h +++ b/intern/cycles/render/curves.h @@ -50,7 +50,7 @@ class ParticleCurveData { array curve_keynum; array curve_length; array curve_uv; - array curve_vcol; + array curve_vcol; array curvekey_co; array curvekey_time;