Cycles / SSS:
authorThomas Dinges <blender@dingto.org>
Tue, 8 Oct 2013 17:07:18 +0000 (17:07 +0000)
committerThomas Dinges <blender@dingto.org>
Tue, 8 Oct 2013 17:07:18 +0000 (17:07 +0000)
* Remove the compatible falloff SSS implementation. We shouldn't support two implementations in the long term, and 2.7x is a good release number do break some compatibility as well.

* Version patch added, so Files with Compatible falloff will automatically use Cubic now.

It was already mentioned in the manual, that Compatible is deprecated.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Shaders#BSSRDF

intern/cycles/blender/blender_shader.cpp
intern/cycles/kernel/kernel_path.h
intern/cycles/kernel/kernel_subsurface.h
intern/cycles/kernel/osl/osl_shader.cpp
intern/cycles/kernel/svm/svm_closure.h
intern/cycles/kernel/svm/svm_types.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_node_types.h
source/blender/makesrna/intern/rna_nodetree.c

index c6c5a4c5dbc4edd8633d8d118b5e03c66791093e..b576181d890f6a150f2c4b79a67bf5e32e20c469 100644 (file)
@@ -322,9 +322,6 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
                SubsurfaceScatteringNode *subsurface = new SubsurfaceScatteringNode();
 
                switch(b_subsurface_node.falloff()) {
-               case BL::ShaderNodeSubsurfaceScattering::falloff_COMPATIBLE:
-                       subsurface->closure = CLOSURE_BSSRDF_COMPATIBLE_ID;
-                       break;
                case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC:
                        subsurface->closure = CLOSURE_BSSRDF_CUBIC_ID;
                        break;
index 5c4e812b4965c1c22fb2f15f4dd5232c7e1ea9d1..5354738d378a674e48fabb78ed870b06bfeda7c2 100644 (file)
@@ -266,14 +266,9 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
                        if(sc) {
                                uint lcg_state = lcg_init(*rng + rng_offset + sample*0x68bc21eb);
 
-                               if(old_subsurface_scatter_use(&sd)) {
-                                       old_subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, false);
-                               }
-                               else {
-                                       float bssrdf_u, bssrdf_v;
-                                       path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
-                                       subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
-                               }
+                               float bssrdf_u, bssrdf_v;
+                               path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+                               subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
 
                                state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
                        }
