diff options
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/closure/bssrdf.h | 62 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_bssrdf.cpp | 31 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_bssrdf.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_closures.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_closures.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_shader.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_subsurface_scattering.osl | 9 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/stdosl.h | 7 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_closure.h | 15 |
9 files changed, 104 insertions, 29 deletions
diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h index d6f889f3285..4ceff655dd5 100644 --- a/intern/cycles/kernel/closure/bssrdf.h +++ b/intern/cycles/kernel/closure/bssrdf.h @@ -31,6 +31,7 @@ __device int bssrdf_setup(ShaderClosure *sc, ClosureType type) } else { sc->data1 = clamp(sc->data1, 0.0f, 1.0f); /* texture blur */ + sc->T.x = clamp(sc->T.x, 0.0f, 1.0f); /* sharpness */ sc->type = type; return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSSRDF; @@ -95,17 +96,49 @@ __device void bssrdf_gaussian_sample(ShaderClosure *sc, float xi, float *r, floa __device float bssrdf_cubic_eval(ShaderClosure *sc, float r) { - const float Rm = sc->data0; + const float sharpness = sc->T.x; - if(r >= Rm) - return 0.0f; - - /* integrate (2*pi*r * 10*(R - r)^3)/(pi * R^5) from 0 to R = 1 */ - const float Rm5 = (Rm*Rm) * (Rm*Rm) * Rm; - const float f = Rm - min(r, Rm); - const float f3 = f*f*f; + if(sharpness == 0.0f) { + const float Rm = sc->data0; + + if(r >= Rm) + return 0.0f; + + /* integrate (2*pi*r * 10*(R - r)^3)/(pi * R^5) from 0 to R = 1 */ + const float Rm5 = (Rm*Rm) * (Rm*Rm) * Rm; + const float f = Rm - r; + const float num = f*f*f; + + return (10.0f * num) / (Rm5 * M_PI_F); - return (f3 * 10.0f) / (Rm5 * M_PI_F); + } + else { + float Rm = sc->data0*(1.0f + sharpness); + + if(r >= Rm) + return 0.0f; + + /* custom variation with extra sharpness, to match the previous code */ + const float y = 1.0f/(1.0f + sharpness); + float Rmy, ry, ryinv; + + if(sharpness == 1.0f) { + Rmy = sqrtf(Rm); + ry = sqrtf(r); + ryinv = (ry > 0.0f)? 1.0f/ry: 0.0f; + } + else { + Rmy = powf(Rm, y); + ry = powf(r, y); + ryinv = (r > 0.0f)? powf(r, 2.0f*y - 2.0f): 0.0f; + } + + const float Rmy5 = (Rmy*Rmy) * (Rmy*Rmy) * Rmy; + const float f = Rmy - ry; + const float num = f*(f*f)*(y*ryinv); + + return (10.0f * num) / (Rmy5 * M_PI_F); + } } __device float bssrdf_cubic_pdf(ShaderClosure *sc, float r) @@ -143,9 +176,16 @@ __device float bssrdf_cubic_quintic_root_find(float xi) __device void bssrdf_cubic_sample(ShaderClosure *sc, float xi, float *r, float *h) { - const float Rm = sc->data0; - const float r_ = bssrdf_cubic_quintic_root_find(xi) * Rm; + float Rm = sc->data0; + float r_ = bssrdf_cubic_quintic_root_find(xi); + const float sharpness = sc->T.x; + if(sharpness != 0.0f) { + r_ = powf(r_, 1.0f + sharpness); + Rm *= (1.0f + sharpness); + } + + r_ *= Rm; *r = r_; /* h^2 + r^2 = Rm^2 */ diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp index 7405b0be567..975967c0bbb 100644 --- a/intern/cycles/kernel/osl/osl_bssrdf.cpp +++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp @@ -56,10 +56,8 @@ public: void setup() { - sc.type = CLOSURE_BSSRDF_COMPATIBLE_ID; - sc.prim = NULL; + sc.type = CLOSURE_BSSRDF_CUBIC_ID; sc.data0 = fabsf(average(radius)); - sc.data1 = 0.0f; // XXX texture blur } bool mergeable(const ClosurePrimitive *other) const @@ -85,6 +83,19 @@ ClosureParam *closure_bssrdf_cubic_params() return params; } +ClosureParam *closure_bssrdf_cubic_extended_params() +{ + static ClosureParam params[] = { + CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, sc.N), + CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, radius), + CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.data1), + CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.T.x), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(CubicBSSRDFClosure) + }; + return params; +} + CLOSURE_PREPARE(closure_bssrdf_cubic_prepare, CubicBSSRDFClosure) /* Gaussian */ @@ -97,9 +108,7 @@ public: void setup() { sc.type = CLOSURE_BSSRDF_GAUSSIAN_ID; - sc.prim = NULL; sc.data0 = fabsf(average(radius)); - sc.data1 = 0.0f; // XXX texture blurring! } bool mergeable(const ClosurePrimitive *other) const @@ -125,6 +134,18 @@ ClosureParam *closure_bssrdf_gaussian_params() return params; } +ClosureParam *closure_bssrdf_gaussian_extended_params() +{ + static ClosureParam params[] = { + CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, sc.N), + CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, radius), + CLOSURE_FLOAT_PARAM(GaussianBSSRDFClosure, sc.data1), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(GaussianBSSRDFClosure) + }; + return params; +} + CLOSURE_PREPARE(closure_bssrdf_gaussian_prepare, GaussianBSSRDFClosure) CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_bssrdf.h b/intern/cycles/kernel/osl/osl_bssrdf.h index ee9fc7c4ac5..fc1a4c587cc 100644 --- a/intern/cycles/kernel/osl/osl_bssrdf.h +++ b/intern/cycles/kernel/osl/osl_bssrdf.h @@ -48,7 +48,7 @@ public: ShaderClosure sc; float3 radius; - CBSSRDFClosure() : OSL::ClosurePrimitive(BSSRDF) { } + CBSSRDFClosure() : OSL::ClosurePrimitive(BSSRDF) { memset(&sc, 0, sizeof(sc)); } ~CBSSRDFClosure() { } int scattering() const { return LABEL_DIFFUSE; } diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index c03e50d4313..6a3f27fb7b1 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -221,6 +221,10 @@ void OSLShader::register_closures(OSLShadingSystem *ss_) closure_bssrdf_cubic_params(), closure_bssrdf_cubic_prepare); register_closure(ss, "bssrdf_gaussian", id++, closure_bssrdf_gaussian_params(), closure_bssrdf_gaussian_prepare); + register_closure(ss, "bssrdf_cubic", id++, + closure_bssrdf_cubic_extended_params(), closure_bssrdf_cubic_prepare); + register_closure(ss, "bssrdf_gaussian", id++, + closure_bssrdf_gaussian_extended_params(), closure_bssrdf_gaussian_prepare); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index e3a7e890597..6632c2c57e5 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -52,6 +52,8 @@ OSL::ClosureParam *closure_westin_backscatter_params(); OSL::ClosureParam *closure_westin_sheen_params(); OSL::ClosureParam *closure_bssrdf_cubic_params(); OSL::ClosureParam *closure_bssrdf_gaussian_params(); +OSL::ClosureParam *closure_bssrdf_cubic_extended_params(); +OSL::ClosureParam *closure_bssrdf_gaussian_extended_params(); void closure_emission_prepare(OSL::RendererServices *, int id, void *data); void closure_background_prepare(OSL::RendererServices *, int id, void *data); diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index c55f36bcc9d..d2ccb7da84c 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -239,6 +239,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag, sc.type = bssrdf->sc.type; sc.N = bssrdf->sc.N; sc.data1 = bssrdf->sc.data1; + sc.T.x = bssrdf->sc.T.x; sc.prim = NULL; /* disable in case of diffuse ancestor, can't see it well then and diff --git a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl index 18864118172..5c1d1be0ee7 100644 --- a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl +++ b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl @@ -20,14 +20,15 @@ shader node_subsurface_scattering( color Color = 0.8, float Scale = 1.0, vector Radius = vector(0.1, 0.1, 0.1), - float TextureBlur = 0.0, // XXX use + float TextureBlur = 0.0, + float Sharpness = 0.0, string Falloff = "Cubic", normal Normal = N, output closure color BSSRDF = 0) { if(Falloff == "Gaussian") - BSSRDF = Color * bssrdf_gaussian(N, Scale * Radius); - else /* Cubic, hardcoded to compatible closure for now */ - BSSRDF = Color * bssrdf_cubic(N, Scale * Radius); + BSSRDF = Color * bssrdf_gaussian(N, Scale * Radius, TextureBlur); + else + BSSRDF = Color * bssrdf_cubic(N, Scale * Radius, TextureBlur, Sharpness); } diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index 7d1c2443ee7..3ad2bbc0588 100644 --- a/intern/cycles/kernel/shaders/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -465,11 +465,12 @@ closure color holdout() BUILTIN; closure color ambient_occlusion() BUILTIN; // BSSRDF -closure color bssrdf_cubic(normal N, vector radius) BUILTIN; -closure color bssrdf_gaussian(normal N, vector radius) BUILTIN; +closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN; +closure color bssrdf_gaussian(normal N, vector radius, float texture_blur) BUILTIN; // Backwards compatibility - +closure color bssrdf_cubic(normal N, vector radius) BUILTIN; +closure color bssrdf_gaussian(normal N, vector radius) BUILTIN; closure color specular_toon(normal N, float size, float smooth) BUILTIN; // Renderer state diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 42d98092b41..9a9aefa5b29 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -108,13 +108,13 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st if(mix_weight == 0.0f) return; - float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N; + float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N; #else decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, NULL); float mix_weight = 1.0f; uint4 data_node = read_node(kg, offset); - float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N; + float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N; #endif float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z); @@ -279,10 +279,10 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st sc->N = N; #ifdef __ANISOTROPIC__ - sc->T = stack_load_float3(stack, data_node.z); + sc->T = stack_load_float3(stack, data_node.y); /* rotate tangent */ - float rotation = stack_load_float(stack, data_node.w); + float rotation = stack_load_float(stack, data_node.z); if(rotation != 0.0f) sc->T = rotate_around_axis(sc->T, sc->N, rotation * M_2PI_F); @@ -353,7 +353,9 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st if(sample_weight > 1e-5f && sd->num_closure+2 < MAX_CLOSURE) { /* radius * scale */ - float3 radius = stack_load_float3(stack, data_node.w)*param1; + float3 radius = stack_load_float3(stack, data_node.z)*param1; + /* sharpness */ + float sharpness = stack_load_float(stack, data_node.w); /* texture color blur */ float texture_blur = param2; @@ -363,6 +365,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st sc->sample_weight = sample_weight; sc->data0 = radius.x; sc->data1 = texture_blur; + sc->T.x = sharpness; #ifdef __OSL__ sc->prim = NULL; #endif @@ -378,6 +381,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st sc->sample_weight = sample_weight; sc->data0 = radius.y; sc->data1 = texture_blur; + sc->T.x = sharpness; #ifdef __OSL__ sc->prim = NULL; #endif @@ -393,6 +397,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st sc->sample_weight = sample_weight; sc->data0 = radius.z; sc->data1 = texture_blur; + sc->T.x = sharpness; #ifdef __OSL__ sc->prim = NULL; #endif |