Pass dummy normal to elliptical hairs
This commit is contained in:
parent
5e21a0909c
commit
8125657606
|
@ -272,10 +272,13 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
|
|||
if (hair->num_curves())
|
||||
return;
|
||||
|
||||
Attribute *attr_normal = NULL;
|
||||
Attribute *attr_intercept = NULL;
|
||||
Attribute *attr_length = NULL;
|
||||
Attribute *attr_random = NULL;
|
||||
|
||||
if (hair->need_attribute(scene, ATTR_STD_VERTEX_NORMAL))
|
||||
attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL);
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
|
||||
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH))
|
||||
|
@ -325,6 +328,11 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
|
|||
num_curve_keys++;
|
||||
}
|
||||
|
||||
if (attr_normal != NULL) {
|
||||
/* TODO: compute geometry normals. */
|
||||
attr_normal->add(make_float3(1.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
if (attr_length != NULL) {
|
||||
attr_length->add(CData->curve_length[curve]);
|
||||
}
|
||||
|
@ -881,10 +889,14 @@ static void export_hair_curves(Scene *scene,
|
|||
int *curve_shader = hair->get_curve_shader().data();
|
||||
|
||||
/* Add requested attributes. */
|
||||
float3 *attr_normal = NULL;
|
||||
float *attr_intercept = NULL;
|
||||
float *attr_length = NULL;
|
||||
float *attr_random = NULL;
|
||||
|
||||
if (hair->need_attribute(scene, ATTR_STD_VERTEX_NORMAL)) {
|
||||
attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL)->data_float3();
|
||||
}
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
|
||||
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT)->data_float();
|
||||
}
|
||||
|
@ -912,6 +924,11 @@ static void export_hair_curves(Scene *scene,
|
|||
const float3 co = get_float3(b_attr_position.data[point_offset].vector());
|
||||
const float radius = b_attr_radius ? b_attr_radius->data[point_offset].value() : 0.005f;
|
||||
|
||||
if (attr_normal) {
|
||||
/* TODO: compute geometry normals. */
|
||||
attr_normal[point_offset] = make_float3(1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
curve_keys[point_offset] = co;
|
||||
curve_radius[point_offset] = radius;
|
||||
|
||||
|
|
|
@ -17,13 +17,6 @@ typedef struct MicrofacetHairExtra {
|
|||
float TRT;
|
||||
|
||||
float eccentricity;
|
||||
float twist_rate;
|
||||
float attr_descr_intercept;
|
||||
float attr_descr_length;
|
||||
|
||||
float axis_rot;
|
||||
float diffraction_weight;
|
||||
float pad1, pad2, pad3;
|
||||
|
||||
/* Geometry data. */
|
||||
float4 geom;
|
||||
|
@ -73,15 +66,20 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd,
|
|||
* the center, to grazing the other edge. This is the sine of the angle
|
||||
* between sd->Ng and Z, as seen from the tangent X. */
|
||||
|
||||
/* TODO: we convert this value to a cosine later and discard the sign, so
|
||||
* we could probably save some operations. */
|
||||
float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(X, sd->Ng);
|
||||
|
||||
kernel_assert(fabsf(h) < 1.0f + 1e-4f);
|
||||
kernel_assert(isfinite_safe(X));
|
||||
kernel_assert(isfinite_safe(h));
|
||||
|
||||
bsdf->extra->geom = make_float4(X.x, X.y, X.z, h);
|
||||
if (bsdf->model_type == NODE_MICROFACET_HAIR_ELLIPTIC_GGX ||
|
||||
bsdf->model_type == NODE_MICROFACET_HAIR_ELLIPTIC_BECKMANN) {
|
||||
/* Local frame is independent of the ray direction for elliptical hairs. */
|
||||
bsdf->extra->geom.w = h;
|
||||
}
|
||||
else {
|
||||
bsdf->extra->geom = make_float4(X.x, X.y, X.z, h);
|
||||
}
|
||||
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
|
||||
}
|
||||
|
@ -1126,23 +1124,10 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_elliptic(KernelGlobals kg,
|
|||
{
|
||||
/* get local wi(convention is reversed from other hair bcsdfs) */
|
||||
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
|
||||
const float3 X0 = float4_to_float3(bsdf->extra->geom);
|
||||
const float3 Y = safe_normalize(sd->dPdu);
|
||||
const float3 Z0 = safe_normalize(cross(X0, Y));
|
||||
|
||||
/* rotate (Z,X) around Y */
|
||||
const float curve_parameter = bsdf->extra->attr_descr_intercept;
|
||||
const float curve_length = bsdf->extra->attr_descr_length;
|
||||
const float curve_twist_rate = bsdf->extra->twist_rate;
|
||||
const float curve_twist_start = bsdf->extra->axis_rot;
|
||||
|
||||
const float twist_angle = M_2PI_F * (curve_twist_start +
|
||||
curve_twist_rate * curve_parameter * curve_length);
|
||||
const float sin_twist_angle = sinf(twist_angle);
|
||||
const float cos_twist_angle = cosf(twist_angle);
|
||||
|
||||
const float3 Z = cos_twist_angle * Z0 + sin_twist_angle * X0;
|
||||
const float3 X = -sin_twist_angle * Z0 + cos_twist_angle * X0;
|
||||
const float3 X = float4_to_float3(bsdf->extra->geom);
|
||||
float3 Y = sd->dPdu;
|
||||
const float3 Z = safe_normalize(cross(X, Y));
|
||||
Y = safe_normalize(cross(Z, X));
|
||||
|
||||
const float3 wi = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
|
||||
const float3 wo = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
|
||||
|
@ -1179,20 +1164,10 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg,
|
|||
}
|
||||
|
||||
/* get local wi (convention is reversed from other hair bcsdfs) */
|
||||
const float3 X0 = float4_to_float3(bsdf->extra->geom);
|
||||
const float3 Y = safe_normalize(sd->dPdu);
|
||||
const float3 Z0 = safe_normalize(cross(X0, Y));
|
||||
|
||||
/* const float curve_parameter = bsdf->extra->attr_descr_intercept; */
|
||||
/* const float curve_length = bsdf->extra->attr_descr_length; */
|
||||
|
||||
/* TODO: compute the ellipse orientation based on the curve normal or user-defined normal? */
|
||||
const float twist_angle = 0.0f;
|
||||
const float sin_twist_angle = sinf(twist_angle);
|
||||
const float cos_twist_angle = cosf(twist_angle);
|
||||
|
||||
const float3 Z = cos_twist_angle * Z0 + sin_twist_angle * X0;
|
||||
const float3 X = -sin_twist_angle * Z0 + cos_twist_angle * X0;
|
||||
const float3 X = float4_to_float3(bsdf->extra->geom);
|
||||
float3 Y = sd->dPdu;
|
||||
const float3 Z = safe_normalize(cross(X, Y));
|
||||
Y = safe_normalize(cross(Z, X));
|
||||
|
||||
const float3 wi = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
|
||||
|
||||
|
|
|
@ -884,8 +884,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
uint4 data_node3 = read_node(kg, &offset);
|
||||
uint4 data_node4 = read_node(kg, &offset);
|
||||
uint4 data_node5 = read_node(kg, &offset);
|
||||
uint4 data_node6 = read_node(kg, &offset);
|
||||
uint4 data_node7 = read_node(kg, &offset);
|
||||
|
||||
Spectrum weight = sd->svm_closure_weight * mix_weight;
|
||||
|
||||
|
@ -894,9 +892,9 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
float alpha = stack_load_float_default(stack, offset_ofs, data_node.z);
|
||||
float ior = stack_load_float_default(stack, ior_ofs, data_node.w);
|
||||
|
||||
uint coat_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs;
|
||||
uint Blur_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs;
|
||||
svm_unpack_node_uchar4(data_node2.x,
|
||||
&coat_ofs,
|
||||
&Blur_ofs,
|
||||
&melanin_ofs,
|
||||
&melanin_redness_ofs,
|
||||
&absorption_coefficient_ofs);
|
||||
|
@ -905,7 +903,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
svm_unpack_node_uchar4(
|
||||
data_node3.x, &tint_ofs, &random_ofs, &random_color_ofs, &random_roughness_ofs);
|
||||
|
||||
const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node4.y);
|
||||
const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node3.w);
|
||||
float random = 0.0f;
|
||||
if (attr_descr_random.offset != ATTR_STD_NOT_FOUND) {
|
||||
random = primitive_surface_attribute_float(kg, sd, attr_descr_random, NULL, NULL);
|
||||
|
@ -914,16 +912,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
random = stack_load_float_default(stack, random_ofs, data_node3.y);
|
||||
}
|
||||
|
||||
uint R_ofs, TT_ofs, TRT_ofs, temp;
|
||||
uint Blur_ofs, model_type;
|
||||
uint R_ofs, TT_ofs, TRT_ofs, model_type;
|
||||
|
||||
svm_unpack_node_uchar4(data_node5.x, &R_ofs, &TT_ofs, &TRT_ofs, &temp);
|
||||
float R = stack_load_float_default(stack, R_ofs, data_node5.y);
|
||||
float TT = stack_load_float_default(stack, TT_ofs, data_node5.z);
|
||||
float TRT = stack_load_float_default(stack, TRT_ofs, data_node5.w);
|
||||
|
||||
svm_unpack_node_uchar4(data_node6.x, &temp, &Blur_ofs, &temp, &model_type);
|
||||
float blur = stack_load_float_default(stack, Blur_ofs, data_node6.z);
|
||||
svm_unpack_node_uchar4(data_node4.x, &R_ofs, &TT_ofs, &TRT_ofs, &model_type);
|
||||
float R = stack_load_float_default(stack, R_ofs, data_node4.y);
|
||||
float TT = stack_load_float_default(stack, TT_ofs, data_node4.z);
|
||||
float TRT = stack_load_float_default(stack, TRT_ofs, data_node4.w);
|
||||
float blur = stack_load_float_default(stack, Blur_ofs, data_node2.y);
|
||||
|
||||
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)bsdf_alloc(
|
||||
sd, sizeof(MicrofacetHairBSDF), weight);
|
||||
|
@ -941,8 +936,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
bsdf->blur = clamp(blur, 0.0f, 1.0f);
|
||||
|
||||
/* Random factors range: [-randomization/2, +randomization/2]. */
|
||||
float random_roughness = stack_load_float_default(
|
||||
stack, random_roughness_ofs, data_node3.w);
|
||||
float random_roughness = param2;
|
||||
float factor_random_roughness = 1.0f + 2.0f * (random - 0.5f) * random_roughness;
|
||||
float roughness = param1 * factor_random_roughness;
|
||||
|
||||
|
@ -1023,21 +1017,18 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
if (model_type == NODE_MICROFACET_HAIR_ELLIPTIC_GGX ||
|
||||
model_type == NODE_MICROFACET_HAIR_ELLIPTIC_BECKMANN) {
|
||||
|
||||
uint eccentricity_ofs;
|
||||
svm_unpack_node_uchar4(data_node7.x, &eccentricity_ofs, &temp, &temp, &temp);
|
||||
uint eccentricity_ofs, temp;
|
||||
svm_unpack_node_uchar4(data_node5.x, &eccentricity_ofs, &temp, &temp, &temp);
|
||||
|
||||
float eccentricity = stack_load_float_default(stack, eccentricity_ofs, data_node7.y);
|
||||
float eccentricity = stack_load_float_default(stack, eccentricity_ofs, data_node5.y);
|
||||
|
||||
/* Eccentricity */
|
||||
bsdf->extra->eccentricity = (eccentricity > 1.f) ? 1.f / eccentricity : eccentricity;
|
||||
|
||||
const AttributeDescriptor attr_descr_intercept = find_attribute(kg, sd, data_node4.z);
|
||||
bsdf->extra->attr_descr_intercept = curve_attribute_float(
|
||||
kg, sd, attr_descr_intercept, NULL, NULL);
|
||||
|
||||
const AttributeDescriptor attr_descr_length = find_attribute(kg, sd, data_node4.w);
|
||||
bsdf->extra->attr_descr_length = curve_attribute_float(
|
||||
kg, sd, attr_descr_length, NULL, NULL);
|
||||
const AttributeDescriptor attr_descr_normal = find_attribute(kg, sd, data_node5.z);
|
||||
const float3 normal = curve_attribute_float3(kg, sd, attr_descr_normal, NULL, NULL);
|
||||
const float3 binormal = safe_normalize(cross(sd->dPdu, normal));
|
||||
bsdf->extra->geom = make_float4(binormal.x, binormal.y, binormal.z, 0.0f);
|
||||
}
|
||||
|
||||
sd->flag |= bsdf_microfacet_hair_setup(sd, bsdf);
|
||||
|
|
|
@ -611,6 +611,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
|
|||
}
|
||||
else if (geometry->geometry_type == Geometry::HAIR) {
|
||||
switch (std) {
|
||||
case ATTR_STD_VERTEX_NORMAL:
|
||||
attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_CURVE_KEY);
|
||||
break;
|
||||
case ATTR_STD_UV:
|
||||
attr = add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
|
||||
break;
|
||||
|
|
|
@ -3697,9 +3697,8 @@ MicrofacetHairBsdfNode::MicrofacetHairBsdfNode() : BsdfBaseNode(get_node_type())
|
|||
/* Enable retrieving Hair Info -> Random if Random isn't linked. */
|
||||
void MicrofacetHairBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||
{
|
||||
/* Make sure we have these 2 for elliptical cross section tracking */
|
||||
attributes->add(ATTR_STD_CURVE_INTERCEPT);
|
||||
attributes->add(ATTR_STD_CURVE_LENGTH);
|
||||
/* Make sure we have the normal for elliptical cross section tracking */
|
||||
attributes->add(ATTR_STD_VERTEX_NORMAL);
|
||||
|
||||
if (!input("Random")->link) {
|
||||
attributes->add(ATTR_STD_CURVE_RANDOM);
|
||||
|
@ -3753,63 +3752,49 @@ void MicrofacetHairBsdfNode::compile(SVMCompiler &compiler)
|
|||
compiler.add_node(
|
||||
NODE_CLOSURE_BSDF,
|
||||
/* Socket IDs can be packed 4 at a time into a single data packet */
|
||||
compiler.encode_uchar4(closure, roughness_ofs, 0, compiler.closure_mix_weight_offset()),
|
||||
compiler.encode_uchar4(
|
||||
closure, roughness_ofs, random_roughness_ofs, compiler.closure_mix_weight_offset()),
|
||||
/* The rest are stored as unsigned integers */
|
||||
__float_as_uint(roughness),
|
||||
0);
|
||||
__float_as_uint(random_roughness));
|
||||
|
||||
/* data node */
|
||||
compiler.add_node(normal_ofs,
|
||||
compiler.encode_uchar4(offset_ofs, ior_ofs, color_ofs, parametrization),
|
||||
__float_as_uint(offset),
|
||||
__float_as_uint(ior));
|
||||
|
||||
/* data node 2 */
|
||||
compiler.add_node(
|
||||
compiler.encode_uchar4(0, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs),
|
||||
0,
|
||||
__float_as_uint(melanin),
|
||||
__float_as_uint(melanin_redness));
|
||||
compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(Blur_in),
|
||||
melanin_ofs,
|
||||
melanin_redness_ofs,
|
||||
absorption_coefficient_ofs),
|
||||
__float_as_uint(Blur),
|
||||
__float_as_uint(melanin),
|
||||
__float_as_uint(melanin_redness));
|
||||
|
||||
/* data node 3 */
|
||||
compiler.add_node(
|
||||
compiler.encode_uchar4(tint_ofs, random_in_ofs, random_color_ofs, random_roughness_ofs),
|
||||
__float_as_uint(random),
|
||||
__float_as_uint(random_color),
|
||||
__float_as_uint(random_roughness));
|
||||
|
||||
int attr_intercept = compiler.attribute(ATTR_STD_CURVE_INTERCEPT);
|
||||
int attr_length = compiler.attribute(ATTR_STD_CURVE_LENGTH);
|
||||
compiler.add_node(compiler.encode_uchar4(tint_ofs, random_in_ofs, random_color_ofs, 0),
|
||||
__float_as_uint(random),
|
||||
__float_as_uint(random_color),
|
||||
attr_random);
|
||||
|
||||
/* data node 4 */
|
||||
compiler.add_node(
|
||||
compiler.encode_uchar4(
|
||||
SVM_STACK_INVALID, SVM_STACK_INVALID, SVM_STACK_INVALID, SVM_STACK_INVALID),
|
||||
attr_random,
|
||||
attr_intercept,
|
||||
attr_length);
|
||||
|
||||
/* data node 5 */
|
||||
compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(R_in),
|
||||
compiler.stack_assign_if_linked(TT_in),
|
||||
compiler.stack_assign_if_linked(TRT_in),
|
||||
SVM_STACK_INVALID),
|
||||
model_type),
|
||||
__float_as_uint(R),
|
||||
__float_as_uint(TT),
|
||||
__float_as_uint(TRT));
|
||||
|
||||
/* data node 6 */
|
||||
compiler.add_node(
|
||||
compiler.encode_uchar4(0, compiler.stack_assign_if_linked(Blur_in), 0, model_type),
|
||||
0,
|
||||
__float_as_uint(Blur),
|
||||
0);
|
||||
|
||||
/* data node 7 */
|
||||
/* data node 5 */
|
||||
compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(eccentricity_in),
|
||||
SVM_STACK_INVALID,
|
||||
SVM_STACK_INVALID,
|
||||
SVM_STACK_INVALID),
|
||||
__float_as_uint(eccentricity),
|
||||
0,
|
||||
compiler.attribute(ATTR_STD_VERTEX_NORMAL),
|
||||
0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue