| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright 2017 Blender Foundation | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CCL_NAMESPACE_BEGIN | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef __SUBSURFACE__
 | 
					
						
							|  |  |  | #  ifndef __KERNEL_CUDA__
 | 
					
						
							|  |  |  | ccl_device | 
					
						
							|  |  |  | #  else
 | 
					
						
							|  |  |  | ccl_device_inline | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | bool kernel_path_subsurface_scatter( | 
					
						
							|  |  |  |         KernelGlobals *kg, | 
					
						
							|  |  |  |         ShaderData *sd, | 
					
						
							|  |  |  |         ShaderData *emission_sd, | 
					
						
							|  |  |  |         PathRadiance *L, | 
					
						
							|  |  |  |         ccl_addr_space PathState *state, | 
					
						
							|  |  |  |         ccl_addr_space Ray *ray, | 
					
						
							|  |  |  |         ccl_addr_space float3 *throughput, | 
					
						
							|  |  |  |         ccl_addr_space SubsurfaceIndirectRays *ss_indirect) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-29 02:06:30 +01:00
										 |  |  | 	PROFILING_INIT(kg, PROFILING_SUBSURFACE); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-14 22:56:32 +02:00
										 |  |  | 	float bssrdf_u, bssrdf_v; | 
					
						
							|  |  |  | 	path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const ShaderClosure *sc = shader_bssrdf_pick(sd, throughput, &bssrdf_u); | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* do bssrdf scatter step if we picked a bssrdf closure */ | 
					
						
							|  |  |  | 	if(sc) { | 
					
						
							|  |  |  | 		/* We should never have two consecutive BSSRDF bounces,
 | 
					
						
							|  |  |  | 		 * the second one should be converted to a diffuse BSDF to | 
					
						
							|  |  |  | 		 * avoid this. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2017-08-23 03:57:27 +02:00
										 |  |  | 		kernel_assert(!(state->flag & PATH_RAY_DIFFUSE_ANCESTOR)); | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 23:16:25 +02:00
										 |  |  | 		uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb); | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 20:25:08 +01:00
										 |  |  | 		LocalIntersection ss_isect; | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 		int num_hits = subsurface_scatter_multi_intersect(kg, | 
					
						
							|  |  |  | 		                                                  &ss_isect, | 
					
						
							|  |  |  | 		                                                  sd, | 
					
						
							| 
									
										
										
										
											2018-01-21 14:04:22 +01:00
										 |  |  | 		                                                  state, | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 		                                                  sc, | 
					
						
							|  |  |  | 		                                                  &lcg_state, | 
					
						
							|  |  |  | 		                                                  bssrdf_u, bssrdf_v, | 
					
						
							|  |  |  | 		                                                  false); | 
					
						
							|  |  |  | #  ifdef __VOLUME__
 | 
					
						
							| 
									
										
										
										
											2017-08-23 03:57:27 +02:00
										 |  |  | 		bool need_update_volume_stack = | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 		        kernel_data.integrator.use_volumes && | 
					
						
							|  |  |  | 		        sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME; | 
					
						
							|  |  |  | #  endif  /* __VOLUME__ */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-03 17:08:46 +01:00
										 |  |  | 		/* Closure memory will be overwritten, so read required variables now. */ | 
					
						
							|  |  |  | 		Bssrdf *bssrdf = (Bssrdf *)sc; | 
					
						
							|  |  |  | 		ClosureType bssrdf_type = sc->type; | 
					
						
							|  |  |  | 		float bssrdf_roughness = bssrdf->roughness; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 		/* compute lighting with the BSDF closure */ | 
					
						
							|  |  |  | 		for(int hit = 0; hit < num_hits; hit++) { | 
					
						
							|  |  |  | 			/* NOTE: We reuse the existing ShaderData, we assume the path
 | 
					
						
							|  |  |  | 			 * integration loop stops when this function returns true. | 
					
						
							|  |  |  | 			 */ | 
					
						
							|  |  |  | 			subsurface_scatter_multi_setup(kg, | 
					
						
							|  |  |  | 			                               &ss_isect, | 
					
						
							|  |  |  | 			                               hit, | 
					
						
							|  |  |  | 			                               sd, | 
					
						
							|  |  |  | 			                               state, | 
					
						
							| 
									
										
										
										
											2019-01-03 17:08:46 +01:00
										 |  |  | 			                               bssrdf_type, | 
					
						
							|  |  |  | 			                               bssrdf_roughness); | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 03:57:27 +02:00
										 |  |  | 			kernel_path_surface_connect_light(kg, sd, emission_sd, *throughput, state, L); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 			ccl_addr_space PathState *hit_state = &ss_indirect->state[ss_indirect->num_rays]; | 
					
						
							|  |  |  | 			ccl_addr_space Ray *hit_ray = &ss_indirect->rays[ss_indirect->num_rays]; | 
					
						
							|  |  |  | 			ccl_addr_space float3 *hit_tp = &ss_indirect->throughputs[ss_indirect->num_rays]; | 
					
						
							| 
									
										
										
										
											2017-08-23 03:57:27 +02:00
										 |  |  | 			PathRadianceState *hit_L_state = &ss_indirect->L_state[ss_indirect->num_rays]; | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			*hit_state = *state; | 
					
						
							|  |  |  | 			*hit_ray = *ray; | 
					
						
							|  |  |  | 			*hit_tp = *throughput; | 
					
						
							| 
									
										
										
										
											2017-08-23 03:57:27 +02:00
										 |  |  | 			*hit_L_state = L->state; | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			hit_state->rng_offset += PRNG_BOUNCE_NUM; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(kernel_path_surface_bounce(kg, | 
					
						
							|  |  |  | 			                              sd, | 
					
						
							|  |  |  | 			                              hit_tp, | 
					
						
							|  |  |  | 			                              hit_state, | 
					
						
							| 
									
										
										
										
											2017-08-23 03:57:27 +02:00
										 |  |  | 			                              hit_L_state, | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 			                              hit_ray)) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | #  ifdef __LAMP_MIS__
 | 
					
						
							|  |  |  | 				hit_state->ray_t = 0.0f; | 
					
						
							|  |  |  | #  endif  /* __LAMP_MIS__ */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #  ifdef __VOLUME__
 | 
					
						
							| 
									
										
										
										
											2017-08-23 03:57:27 +02:00
										 |  |  | 				if(need_update_volume_stack) { | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 					Ray volume_ray = *ray; | 
					
						
							|  |  |  | 					/* Setup ray from previous surface point to the new one. */ | 
					
						
							|  |  |  | 					volume_ray.D = normalize_len(hit_ray->P - volume_ray.P, | 
					
						
							|  |  |  | 					                             &volume_ray.t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					kernel_volume_stack_update_for_subsurface( | 
					
						
							|  |  |  | 					    kg, | 
					
						
							|  |  |  | 					    emission_sd, | 
					
						
							|  |  |  | 					    &volume_ray, | 
					
						
							|  |  |  | 					    hit_state->volume_stack); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | #  endif  /* __VOLUME__ */
 | 
					
						
							|  |  |  | 				ss_indirect->num_rays++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ccl_device_inline void kernel_path_subsurface_init_indirect( | 
					
						
							|  |  |  |         ccl_addr_space SubsurfaceIndirectRays *ss_indirect) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ss_indirect->num_rays = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ccl_device void kernel_path_subsurface_setup_indirect( | 
					
						
							|  |  |  |         KernelGlobals *kg, | 
					
						
							|  |  |  |         ccl_addr_space SubsurfaceIndirectRays *ss_indirect, | 
					
						
							|  |  |  |         ccl_addr_space PathState *state, | 
					
						
							|  |  |  |         ccl_addr_space Ray *ray, | 
					
						
							|  |  |  |         PathRadiance *L, | 
					
						
							|  |  |  |         ccl_addr_space float3 *throughput) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* Setup state, ray and throughput for indirect SSS rays. */ | 
					
						
							|  |  |  | 	ss_indirect->num_rays--; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 03:57:27 +02:00
										 |  |  | 	path_radiance_sum_indirect(L); | 
					
						
							|  |  |  | 	path_radiance_reset_indirect(L); | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	*state = ss_indirect->state[ss_indirect->num_rays]; | 
					
						
							| 
									
										
										
										
											2017-08-23 03:57:27 +02:00
										 |  |  | 	*ray = ss_indirect->rays[ss_indirect->num_rays]; | 
					
						
							|  |  |  | 	L->state = ss_indirect->L_state[ss_indirect->num_rays]; | 
					
						
							| 
									
										
										
										
											2017-03-08 15:42:26 +01:00
										 |  |  | 	*throughput = ss_indirect->throughputs[ss_indirect->num_rays]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	state->rng_offset += ss_indirect->num_rays * PRNG_BOUNCE_NUM; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif  /* __SUBSURFACE__ */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CCL_NAMESPACE_END |