@@ -664,41 +659,35 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
                        if(sc) {
                                uint lcg_state = lcg_init(*rng + rng_offset + sample*0x68bc21eb);
 
-                               if(old_subsurface_scatter_use(&sd)) {
-                                       old_subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, false);
-                               }
-                               else {
-                                       ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
-                                       float bssrdf_u, bssrdf_v;
-                                       path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
-                                       int num_hits = subsurface_scatter_multi_step(kg, &sd, bssrdf_sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
-
-                                       /* compute lighting with the BSDF closure */
-                                       for(int hit = 0; hit < num_hits; hit++) {
-                                               float3 tp = throughput;
-                                               PathState hit_state = state;
-                                               Ray hit_ray = ray;
-                                               float hit_ray_t = ray_t;
-                                               float hit_ray_pdf = ray_pdf;
-                                               float hit_min_ray_pdf = min_ray_pdf;
-
-                                               hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
-                                               
-                                               if(kernel_path_integrate_lighting(kg, rng, sample, num_samples, &bssrdf_sd[hit],
-                                                       &tp, &hit_min_ray_pdf, &hit_ray_pdf, &hit_state, rng_offset+PRNG_BOUNCE_NUM, &L, &hit_ray, &hit_ray_t)) {
-                                                       kernel_path_indirect(kg, rng, sample, hit_ray, buffer,
-                                                               tp, num_samples, num_samples,
-                                                               hit_min_ray_pdf, hit_ray_pdf, hit_state, rng_offset+PRNG_BOUNCE_NUM*2, &L);
-
-                                                       /* for render passes, sum and reset indirect light pass variables
-                                                        * for the next samples */
-                                                       path_radiance_sum_indirect(&L);
-                                                       path_radiance_reset_indirect(&L);
-                                               }
+                               ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
+                               float bssrdf_u, bssrdf_v;
+                               path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+                               int num_hits = subsurface_scatter_multi_step(kg, &sd, bssrdf_sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
+
+                               /* compute lighting with the BSDF closure */
+                               for(int hit = 0; hit < num_hits; hit++) {
+                                       float3 tp = throughput;
+                                       PathState hit_state = state;
+                                       Ray hit_ray = ray;
+                                       float hit_ray_t = ray_t;
+                                       float hit_ray_pdf = ray_pdf;
+                                       float hit_min_ray_pdf = min_ray_pdf;
+
+                                       hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
+                                       
+                                       if(kernel_path_integrate_lighting(kg, rng, sample, num_samples, &bssrdf_sd[hit],
+                                               &tp, &hit_min_ray_pdf, &hit_ray_pdf, &hit_state, rng_offset+PRNG_BOUNCE_NUM, &L, &hit_ray, &hit_ray_t)) {
+                                               kernel_path_indirect(kg, rng, sample, hit_ray, buffer,
+                                                       tp, num_samples, num_samples,
+                                                       hit_min_ray_pdf, hit_ray_pdf, hit_state, rng_offset+PRNG_BOUNCE_NUM*2, &L);
+
+                                               /* for render passes, sum and reset indirect light pass variables
+                                                * for the next samples */
+                                               path_radiance_sum_indirect(&L);
+                                               path_radiance_reset_indirect(&L);
                                        }
-
-                                       break;
                                }
+                               break;
                        }
                }
 #endif
@@ -1131,17 +1120,6 @@ __device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, int
                                /* do subsurface scatter step with copy of shader data, this will
                                 * replace the BSSRDF with a diffuse BSDF closure */
                                for(int j = 0; j < num_samples; j++) {
-                                       if(old_subsurface_scatter_use(&sd)) {
-                                               ShaderData bssrdf_sd = sd;
-                                               old_subsurface_scatter_step(kg, &bssrdf_sd, state.flag, sc, &lcg_state, true);
-
-                                               /* compute lighting with the BSDF closure */
-                                               kernel_branched_path_integrate_lighting(kg, rng, sample*num_samples + j,
-                                                       aa_samples*num_samples,
-                                                       &bssrdf_sd, throughput, num_samples_inv,
-                                                       ray_pdf, ray_pdf, state, rng_offset, &L, buffer);
-                                       }
-                                       else {
                                                ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
                                                float bssrdf_u, bssrdf_v;
                                                path_rng_2D(kg, &bssrdf_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
@@ -1153,7 +1131,6 @@ __device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, int
                                                                aa_samples*num_samples,
                                                                &bssrdf_sd[hit], throughput, num_samples_inv,
                                                                ray_pdf, ray_pdf, state, rng_offset+PRNG_BOUNCE_NUM, &L, buffer);
-                                       }
                                }
 
                                state.flag &= ~PATH_RAY_BSSRDF_ANCESTOR;
index 4567f2ff0cefa706c900512113dbcc9367d9f327..d16b9328bf24f93e3c11bba8e4a8afb789a68124 100644 (file)
@@ -403,164 +403,5 @@ __device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd,
        subsurface_scatter_setup_diffuse_bsdf(sd, eval, (num_hits > 0), N);
 }
 
-
-/* OLD BSSRDF */
-
-__device float old_bssrdf_sample_distance(KernelGlobals *kg, float radius, float refl, float u)
-{
-       int table_offset = kernel_data.bssrdf.table_offset;
-       float r = lookup_table_read_2D(kg, u, refl, table_offset, BSSRDF_RADIUS_TABLE_SIZE, BSSRDF_REFL_TABLE_SIZE);
-
-       return r*radius;
-}
-
-#ifdef BSSRDF_MULTI_EVAL
-__device float old_bssrdf_pdf(KernelGlobals *kg, float radius, float refl, float r)
-{
-       if(r >= radius)
-               return 0.0f;
-
-       /* todo: when we use the real BSSRDF this will need to be divided by the maximum
-        * radius instead of the average radius */
-       float t = r/radius;
-
-       int table_offset = kernel_data.bssrdf.table_offset + BSSRDF_PDF_TABLE_OFFSET;
-       float pdf = lookup_table_read_2D(kg, t, refl, table_offset, BSSRDF_RADIUS_TABLE_SIZE, BSSRDF_REFL_TABLE_SIZE);
-
-       pdf /= radius;
-
-       return pdf;
-}
-#endif
-
-#ifdef BSSRDF_MULTI_EVAL
-__device float3 old_subsurface_scatter_multi_eval(KernelGlobals *kg, ShaderData *sd, bool hit, float refl, float *r, int num_r, bool all)
-{
-       /* compute pdf */
-       float3 eval_sum = make_float3(0.0f, 0.0f, 0.0f);
-       float pdf_sum = 0.0f;
-       float sample_weight_sum = 0.0f;
-       int num_bssrdf = 0;
-
-       for(int i = 0; i < sd->num_closure; i++) {
-               ShaderClosure *sc = &sd->closure[i];
-               
-               if(CLOSURE_IS_BSSRDF(sc->type)) {
-                       float sample_weight = (all)? 1.0f: sc->sample_weight;
-
-                       /* compute pdf */
-                       float pdf = 1.0f;
-                       for(int i = 0; i < num_r; i++)
-                               pdf *= old_bssrdf_pdf(kg, sc->data0, refl, r[i]);
-
-                       eval_sum += sc->weight*pdf;
-                       pdf_sum += sample_weight*pdf;
-
-                       sample_weight_sum += sample_weight;
-                       num_bssrdf++;
-               }
-       }
-
-       float inv_pdf_sum;
-       
-       if(pdf_sum > 0.0f) {
-               /* in case of branched path integrate we sample all bssrdf's once,
-                * for path trace we pick one, so adjust pdf for that */
-               if(all)
-                       inv_pdf_sum = 1.0f/pdf_sum;
-               else
-                       inv_pdf_sum = sample_weight_sum/pdf_sum;
-       }
-       else
-               inv_pdf_sum = 0.0f;
-
-       float3 weight = eval_sum * inv_pdf_sum;
-
-       return weight;
-}
-#endif
-
-/* subsurface scattering step, from a point on the surface to another nearby point on the same object */
-__device void old_subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, int state_flag, ShaderClosure *sc, uint *lcg_state, bool all)
-{
-       float radius = sc->data0;
-       float refl = max(average(sc->weight)*3.0f, 0.0f);
-       float r = 0.0f;
-       bool hit = false;
-       float3 weight = make_float3(1.0f, 1.0f, 1.0f);
-#ifdef BSSRDF_MULTI_EVAL
-       float r_attempts[BSSRDF_MAX_ATTEMPTS];
-#endif
-       int num_attempts;
-
-       /* attempt to find a hit a given number of times before giving up */
-       for(num_attempts = 0; num_attempts < kernel_data.bssrdf.num_attempts; num_attempts++) {
-               /* random numbers for sampling */
-               float u1 = lcg_step_float(lcg_state);
-               float u2 = lcg_step_float(lcg_state);
-               float u3 = lcg_step_float(lcg_state);
-               float u4 = lcg_step_float(lcg_state);
-               float u5 = lcg_step_float(lcg_state);
-
-               r = old_bssrdf_sample_distance(kg, radius, refl, u5);
-#ifdef BSSRDF_MULTI_EVAL
-               r_attempts[num_attempts] = r;
-#endif
-
-               float3 p1 = sd->P + sample_uniform_sphere(u1, u2)*r;
-               float3 p2 = sd->P + sample_uniform_sphere(u3, u4)*r;
-
-               /* create ray */
-               Ray ray;
-               ray.P = p1;
-               ray.D = normalize_len(p2 - p1, &ray.t);
-               ray.dP = sd->dP;
-               ray.dD = differential3_zero();
-               ray.time = sd->time;
-
-               /* intersect with the same object. if multiple intersections are
-                * found it will randomly pick one of them */
-               Intersection isect;
-               if(scene_intersect_subsurface(kg, &ray, &isect, sd->object, lcg_state, 1) == 0)
-                       continue;
-
-               /* setup new shading point */
-               shader_setup_from_subsurface(kg, sd, &isect, &ray);
-
-               hit = true;
-               num_attempts++;
-               break;
-       }
-
-       /* evaluate subsurface scattering closures */
-#ifdef BSSRDF_MULTI_EVAL
-       weight *= old_subsurface_scatter_multi_eval(kg, sd, hit, refl, r_attempts, num_attempts, all);
-#else
-       weight *= sc->weight;
-#endif
-
-       if(!hit)
-               weight = make_float3(0.0f, 0.0f, 0.0f);
-
-       /* optionally blur colors and bump mapping */
-       float3 N = sd->N;
-       subsurface_color_bump_blur(kg, sd, sd, state_flag, &weight, &N);
-
-       /* replace closures with a single diffuse BSDF */
-       subsurface_scatter_setup_diffuse_bsdf(sd, weight, hit, N);
-}
-
-__device bool old_subsurface_scatter_use(ShaderData *sd)
-{
-       for(int i = 0; i < sd->num_closure; i++) {
-               ShaderClosure *sc = &sd->closure[i];
-               
-               if(sc->type == CLOSURE_BSSRDF_COMPATIBLE_ID)
-                       return true;
-       }
-
-       return false;
-}
-
 CCL_NAMESPACE_END
 
