[Bf-blender-cvs] [40bc1a5cddf] soc-2018-hair-shader: GSoC 2018: port Lukas Stockner's hair patch

L. E. Segovia noreply at git.blender.org
Mon May 14 20:47:43 CEST 2018


Commit: 40bc1a5cddf261bdb428a3d07819487b376a6151
Author: L. E. Segovia
Date:   Mon May 14 18:38:34 2018 +0000
Branches: soc-2018-hair-shader
https://developer.blender.org/rB40bc1a5cddf261bdb428a3d07819487b376a6151

GSoC 2018: port Lukas Stockner's hair patch

Still missing:
 - some SSE ops which he disabled (I don't know why, so I didn't add
 that)
 - in svm_tex_coord, he invalidated NODE_TEXCO_WINDOW initialization (I
 don't know why again)
 - no change of util_color.h ops
 - no change of nodeitems_builtin.py (XCode didn't find it in the
 project)

Ref T54796

===================================================================

M	intern/cycles/blender/blender_shader.cpp
M	intern/cycles/kernel/closure/bsdf.h
A	intern/cycles/kernel/closure/bsdf_hair_principled.h
M	intern/cycles/kernel/geom/geom_curve.h
M	intern/cycles/kernel/geom/geom_curve_intersect.h
M	intern/cycles/kernel/kernel_volume.h
M	intern/cycles/kernel/svm/svm_closure.h
M	intern/cycles/kernel/svm/svm_types.h
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h
M	intern/cycles/util/util_math.h
M	intern/cycles/util/util_math_float3.h
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.c
M	source/blender/editors/space_node/drawnode.c
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_shader.h
M	source/blender/nodes/NOD_static_types.h
A	source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c

===================================================================

diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index eb9968a85c2..5bf4a4c406b 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -524,6 +524,12 @@ static ShaderNode *add_node(Scene *scene,
 		}
 		node = hair;
 	}
