[Bf-blender-cvs] [1fe1e742a6f] gsoc-2018-many-light-sampling: Cycles: WIP: Volumes are not using the light tree.

Erik Englesson noreply at git.blender.org
Fri Jul 27 18:19:51 CEST 2018


Commit: 1fe1e742a6f27a051c98025898ca61a536cb477f
Author: Erik Englesson
Date:   Tue Jul 24 13:06:58 2018 +0200
Branches: gsoc-2018-many-light-sampling
https://developer.blender.org/rB1fe1e742a6f27a051c98025898ca61a536cb477f

Cycles: WIP: Volumes are not using the light tree.

If a shading point is inside or on the boundary of a volume
then it will use the old sampling method until we have
properly implemented the volume parts of the paper.

Also, the PDF picking probability for volumes have now been
updated properly since the PDF restructure.

Tried to provide the correct shading point and normal to
the MIS calculations. This part needs more work.

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

M	intern/cycles/kernel/kernel_bake.h
M	intern/cycles/kernel/kernel_emission.h
M	intern/cycles/kernel/kernel_light.h
M	intern/cycles/kernel/kernel_path.h
M	intern/cycles/kernel/kernel_path_branched.h
M	intern/cycles/kernel/kernel_path_surface.h
M	intern/cycles/kernel/kernel_path_volume.h
M	intern/cycles/kernel/split/kernel_direct_lighting.h
M	intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h

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

diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index f68afb117a9..107c308e80f 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -68,7 +68,8 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
 
 		/* sample emission */
 		if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
-			float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
+			bool is_volume_boundary = (state.volume_bounce > 0) || (state.volume_bounds_bounce > 0);
+			float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf, ray.P, sd->N, is_volume_boundary); // todo: is this the correct P and N?
 			path_radiance_accum_emission(&L_sample, &state, throughput, emission);
 		}
 
@@ -119,7 +120,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
 				state.ray_t = 0.0f;
 #endif
 				/* compute indirect light */
-				kernel_path_indirect(kg, &indirect_sd, &emission_sd, &ray, sd->N, throughput, &state, &L_sample);
+				kernel_path_indirect(kg, &indirect_sd, &emission_sd, &ray, sd->N, throughput, &state, &L_sample); // todo: is this correct P and N?
 
 				/* sum and reset indirect light pass variables for the next samples */
 				path_radiance_sum_indirect(&L_sample);
@@ -138,7 +139,8 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
 
 		/* sample emission */
 		if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
-			float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
+			bool is_volume_boundary = (state.volume_bounce > 0) || (state.volume_bounds_bounce > 0);
+			float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf, ray.P, sd->N, is_volume_boundary); // todo: is this correct P and N?
 			path_radiance_accum_emission(&L_sample, &state, throughput, emission);
 		}
 
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index f3693638292..9d8e38dc458 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -198,7 +198,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg,
 
 /* Indirect Primitive Emission */
 
-ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
+ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf, float3 P, float3 N, bool is_volume_boundary)
 {
 	/* evaluate emissive closure */
 	float3 L = shader_emissive_eval(kg, sd);
@@ -212,7 +212,7 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader
 		/* multiple importance sampling, get triangle light pdf,
 		 * and compute weight with respect to BSDF pdf */
 		float pdf = triangle_light_pdf(kg, sd, t);
-		pdf *= light_distribution_pdf(kg, sd->P, sd->N, sd->prim);
+		pdf *= light_distribution_pdf(kg, P, N, sd->prim, is_volume_boundary);
 		float mis_weight = power_heuristic(bsdf_pdf, pdf);
 
 		return L*mis_weight;
@@ -260,6 +260,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg,
 		                                ls.t,
 		                                ray->time);
 
+		bool is_inside_volume = false;
 #ifdef __VOLUME__
 		if(state->volume_stack[0].shader != SHADER_NONE) {
 			/* shadow attenuation */
@@ -269,6 +270,10 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg,
 			kernel_volume_shadow(kg, emission_sd, state, &volume_ray, &volume_tp);
 			L *= volume_tp;
 		}
+
+		if((state->volume_bounce > 0 || (state->volume_bounds_bounce > 0)) && (emission_sd->flag & SD_HAS_VOLUME)) {
+			is_inside_volume = true;
+		}
 #endif
 
 		if(!(state->flag & PATH_RAY_MIS_SKIP)) {
@@ -276,7 +281,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg,
 			 * and compute weight with respect to BSDF pdf */
 
 			/* multiply with light picking probablity to pdf */
-			ls.pdf *= light_distribution_pdf(kg, ray->P, N, ~ls.lamp);
+			ls.pdf *= light_distribution_pdf(kg, ray->P, N, ~ls.lamp, is_inside_volume);
 			float mis_weight = power_heuristic(state->ray_pdf, ls.pdf);
 			L *= mis_weight;
 		}
@@ -323,6 +328,16 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg,
 	path_state_modify_bounce(state, false);
 
 #ifdef __BACKGROUND_MIS__
+
+	/* todo: looks like this only happens for volume boundaries and not inside.
+	 * is this expected? */
+	bool is_on_volume_boundary = false;
+#ifdef __VOLUME__
+	if((state->volume_bounce > 0) || (state->volume_bounds_bounce > 0)) {
+		is_on_volume_boundary = true;
+	}
+#endif
+
 	/* check if background light exists or if we should skip pdf */
 	int res_x = kernel_data.integrator.pdf_background_res_x;
 
