[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59471] trunk/blender/intern/cycles: Cycles: reduce noise using regular path tracing + subsurface scattering with
Brecht Van Lommel
brechtvanlommel at pandora.be
Sat Aug 24 17:02:08 CEST 2013
Revision: 59471
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59471
Author: blendix
Date: 2013-08-24 15:02:08 +0000 (Sat, 24 Aug 2013)
Log Message:
-----------
Cycles: reduce noise using regular path tracing + subsurface scattering with
new cubic and gaussian falloff. Like the branched path tracer, this will now
shade all intersection points instead of using one at random.
Modified Paths:
--------------
trunk/blender/intern/cycles/blender/blender_sync.cpp
trunk/blender/intern/cycles/kernel/kernel_path.h
trunk/blender/intern/cycles/kernel/kernel_subsurface.h
trunk/blender/intern/cycles/kernel/kernel_types.h
trunk/blender/intern/cycles/render/osl.cpp
Modified: trunk/blender/intern/cycles/blender/blender_sync.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_sync.cpp 2013-08-24 14:40:15 UTC (rev 59470)
+++ trunk/blender/intern/cycles/blender/blender_sync.cpp 2013-08-24 15:02:08 UTC (rev 59471)
@@ -189,7 +189,7 @@
}
#endif
- integrator->method = (Integrator::Method)get_int(cscene, "progressive");
+ integrator->method = (Integrator::Method)get_enum(cscene, "progressive");
int diffuse_samples = get_int(cscene, "diffuse_samples");
int glossy_samples = get_int(cscene, "glossy_samples");
Modified: trunk/blender/intern/cycles/kernel/kernel_path.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_path.h 2013-08-24 14:40:15 UTC (rev 59470)
+++ trunk/blender/intern/cycles/kernel/kernel_path.h 2013-08-24 15:02:08 UTC (rev 59471)
@@ -231,52 +231,24 @@
return result;
}
-__device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer)
-{
- /* initialize */
- PathRadiance L;
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- float L_transparent = 0.0f;
- path_radiance_init(&L, kernel_data.film.use_light_pass);
+#if defined(__BRANCHED_PATH__) || defined(__BSSRDF__)
- float min_ray_pdf = FLT_MAX;
- float ray_pdf = 0.0f;
+__device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer,
+ float3 throughput, int num_samples, int num_total_samples,
+ float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L)
+{
#ifdef __LAMP_MIS__
float ray_t = 0.0f;
#endif
- PathState state;
- int rng_offset = PRNG_BASE_NUM;
-#ifdef __CMJ__
- int num_samples = kernel_data.integrator.aa_samples;
-#else
- int num_samples = 0;
-#endif
- path_state_init(&state);
-
/* path iteration */
for(;; rng_offset += PRNG_BOUNCE_NUM) {
/* intersect scene */
Intersection isect;
uint visibility = path_state_ray_visibility(kg, &state);
-
#ifdef __HAIR__
- float difl = 0.0f, extmax = 0.0f;
- uint lcg_state = 0;
-
- if(kernel_data.bvh.have_curves) {
- if((kernel_data.cam.resolution == 1) && (state.flag & PATH_RAY_CAMERA)) {
- float3 pixdiff = ray.dD.dx + ray.dD.dy;
- /*pixdiff = pixdiff - dot(pixdiff, ray.D)*ray.D;*/
- difl = kernel_data.curve.minimum_width * len(pixdiff) * 0.5f;
- }
-
- extmax = kernel_data.curve.maximum_width;
- lcg_state = lcg_init(*rng + rng_offset + sample*0x51633e2d);
- }
-
- bool hit = scene_intersect(kg, &ray, visibility, &isect, &lcg_state, difl, extmax);
+ bool hit = scene_intersect(kg, &ray, visibility, &isect, NULL, 0.0f, 0.0f);
#else
bool hit = scene_intersect(kg, &ray, visibility, &isect);
#endif
@@ -295,29 +267,19 @@
light_ray.dP = ray.dP;
/* intersect with lamp */
- float light_t = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT);
+ float light_t = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT);
float3 emission;
if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission, state.bounce))
- path_radiance_accum_emission(&L, throughput, emission, state.bounce);
+ path_radiance_accum_emission(L, throughput, emission, state.bounce);
}
#endif
if(!hit) {
- /* eval background shader if nothing hit */
- if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) {
- L_transparent += average(throughput);
-
-#ifdef __PASSES__
- if(!(kernel_data.film.pass_flag & PASS_BACKGROUND))
-#endif
- break;
- }
-
#ifdef __BACKGROUND__
/* sample background shader */
float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf, state.bounce);
- path_radiance_accum_background(&L, throughput, L_background, state.bounce);
+ path_radiance_accum_background(L, throughput, L_background, state.bounce);
#endif
break;
@@ -326,32 +288,10 @@
/* setup shading */
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce);
- float rbsdf = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF);
- shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
+ float rbsdf = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF);
+ shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_INDIRECT);
+ shader_merge_closures(kg, &sd);
- /* holdout */
-#ifdef __HOLDOUT__
- if((sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK)) && (state.flag & PATH_RAY_CAMERA)) {
- if(kernel_data.background.transparent) {
- float3 holdout_weight;
-
- if(sd.flag & SD_HOLDOUT_MASK)
- holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
- else
- holdout_weight = shader_holdout_eval(kg, &sd);
-
- /* any throughput is ok, should all be identical here */
- L_transparent += average(holdout_weight*throughput);
- }
-
- if(sd.flag & SD_HOLDOUT_MASK)
- break;
- }
-#endif
-
- /* holdout mask objects do not write data passes */
- kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
-
/* blurring of bsdf after bounces, for rays that have a small likelihood
* of following this particular path (diffuse, rough glossy) */
if(kernel_data.integrator.filter_glossy != FLT_MAX) {
@@ -366,22 +306,21 @@
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
- /* todo: is isect.t wrong here for transparent surfaces? */
float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf);
- path_radiance_accum_emission(&L, throughput, emission, state.bounce);
+ path_radiance_accum_emission(L, throughput, emission, state.bounce);
}
#endif
/* path termination. this is a strange place to put the termination, it's
* mainly due to the mixed in MIS that we use. gives too many unneeded
* shader evaluations, only need emission if we are going to terminate */
- float probability = path_state_terminate_probability(kg, &state, throughput);
+ float probability = path_state_terminate_probability(kg, &state, throughput*num_samples);
if(probability == 0.0f) {
break;
}
else if(probability != 1.0f) {
- float terminate = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_TERMINATE);
+ float terminate = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_TERMINATE);
if(terminate >= probability)
break;
@@ -389,38 +328,11 @@
throughput /= probability;
}
-#ifdef __SUBSURFACE__
- /* bssrdf scatter to a different location on the same object, replacing
- * the closures with a diffuse BSDF */
- if(sd.flag & SD_BSSRDF) {
- float bssrdf_probability;
- ShaderClosure *sc = subsurface_scatter_pick_closure(kg, &sd, &bssrdf_probability);
-
- /* modify throughput for picking bssrdf or bsdf */
- throughput *= bssrdf_probability;
-
- /* do bssrdf scatter step if we picked a bssrdf closure */
- 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_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);
- }
- }
- }
-#endif
-
#ifdef __AO__
/* ambient occlusion */
if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
- /* todo: solve correlation */
float bsdf_u, bsdf_v;
- path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v);
+ path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v);
float ao_factor = kernel_data.background.ao_factor;
float3 ao_N;
@@ -444,23 +356,51 @@
light_ray.dD = differential3_zero();
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
- path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce);
+ path_radiance_accum_ao(L, throughput, ao_bsdf, ao_shadow, state.bounce);
}
}
#endif
+#ifdef __SUBSURFACE__
+ /* bssrdf scatter to a different location on the same object, replacing
+ * the closures with a diffuse BSDF */
+ if(sd.flag & SD_BSSRDF) {
+ float bssrdf_probability;
+ ShaderClosure *sc = subsurface_scatter_pick_closure(kg, &sd, &bssrdf_probability);
+
+ /* modify throughput for picking bssrdf or bsdf */
+ throughput *= bssrdf_probability;
+
+ /* do bssrdf scatter step if we picked a bssrdf closure */
+ 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);
+ }
+
+ state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
+ }
+ }
+#endif
+
#ifdef __EMISSION__
if(kernel_data.integrator.use_direct_light) {
/* sample illumination from lights to find path contribution */
if(sd.flag & SD_BSDF_HAS_EVAL) {
- float light_t = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT);
+ float light_t = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT);
#ifdef __MULTI_CLOSURE__
float light_o = 0.0f;
#else
- float light_o = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_F);
+ float light_o = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT_F);
#endif
float light_u, light_v;
- path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v);
+ path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v);
Ray light_ray;
BsdfEval L_light;
@@ -470,13 +410,14 @@
light_ray.time = sd.time;
#endif
+ /* sample random light */
if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
- path_radiance_accum_light(&L, throughput, &L_light, shadow, 1.0f, state.bounce, is_lamp);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list