+    else if(b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) {
+        BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node);
+        PrincipledHairBsdfNode *principled_hair = new PrincipledHairBsdfNode();
+        principled_hair->parametrization = (NodePrincipledHairParametrization) get_enum(b_principled_hair_node.ptr, "parametrization", NODE_PRINCIPLED_HAIR_NUM, NODE_PRINCIPLED_HAIR_COLOR);
+        node = principled_hair;
+    }
 	else if(b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) {
 		BL::ShaderNodeBsdfPrincipled b_principled_node(b_node);
 		PrincipledBsdfNode *principled = new PrincipledBsdfNode();
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index d8ff69ca241..0f6d7450003 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -27,6 +27,7 @@
 #include "kernel/closure/bsdf_ashikhmin_shirley.h"
 #include "kernel/closure/bsdf_toon.h"
 #include "kernel/closure/bsdf_hair.h"
+#include "kernel/closure/bsdf_hair_principled.h"
 #include "kernel/closure/bsdf_principled_diffuse.h"
 #include "kernel/closure/bsdf_principled_sheen.h"
 #include "kernel/closure/bssrdf.h"
@@ -171,6 +172,9 @@ ccl_device_forceinline int bsdf_sample(KernelGlobals *kg,
 			label = bsdf_hair_transmission_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
 				eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
 			break;
+        case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
+            label = bsdf_principled_hair_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+            break;
 #ifdef __PRINCIPLED__
 		case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
 		case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
@@ -220,7 +224,10 @@ float3 bsdf_eval(KernelGlobals *kg,
 {
 	float3 eval;
 
-	if(dot(sd->Ng, omega_in) >= 0.0f) {
+    if(sc->type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) {
+        eval = bsdf_principled_hair_eval(sd, sc, omega_in, pdf);
+    }
+    else if(dot(sd->Ng, omega_in) >= 0.0f) {
 		switch(sc->type) {
 			case CLOSURE_BSDF_DIFFUSE_ID:
 			case CLOSURE_BSDF_BSSRDF_ID:
diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h
new file mode 100644
index 00000000000..1ab99be7a1f
--- /dev/null
+++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h
@@ -0,0 +1,404 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of Sony Pictures Imageworks nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef __KERNEL_CPU__
+#include <fenv.h>
+#endif
+
+#ifndef __BSDF_HAIR_PRINCIPLED_H__
+#define __BSDF_HAIR_PRINCIPLED_H__
+
+CCL_NAMESPACE_BEGIN
+
+typedef ccl_addr_space struct PrincipledHairBSDF {
+	SHADER_CLOSURE_BASE;
+
+	float3 sigma;
+	float4 geom;
+	float v;
+	float s;
+	float alpha;
+	float eta;
+} PrincipledHairBSDF;
+
+static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairBSDF), "PrincipledHairBSDF is too large!");
+
+ccl_device_inline float cos_from_sin(const float s)
+{
+	return safe_sqrtf(1.0f - s*s);
+}
+
+/* Gives the change in direction in the normal plane for the given angles and p-th-order scattering. */
+ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t) {
+	return 2.0f*(p * (gamma_t + M_PI_2_F) - gamma_o);
+}
+
+ccl_device_inline float wrap_angle(float a)
+{
+	while(a > M_PI_F) a -= M_2PI_F;
+	while(a < -M_PI_F) a += M_2PI_F;
+	return a;
+}
+
+ccl_device_inline float logistic(float x, float s)
+{
+	float v = expf(-fabsf(x)/s);
+	return v / (s * sqr(1.0f + v));
+}
+
+ccl_device_inline float logistic_cdf(float x, float s)
+{
+	float arg = -x/s;
+	if(arg > 100.0f) return 0.0f;
+	return 1.0f / (1.0f + expf(arg));
+}
+
+ccl_device_inline float bessel_I0(float x)
+{
+	x = sqr(x);
+	float val = 1.0f + 0.25f*x;
+	float pow_x_2i = sqr(x);
+	uint64_t i_fac_2 = 1;
+	int pow_4_i = 16;
+	for(int i = 2; i < 10; i++) {
+		i_fac_2 *= i*i;
+		float newval = val + pow_x_2i / (pow_4_i * i_fac_2);
+		if(val == newval) return val;
+		val = newval;
+		pow_x_2i *= x;
+		pow_4_i *= 4;
+	}
+	return val;
+}
+
+ccl_device_inline float log_bessel_I0(float x)
+{
+	if (x > 12.0f) {
+		return x + 0.5f * (1.f / (8.0f * x) - M_LN_2PI_F - logf(x));
+	}
+	else {
+		return logf(bessel_I0(x));
+	}
+}
+
+/* Logistic distribution limited to the interval from -pi to pi. */
+ccl_device_inline float trimmed_logistic(float x, float s)
+{
+	/* The logistic distribution is symmetric and centered around zero,
+	 * so logistic_cdf(x, s) = 1 - logistic_cdf(-x, s).
+	 * Therefore, logistic_cdf(x, s)-logistic_cdf(-x, s) = 1 - 2*logistic_cdf(-x, s) */
+	float scaling_fac = 1.0f - 2.0f*logistic_cdf(-M_PI_F, s);
+	float val = logistic(x, s);
+	return val / scaling_fac;
+}
+
+ccl_device_inline float sample_trimmed_logistic(float u, float s)
+{
+	float cdf_minuspi = logistic_cdf(-M_PI_F, s);
+	float x = -s*logf(1.0f / (u*(1.0f - 2.0f*cdf_minuspi) + cdf_minuspi) - 1.0f);
+	return clamp(x, -M_PI_F, M_PI_F);
+}
+
+ccl_device_inline float azimuthal_scattering(float phi, int p, float s, float gamma_o, float gamma_t)
+{
+	float phi_o = wrap_angle(phi - delta_phi(p, gamma_o, gamma_t));
+	float val = trimmed_logistic(phi_o, s);
+	//printf("Azi Phi %f Val %f\n", (double)phi_o, (double)val);
+	return val;
+}
+
+ccl_device_inline float longitudinal_scattering(float sin_theta_i, float cos_theta_i, float sin_theta_o, float cos_theta_o, float v)
+{
+	float inv_v = 1.0f/v;
+	float cos_arg = cos_theta_i * cos_theta_o * inv_v;
+	float sin_arg = sin_theta_i * sin_theta_o * inv_v;
+	if(v <= 0.1f) {
+		float i0 = log_bessel_I0(cos_arg);
+		float val = expf(i0 - sin_arg - inv_v + 0.6931f + logf(0.5f*inv_v));
+		//printf("Long LogI0 %f val %f\n", (double)i0, (double)val);
+		return val;
+	}
+	else {
+		float i0 = bessel_I0(cos_arg);
+		float val = (expf(-sin_arg) * i0) / (sinhf(inv_v) * 2.0f * v);
+		//printf("Long I0 %f val %f\n", (double)i0, (double)val);
+		return val;
+	}
+}
+
+ccl_device_inline float4 combine_with_energy(float3 c)
+{
+	return make_float4(c.x, c.y, c.z, linear_rgb_to_gray(c));
+}
+
+ccl_device int bsdf_principled_hair_setup(KernelGlobals *kg, ShaderData *sd, PrincipledHairBSDF *bsdf)
+{
+	if((sd->type & PRIMITIVE_ALL_CURVE) == 0) {
+		bsdf->type = CLOSURE_BSDF_DIFFUSE_ID;
+		return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_NEEDS_LCG;
+	}
+
+	bsdf->type = CLOSURE_BSDF_HAIR_PRINCIPLED_ID;
+	bsdf->v = clamp(bsdf->v, 0.001f, 0.999f);
+	bsdf->s = clamp(bsdf->s, 0.001f, 0.999f);
+
+	bsdf->v = sqr(0.726f*bsdf->v + 0.812f*sqr(bsdf->v) + 3.700f*pow20(bsdf->v));
+	bsdf->s =    (0.265f*bsdf->s + 1.194f*sqr(bsdf->s) + 5.372f*pow22(bsdf->s))*M_SQRT_PI_8_F;
+
+	float3 dPdCD, curve_P;
+	float h = curve_core_distance(kg, sd, &curve_P, &dPdCD);
+	dPdCD = normalize(dPdCD);
+	bsdf->geom = make_float4(dPdCD.x, dPdCD.y, dPdCD.z, h);
+
+	return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_NEEDS_LCG;
+}
+
+ccl_device_inline void hair_ap(float f, float3 T, float4 *Ap)
+{
+	Ap[0] = make_float4(f, f, f, f);
+	float3 col = sqr(1.0f - f) * T;
+	Ap[1] = combine_with_energy(col);
+	col *= T*f;
+	Ap[2] = combine_with_energy(col);
+	col *= T*f;
+	Ap[3] = combine_with_energy(col / (make_float3(1.0f, 1.0f, 1.0f) - T*f));
+
+	float fac = 1.0f / (Ap[0].w + Ap[1].w + Ap[2].w + Ap[3].w);
+	Ap[0].w *= fac;
+	Ap[1].w *= fac;
+	Ap[2].w *= fac;
+	Ap[3].w *= fac;
+}
+
+ccl_device_inline void hair_alpha_angles(float sin_theta_i, float cos_theta_i, float alpha, float *angles)
+{
+	float sin_1alpha = sinf(alpha);
+	float cos_1alpha = cos_from_sin(sin_1alpha);
+	float sin_2alpha = 2.0f*sin_1alpha*cos_1alpha;
+	float cos_2alpha = sqr(cos_1alpha) - sqr(sin_1alpha);
+	float sin_4alpha = 2.0f*sin_2alpha*cos_2alpha;
+	float cos_4alpha = sqr(cos_2alpha) - sqr(sin_2alpha);
+
+	angles[0] = sin_theta_i*cos_2alpha + cos_theta_i*sin_2alpha;
+	angles[1] = fabsf(cos_theta_i*cos_2alpha - sin_theta_i*sin_2alpha);
+	angles[2] = sin_theta_i*cos_1alpha - cos_theta_i*sin_1alpha;
+	angles[3] = fabsf(cos_theta_i*cos_1alpha + sin_theta_i*sin_1alpha);
+	angles[4] = sin_theta_i*cos_4alpha - cos_theta_i*sin_4alpha;
+	angles[5] = fabsf(cos_theta_i*cos_4alpha + sin_theta_i*sin_4alpha);
+}
+
+ccl_device float3 bsdf_principled_hair_eval(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
+{
+	//*pdf = 0.0f;
+	//return make_float3(0.0f, 0.0f, 0.0f);
+
+	const PrincipledHairBSDF *bs

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list