[Bf-blender-cvs] [eb4abf2ca7a] soc-2018-hair-shader: Linearize melanin concentration
L. E. Segovia
noreply at git.blender.org
Mon Jul 9 18:14:05 CEST 2018
Commit: eb4abf2ca7a0f38a46ebb122cfcd590f07164ed2
Author: L. E. Segovia
Date: Mon Jul 9 16:12:31 2018 +0000
Branches: soc-2018-hair-shader
https://developer.blender.org/rBeb4abf2ca7a0f38a46ebb122cfcd590f07164ed2
Linearize melanin concentration
This commit includes factoring remappings into new functions, as well as
adjusted defaults for maintaining roughly the same brownish hair.
(In reality, Melanin 1.3 = New Melanin 0.8054375, so I truncated the
extra decimal places.)
===================================================================
M intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl
M intern/cycles/kernel/svm/svm_closure.h
M intern/cycles/render/nodes.cpp
M source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c
===================================================================
diff --git a/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl b/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl
index a4709702496..b4451164240 100644
--- a/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl
@@ -20,10 +20,19 @@ color log3 (color a) {
return color(log(a[0]), log(a[1]), log(a[2]));
}
+color sigma_from_concentration(float Eumelanin, float Pheomelanin) {
+ return Eumelanin*color(0.506, 0.841, 1.653) + Pheomelanin*color(0.343, 0.733, 1.924);
+}
+
+color sigma_from_reflectance(color Color, float AzimuthalRoughness) {
+ float roughness_fac = (((((0.245*AzimuthalRoughness) + 5.574)*AzimuthalRoughness - 10.73)*AzimuthalRoughness + 2.532)*AzimuthalRoughness - 0.215)*AzimuthalRoughness + 5.969;
+ return log3(Color)/roughness_fac;
+}
+
shader node_principled_hair_bsdf(
- color Color = color(0.09292, 0.02100, 0.00417),
- float Melanin = 0.0,
- float MelaninRedness = 1.3,
+ color Color = color(0.017513, 0.005763, 0.002059),
+ float Melanin = 0.8,
+ float MelaninRedness = 1.0,
float RandomColor = 0.0,
color Tint = 1.0,
color AbsorptionCoefficient = color(0.245531, 0.52, 1.365),
@@ -41,7 +50,6 @@ shader node_principled_hair_bsdf(
output closure color BSDF = 0)
{
color sigma;
-
float random_value = 0.0;
if (AttrRandom != "none") {
@@ -57,28 +65,27 @@ shader node_principled_hair_bsdf(
float adjusted_roughness = Roughness*factor_random_roughness;
float adjusted_radial_roughness = RadialRoughness*factor_random_roughness;
- float adjusted_eumelanin = Melanin*(1.0-MelaninRedness)*factor_random_color;
- float adjusted_pheomelanin = Melanin*MelaninRedness*factor_random_color;
+ float melanin_qty = -log(max(1.0 - Melanin, 0.0001));
+ float adjusted_eumelanin = melanin_qty*(1.0-MelaninRedness)*factor_random_color;
+ float adjusted_pheomelanin = melanin_qty*MelaninRedness*factor_random_color;
if (parametrization == "Absorption coefficient") {
sigma = AbsorptionCoefficient;
}
else if (parametrization == "Melanin concentration") {
- color melanin_sigma = adjusted_eumelanin*color(0.419, 0.697, 1.37) + adjusted_pheomelanin*color(0.187, 0.4, 1.05);
- float roughness_fac = (((((0.245*adjusted_radial_roughness) + 5.574)*adjusted_radial_roughness - 10.73)*adjusted_radial_roughness + 2.532)*adjusted_radial_roughness - 0.215)*adjusted_radial_roughness + 5.969;
- color tint_sigma = log3(Tint)/roughness_fac;
+ color melanin_sigma = sigma_from_concentration(adjusted_eumelanin, adjusted_pheomelanin);
+ color tint_sigma = sigma_from_reflectance(Tint, adjusted_radial_roughness);
tint_sigma *= tint_sigma;
sigma = melanin_sigma + tint_sigma;
}
else if (parametrization == "Direct coloring"){
- float roughness_fac = (((((0.245*adjusted_radial_roughness) + 5.574)*adjusted_radial_roughness - 10.73)*adjusted_radial_roughness + 2.532)*adjusted_radial_roughness - 0.215)*adjusted_radial_roughness + 5.969;
- sigma = log3(Color)/roughness_fac;
+ sigma = sigma_from_reflectance(Color, adjusted_radial_roughness);
sigma *= sigma;
}
else {
// Falling back to Benedikt Bitterli's brownish hair with Tungsten (via PHEOmelanin concentration)
// This gives the exact amount set as default above
- sigma = 0.0*color(0.419, 0.697, 1.37) + 1.3*color(0.187, 0.4, 1.05);
+ sigma = sigma_from_concentration(0.0, 0.8054375);
}
//printf("Info: color %f, incoming eumelanin %f, incoming pheomelanin %f, incoming sigma %f, incoming color range %f, incoming normal %f, parametrization %s, resulting sigma %f, Longitudinal %f, Azimuthal %f, roughness range %f, Scale deviation %f, IOR %f\n", Color, Melanin, MelaninRedness, AbsorptionCoefficient, Normal, parametrization, sigma, RandomColor, Roughness, RadialRoughness, RandomRoughness, Offset, IOR);
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index c4f27bb5232..0b1d8551dbc 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -16,6 +16,19 @@
CCL_NAMESPACE_BEGIN
+/* Helper functions */
+
+ccl_device_inline float3 sigma_from_concentration(float eumelanin, float pheomelanin)
+{
+ return eumelanin*make_float3(0.506f, 0.841f, 1.653f) + pheomelanin*make_float3(0.343f, 0.733f, 1.924f);
+}
+
+ccl_device_inline float3 sigma_from_reflectance(float3 color, float azimuthal_roughness)
+{
+ float roughness_fac = (((((0.245f*azimuthal_roughness) + 5.574f)*azimuthal_roughness - 10.73f)*azimuthal_roughness + 2.532f)*azimuthal_roughness - 0.215f)*azimuthal_roughness + 5.969f;
+ return log3(color) / roughness_fac;
+}
+
/* Closure Nodes */
ccl_device void svm_node_glass_setup(ShaderData *sd, MicrofacetBsdf *bsdf, int type, float eta, float roughness, bool refract)
@@ -787,30 +800,30 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bsdf->sigma = absorption_coefficient;
break;
case NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION: {
- // Benedikt Bitterli's melanin ratio remapping.
+ // Benedikt Bitterli's melanin ratio remapping (adjusted for linearity).
+ melanin_qty = -logf(fmaxf(1.0 - melanin_qty, 0.0001));
float eumelanin = melanin_qty*(1.0f-melanin_ratio);
float pheomelanin = melanin_qty*melanin_ratio;
float factor_random_color = 1.0f + 2.0f*(random - 0.5f)*random_color;
eumelanin *= factor_random_color;
pheomelanin *= factor_random_color;
- float3 melanin_sigma = eumelanin*make_float3(0.419f, 0.697f, 1.37f) + pheomelanin*make_float3(0.187f, 0.4f, 1.05f);
- float roughness_fac = (((((0.245f*param2) + 5.574f)*param2 - 10.73f)*param2 + 2.532f)*param2 - 0.215f)*param2 + 5.969f;
- float3 tint_sigma = log3(tint)/roughness_fac;
+ float3 melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin);
+ float3 tint_sigma = sigma_from_reflectance(tint, param2);
tint_sigma *= tint_sigma;
bsdf->sigma = melanin_sigma+tint_sigma;
break;
}
case NODE_PRINCIPLED_HAIR_REFLECTANCE: {
- float roughness_fac = (((((0.245f*param2) + 5.574f)*param2 - 10.73f)*param2 + 2.532f)*param2 - 0.215f)*param2 + 5.969f;
- bsdf->sigma = log3(color)/roughness_fac;
+ bsdf->sigma = sigma_from_reflectance(color, param2);
bsdf->sigma *= bsdf->sigma;
break;
}
default: {
kernel_assert(!"Invalid Principled Hair parametrization!");
// Falling back to Benedikt Bitterli's brownish hair with Tungsten (via PHEOmelanin concentration)
- bsdf->sigma = 0.0f*make_float3(0.419f, 0.697f, 1.37f) + 1.3f*make_float3(0.187f, 0.4f, 1.05f);
+ // Original mapping: 1.3 -> Blender's mapping: 0.8054375
+ bsdf->sigma = sigma_from_concentration(0.0f, 0.8054375f);
break;
}
}
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index b2deb4bd2ab..684f17def9a 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -3068,8 +3068,8 @@ NODE_DEFINE(PrincipledHairBsdfNode)
NodeType* type = NodeType::add("principled_hair_bsdf", create, NodeType::SHADER);
// Initialize all sockets to their default values.
- SOCKET_IN_COLOR(color, "Color", make_float3(0.09292f, 0.02100f, 0.00417f));
- SOCKET_IN_FLOAT(melanin, "Melanin", 1.3f);
+ SOCKET_IN_COLOR(color, "Color", make_float3(0.017513f, 0.005763f, 0.002059f));
+ SOCKET_IN_FLOAT(melanin, "Melanin", 0.8f);
SOCKET_IN_FLOAT(melanin_redness, "Melanin Redness", 1.0f);
SOCKET_IN_COLOR(tint, "Tint", make_float3(1.f, 1.f, 1.f));
SOCKET_IN_FLOAT(random_color, "Random Color", 0.0f);
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c
index 1b2a86c0a4e..d1621c16a08 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c
@@ -31,8 +31,8 @@
static bNodeSocketTemplate sh_node_bsdf_hair_principled_in[] = {
// This value was chosen empirically from rendering Bitterli's hair
- { SOCK_RGBA, 1, N_("Color"), 0.09292f, 0.02100f, 0.00417f, 1.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 1, N_("Melanin"), 1.3f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f},
+ { SOCK_RGBA, 1, N_("Color"), 0.017513f, 0.005763f, 0.002059f, 1.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Melanin"), 0.8f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_FLOAT, 1, N_("Melanin Redness"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_RGBA, 1, N_("Tint"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
// Benedikt Bitterli's default brownish hair with PHEOmelanin
More information about the Bf-blender-cvs
mailing list