kernel_path_surface.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. /*
  2. * Copyright 2011-2013 Blender Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. CCL_NAMESPACE_BEGIN
  17. #if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__) || defined(__SHADOW_TRICKS__) || \
  18. defined(__BAKING__)
  19. /* branched path tracing: connect path directly to position on one or more lights and add it to L
  20. */
  21. ccl_device_noinline void kernel_branched_path_surface_connect_light(
  22. KernelGlobals *kg,
  23. ShaderData *sd,
  24. ShaderData *emission_sd,
  25. ccl_addr_space PathState *state,
  26. float3 throughput,
  27. float num_samples_adjust,
  28. PathRadiance *L,
  29. int sample_all_lights)
  30. {
  31. # ifdef __EMISSION__
  32. /* sample illumination from lights to find path contribution */
  33. if (!(sd->flag & SD_BSDF_HAS_EVAL))
  34. return;
  35. Ray light_ray;
  36. BsdfEval L_light;
  37. bool is_lamp;
  38. # ifdef __OBJECT_MOTION__
  39. light_ray.time = sd->time;
  40. # endif
  41. if (sample_all_lights) {
  42. /* lamp sampling */
  43. for (int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
  44. if (UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
  45. continue;
  46. int num_samples = ceil_to_int(num_samples_adjust * light_select_num_samples(kg, i));
  47. float num_samples_inv = num_samples_adjust /
  48. (num_samples * kernel_data.integrator.num_all_lights);
  49. uint lamp_rng_hash = cmj_hash(state->rng_hash, i);
  50. for (int j = 0; j < num_samples; j++) {
  51. float light_u, light_v;
  52. path_branched_rng_2D(
  53. kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
  54. float terminate = path_branched_rng_light_termination(
  55. kg, lamp_rng_hash, state, j, num_samples);
  56. LightSample ls;
  57. if (lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) {
  58. /* The sampling probability returned by lamp_light_sample assumes that all lights were
  59. * sampled.
  60. * However, this code only samples lamps, so if the scene also had mesh lights, the real
  61. * probability is twice as high. */
  62. if (kernel_data.integrator.pdf_triangles != 0.0f)
  63. ls.pdf *= 2.0f;
  64. if (direct_emission(
  65. kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
  66. /* trace shadow ray */
  67. float3 shadow;
  68. if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
  69. /* accumulate */
  70. path_radiance_accum_light(L,
  71. state,
  72. throughput * num_samples_inv,
  73. &L_light,
  74. shadow,
  75. num_samples_inv,
  76. is_lamp);
  77. }
  78. else {
  79. path_radiance_accum_total_light(L, state, throughput * num_samples_inv, &L_light);
  80. }
  81. }
  82. }
  83. }
  84. }
  85. /* mesh light sampling */
  86. if (kernel_data.integrator.pdf_triangles != 0.0f) {
  87. int num_samples = ceil_to_int(num_samples_adjust *
  88. kernel_data.integrator.mesh_light_samples);
  89. float num_samples_inv = num_samples_adjust / num_samples;
  90. for (int j = 0; j < num_samples; j++) {
  91. float light_u, light_v;
  92. path_branched_rng_2D(
  93. kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
  94. float terminate = path_branched_rng_light_termination(
  95. kg, state->rng_hash, state, j, num_samples);
  96. /* only sample triangle lights */
  97. if (kernel_data.integrator.num_all_lights)
  98. light_u = 0.5f * light_u;
  99. LightSample ls;
  100. if (light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
  101. /* Same as above, probability needs to be corrected since the sampling was forced to
  102. * select a mesh light. */
  103. if (kernel_data.integrator.num_all_lights)
  104. ls.pdf *= 2.0f;
  105. if (direct_emission(
  106. kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
  107. /* trace shadow ray */
  108. float3 shadow;
  109. if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
  110. /* accumulate */
  111. path_radiance_accum_light(L,
  112. state,
  113. throughput * num_samples_inv,
  114. &L_light,
  115. shadow,
  116. num_samples_inv,
  117. is_lamp);
  118. }
  119. else {
  120. path_radiance_accum_total_light(L, state, throughput * num_samples_inv, &L_light);
  121. }
  122. }
  123. }
  124. }
  125. }
  126. }
  127. else {
  128. /* sample one light at random */
  129. float light_u, light_v;
  130. path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
  131. float terminate = path_state_rng_light_termination(kg, state);
  132. LightSample ls;
  133. if (light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
  134. /* sample random light */
  135. if (direct_emission(
  136. kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
  137. /* trace shadow ray */
  138. float3 shadow;
  139. if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
  140. /* accumulate */
  141. path_radiance_accum_light(L,
  142. state,
  143. throughput * num_samples_adjust,
  144. &L_light,
  145. shadow,
  146. num_samples_adjust,
  147. is_lamp);
  148. }
  149. else {
  150. path_radiance_accum_total_light(L, state, throughput * num_samples_adjust, &L_light);
  151. }
  152. }
  153. }
  154. }
  155. # endif
  156. }
  157. /* branched path tracing: bounce off or through surface to with new direction stored in ray */
  158. ccl_device bool kernel_branched_path_surface_bounce(KernelGlobals *kg,
  159. ShaderData *sd,
  160. const ShaderClosure *sc,
  161. int sample,
  162. int num_samples,
  163. ccl_addr_space float3 *throughput,
  164. ccl_addr_space PathState *state,
  165. PathRadianceState *L_state,
  166. ccl_addr_space Ray *ray,
  167. float sum_sample_weight)
  168. {
  169. /* sample BSDF */
  170. float bsdf_pdf;
  171. BsdfEval bsdf_eval;
  172. float3 bsdf_omega_in;
  173. differential3 bsdf_domega_in;
  174. float bsdf_u, bsdf_v;
  175. path_branched_rng_2D(
  176. kg, state->rng_hash, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
  177. int label;
  178. label = shader_bsdf_sample_closure(
  179. kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
  180. if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
  181. return false;
  182. /* modify throughput */
  183. path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
  184. # ifdef __DENOISING_FEATURES__
  185. state->denoising_feature_weight *= sc->sample_weight / (sum_sample_weight * num_samples);
  186. # endif
  187. /* modify path state */
  188. path_state_next(kg, state, label);
  189. /* setup ray */
  190. ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT) ? -sd->Ng : sd->Ng);
  191. ray->D = normalize(bsdf_omega_in);
  192. ray->t = FLT_MAX;
  193. # ifdef __RAY_DIFFERENTIALS__
  194. ray->dP = sd->dP;
  195. ray->dD = bsdf_domega_in;
  196. # endif
  197. # ifdef __OBJECT_MOTION__
  198. ray->time = sd->time;
  199. # endif
  200. # ifdef __VOLUME__
  201. /* enter/exit volume */
  202. if (label & LABEL_TRANSMIT)
  203. kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
  204. # endif
  205. /* branch RNG state */
  206. path_state_branch(state, sample, num_samples);
  207. /* set MIS state */
  208. state->min_ray_pdf = fminf(bsdf_pdf, FLT_MAX);
  209. state->ray_pdf = bsdf_pdf;
  210. # ifdef __LAMP_MIS__
  211. state->ray_t = 0.0f;
  212. # endif
  213. return true;
  214. }
  215. #endif
  216. /* path tracing: connect path directly to position on a light and add it to L */
  217. ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg,
  218. ShaderData *sd,
  219. ShaderData *emission_sd,
  220. float3 throughput,
  221. ccl_addr_space PathState *state,
  222. PathRadiance *L)
  223. {
  224. PROFILING_INIT(kg, PROFILING_CONNECT_LIGHT);
  225. #ifdef __EMISSION__
  226. if (!(kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL)))
  227. return;
  228. # ifdef __SHADOW_TRICKS__
  229. if (state->flag & PATH_RAY_SHADOW_CATCHER) {
  230. kernel_branched_path_surface_connect_light(kg, sd, emission_sd, state, throughput, 1.0f, L, 1);
  231. return;
  232. }
  233. # endif
  234. /* sample illumination from lights to find path contribution */
  235. float light_u, light_v;
  236. path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
  237. Ray light_ray;
  238. BsdfEval L_light;
  239. bool is_lamp;
  240. # ifdef __OBJECT_MOTION__
  241. light_ray.time = sd->time;
  242. # endif
  243. LightSample ls;
  244. if (light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
  245. float terminate = path_state_rng_light_termination(kg, state);
  246. if (direct_emission(
  247. kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
  248. /* trace shadow ray */
  249. float3 shadow;
  250. if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
  251. /* accumulate */
  252. path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
  253. }
  254. else {
  255. path_radiance_accum_total_light(L, state, throughput, &L_light);
  256. }
  257. }
  258. }
  259. #endif
  260. }
  261. /* path tracing: bounce off or through surface to with new direction stored in ray */
  262. ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg,
  263. ShaderData *sd,
  264. ccl_addr_space float3 *throughput,
  265. ccl_addr_space PathState *state,
  266. PathRadianceState *L_state,
  267. ccl_addr_space Ray *ray)
  268. {
  269. PROFILING_INIT(kg, PROFILING_SURFACE_BOUNCE);
  270. /* no BSDF? we can stop here */
  271. if (sd->flag & SD_BSDF) {
  272. /* sample BSDF */
  273. float bsdf_pdf;
  274. BsdfEval bsdf_eval;
  275. float3 bsdf_omega_in;
  276. differential3 bsdf_domega_in;
  277. float bsdf_u, bsdf_v;
  278. path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
  279. int label;
  280. label = shader_bsdf_sample(
  281. kg, sd, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
  282. if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
  283. return false;
  284. /* modify throughput */
  285. path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
  286. /* set labels */
  287. if (!(label & LABEL_TRANSPARENT)) {
  288. state->ray_pdf = bsdf_pdf;
  289. #ifdef __LAMP_MIS__
  290. state->ray_t = 0.0f;
  291. #endif
  292. state->min_ray_pdf = fminf(bsdf_pdf, state->min_ray_pdf);
  293. }
  294. /* update path state */
  295. path_state_next(kg, state, label);
  296. /* setup ray */
  297. ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT) ? -sd->Ng : sd->Ng);
  298. ray->D = normalize(bsdf_omega_in);
  299. if (state->bounce == 0)
  300. ray->t -= sd->ray_length; /* clipping works through transparent */
  301. else
  302. ray->t = FLT_MAX;
  303. #ifdef __RAY_DIFFERENTIALS__
  304. ray->dP = sd->dP;
  305. ray->dD = bsdf_domega_in;
  306. #endif
  307. #ifdef __VOLUME__
  308. /* enter/exit volume */
  309. if (label & LABEL_TRANSMIT)
  310. kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
  311. #endif
  312. return true;
  313. }
  314. #ifdef __VOLUME__
  315. else if (sd->flag & SD_HAS_ONLY_VOLUME) {
  316. if (!path_state_volume_next(kg, state)) {
  317. return false;
  318. }
  319. if (state->bounce == 0)
  320. ray->t -= sd->ray_length; /* clipping works through transparent */
  321. else
  322. ray->t = FLT_MAX;
  323. /* setup ray position, direction stays unchanged */
  324. ray->P = ray_offset(sd->P, -sd->Ng);
  325. # ifdef __RAY_DIFFERENTIALS__
  326. ray->dP = sd->dP;
  327. # endif
  328. /* enter/exit volume */
  329. kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
  330. return true;
  331. }
  332. #endif
  333. else {
  334. /* no bsdf or volume? */
  335. return false;
  336. }
  337. }
  338. CCL_NAMESPACE_END