index 625ad263f7f8b7b880c7dea5adc2d9440cf50547..18e8fee43482468817a2b6c583e7fdf329b9e66b 100644 (file)
@@ -253,7 +253,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag,
                                                /* disable in case of diffuse ancestor, can't see it well then and
                                                 * adds considerably noise due to probabilities of continuing path
                                                 * getting lower and lower */
-                                               if(sc.type != CLOSURE_BSSRDF_COMPATIBLE_ID && (path_flag & PATH_RAY_DIFFUSE_ANCESTOR))
+                                               if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
                                                        bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f);
 
                                                /* create one closure for each color channel */
index 6d9c4e215e6f21b08e7a8084e39670e932486b62..0d4716ab078425df781888f476b00af3d324ffe3 100644 (file)
@@ -378,7 +378,6 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
 #endif
 
 #ifdef __SUBSURFACE__
-               case CLOSURE_BSSRDF_COMPATIBLE_ID:
                case CLOSURE_BSSRDF_CUBIC_ID:
                case CLOSURE_BSSRDF_GAUSSIAN_ID: {
                        ShaderClosure *sc = &sd->closure[sd->num_closure];
@@ -388,7 +387,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
                        /* disable in case of diffuse ancestor, can't see it well then and
                         * adds considerably noise due to probabilities of continuing path
                         * getting lower and lower */
-                       if(type != CLOSURE_BSSRDF_COMPATIBLE_ID && (path_flag & PATH_RAY_DIFFUSE_ANCESTOR))
+                       if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
                                param1 = 0.0f;
 
                        if(sample_weight > 1e-5f && sd->num_closure+2 < MAX_CLOSURE) {
index 50daf159f260411b6f215743bb27255d86ceaaae..abd63530d631eb167a565e2b7077aa6bf4009c65 100644 (file)
@@ -377,7 +377,6 @@ typedef enum ClosureType {
        CLOSURE_BSDF_TRANSPARENT_ID,
 
        /* BSSRDF */
-       CLOSURE_BSSRDF_COMPATIBLE_ID,
        CLOSURE_BSSRDF_CUBIC_ID,
        CLOSURE_BSSRDF_GAUSSIAN_ID,
 
@@ -402,7 +401,7 @@ typedef enum ClosureType {
 #define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID)
 #define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)
 #define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID)
-#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_COMPATIBLE_ID && type <= CLOSURE_BSSRDF_GAUSSIAN_ID)
+#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_GAUSSIAN_ID)
 #define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_ISOTROPIC_ID)
 #define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID)
 #define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID)
index 19c1360b6cccba382592b750fef5969652da9499..5b32e7229d50e30801cf5a0348724ae2ba409e5e 100644 (file)
@@ -42,7 +42,7 @@ extern "C" {
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION         269
-#define BLENDER_SUBVERSION      0
+#define BLENDER_SUBVERSION      1
 /* 262 was the last editmesh release but it has compatibility code for bmesh data */
 #define BLENDER_MINVERSION      262
 #define BLENDER_MINSUBVERSION   0
index b673246a38f2b09dcfb39c5cb59e30ebd8ddbc6e..8dc9622393c87f99a0189ee6a7c9ae4e3155f51b 100644 (file)
@@ -9707,6 +9707,22 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        }
                }
        }
+       
+       if (!MAIN_VERSION_ATLEAST(main, 269, 1)) {
+               /* Removal of Cycles SSS Compatible fallof */
+               FOREACH_NODETREE(main, ntree, id) {
+                       if (ntree->type == NTREE_SHADER) {
+                               bNode *node;
+                               for (node = ntree->nodes.first; node; node = node->next) {
+                                       if (node->type == SH_NODE_SUBSURFACE_SCATTERING) {
+                                               if (node->custom1 == SHD_SUBSURFACE_COMPATIBLE) {
+                                                       node->custom1 = SHD_SUBSURFACE_CUBIC;
+                                               }
+                                       }
+                               }
+                       }
+               } FOREACH_NODETREE_END
+       }
 
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
index 5cfe3fd20822d50027babe172b00298e9c819fb4..0ed620c4632fcff15380622dcec4b58994dd2366 100644 (file)
@@ -976,7 +976,7 @@ typedef struct NodeShaderNormalMap {
 #define SHD_NORMAL_MAP_BLENDER_WORLD   4
 
 /* subsurface */
-#define SHD_SUBSURFACE_COMPATIBLE              0
+#define SHD_SUBSURFACE_COMPATIBLE              0 // Deprecated
 #define SHD_SUBSURFACE_CUBIC                   1
 #define SHD_SUBSURFACE_GAUSSIAN                        2
 
index d2f181d41b2389b22a168e63a89e728b749bc172..8ad19735517c8b73923fd925532e95c985394a5d 100644 (file)
@@ -3699,7 +3699,6 @@ static void def_sh_tangent(StructRNA *srna)
 static void def_sh_subsurface(StructRNA *srna)
 {
        static EnumPropertyItem prop_subsurface_falloff_items[] = {
-               {SHD_SUBSURFACE_COMPATIBLE, "COMPATIBLE", 0, "Compatible", "Subsurface scattering falloff compatible with previous versions"},
                {SHD_SUBSURFACE_CUBIC, "CUBIC", 0, "Cubic", "Simple cubic falloff function"},
                {SHD_SUBSURFACE_GAUSSIAN, "GAUSSIAN", 0, "Gaussian", "Normal distribution, multiple can be combined to fit more complex profiles"},
                {0, NULL, 0, NULL, NULL}