@@ -331,7 +346,7 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg,
 		 * direction, and compute weight with respect to BSDF pdf */
 		float pdf = background_light_pdf(kg, ray->P, ray->D);
 		int background_index = kernel_data.integrator.background_light_index;
-		pdf *= light_distribution_pdf(kg, ray->P, N, ~background_index);
+		pdf *= light_distribution_pdf(kg, ray->P, N, ~background_index, is_on_volume_boundary);
 		float mis_weight = power_heuristic(state->ray_pdf, pdf);
 
 		return L*mis_weight;
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index af8127a08a6..abad0886727 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -1400,7 +1400,7 @@ ccl_device float light_bvh_pdf(KernelGlobals *kg, float3 P, float3 N,
 
 /* computes the the probability of picking the given light out of all lights */
 ccl_device float light_distribution_pdf(KernelGlobals *kg, float3 P, float3 N,
-                                        int prim_id)
+                                        int prim_id, bool is_inside_volume)
 {
 	/* convert from triangle/lamp to light distribution */
 	int distribution_id;
@@ -1415,8 +1415,7 @@ ccl_device float light_distribution_pdf(KernelGlobals *kg, float3 P, float3 N,
 	              (distribution_id < kernel_data.integrator.num_distribution));
 
 	/* compute picking pdf for this light */
-	if (kernel_data.integrator.use_light_bvh){
-
+	if (kernel_data.integrator.use_light_bvh && !is_inside_volume){
 		/* find out which group of lights to sample */
 		int group;
 		if(prim_id >= 0){
@@ -1457,10 +1456,10 @@ ccl_device float light_distribution_pdf(KernelGlobals *kg, float3 P, float3 N,
 
 /* picks a light and returns its index and the probability of picking it */
 ccl_device void light_distribution_sample(KernelGlobals *kg, float3 P, float3 N,
-                                          float *randu, int *index, float *pdf)
+                                          bool is_in_volume, float *randu,
+                                          int *index, float *pdf)
 {
-	if (kernel_data.integrator.use_light_bvh){
-
+	if (kernel_data.integrator.use_light_bvh && !is_in_volume){
 		/* sample light type distribution */
 		int   group      = light_group_distribution_sample(kg, randu);
 		float group_prob = kernel_tex_fetch(__light_group_sample_prob, group);
@@ -1528,12 +1527,13 @@ ccl_device_noinline bool light_sample(KernelGlobals *kg,
                                       float3 P,
                                       float3 N,
                                       int bounce,
-                                      LightSample *ls)
+                                      LightSample *ls,
+                                      bool is_in_volume)
 {
 	/* sample index and compute light picking pdf */
 	float pdf_factor = 0.0f;
 	int index = -1;
-	light_distribution_sample(kg, P, N, &randu, &index, &pdf_factor);
+	light_distribution_sample(kg, P, N, is_in_volume, &randu, &index, &pdf_factor);
 
 	if(pdf_factor == 0.0f){
 		return false;
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 3605faaf65f..a9235e5f446 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -275,6 +275,7 @@ ccl_device_forceinline bool kernel_path_shader_apply(
 	ShaderData *sd,
 	ccl_addr_space PathState *state,
 	ccl_addr_space Ray *ray,
+	float3 MIS_N,
 	float3 throughput,
 	ShaderData *emission_sd,
 	PathRadiance *L,
@@ -288,7 +289,7 @@ ccl_device_forceinline bool kernel_path_shader_apply(
 
 			float3 bg = make_float3(0.0f, 0.0f, 0.0f);
 			if(!kernel_data.background.transparent) {
-				bg = indirect_background(kg, emission_sd, sd->N, state, ray);
+				bg = indirect_background(kg, emission_sd, MIS_N, state, ray);
 			}
 			path_radiance_accum_shadowcatcher(L, throughput, bg);
 		}
@@ -341,7 +342,8 @@ ccl_device_forceinline bool kernel_path_shader_apply(
 #ifdef __EMISSION__
 	/* emission */
 	if(sd->flag & SD_EMISSION) {
-		float3 emission = indirect_primitive_emission(kg, sd, sd->ray_length, state->flag, state->ray_pdf);
+		bool is_volume_boundary = (state->volume_bounce > 0) || (state->volume_bounds_bounce > 0);
+		float3 emission = indirect_primitive_emission(kg, sd, sd->ray_length, state->flag, state->ray_pdf, ray->P, MIS_N, is_volume_boundary);
 		path_radiance_accum_emission(L, state, throughput, emission);
 	}
 #endif  /* __EMISSION__ */
@@ -412,6 +414,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
 
 	/* path iteration */
 	for(;;) {
+
 		/* Find intersection with objects in scene. */
 		Intersection isect;
 		bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
@@ -437,6 +440,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
 		else if(result == VOLUME_PATH_MISSED) {
 			break;
 		}
+
 #endif /* __VOLUME__*/
 
 		/* Shade background. */
@@ -450,7 +454,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
 
 		/* Setup shader data. */
 		shader_setup_from_ray(kg, sd, &isect, ray);
-		N = sd->N;
+
 		/* Skip most work for volume bounding surface. */
 #ifdef __VOLUME__
 		if(!(sd->flag & SD_HAS_ONLY_VOLUME)) {
@@ -465,6 +469,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
 		                             sd,
 		                             state,
 		                          

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list