Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/kernel_light.h')
-rw-r--r--intern/cycles/kernel/kernel_light.h83
1 files changed, 43 insertions, 40 deletions
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 7590ec2d706..675eacfc5ee 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -262,7 +262,7 @@ ccl_device_inline bool background_portal_data_fetch_and_check_side(KernelGlobals
*dir = make_float3(data3.y, data3.z, data3.w);
/* Check whether portal is on the right side. */
- if(dot(*dir, P - *lightpos) > 1e-5f)
+ if(dot(*dir, P - *lightpos) > 1e-4f)
return true;
return false;
@@ -276,6 +276,7 @@ ccl_device float background_portal_pdf(KernelGlobals *kg,
{
float portal_pdf = 0.0f;
+ int num_possible = 0;
for(int p = 0; p < kernel_data.integrator.num_portals; p++) {
if(p == ignore_portal)
continue;
@@ -284,13 +285,14 @@ ccl_device float background_portal_pdf(KernelGlobals *kg,
if(!background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir))
continue;
+ /* There's a portal that could be sampled from this position. */
if(is_possible) {
- /* There's a portal that could be sampled from this position. */
*is_possible = true;
}
+ num_possible++;
float t = -(dot(P, dir) - dot(lightpos, dir)) / dot(direction, dir);
- if(t <= 1e-5f) {
+ if(t <= 1e-4f) {
/* Either behind the portal or too close. */
continue;
}
@@ -312,7 +314,12 @@ ccl_device float background_portal_pdf(KernelGlobals *kg,
portal_pdf += area_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false);
}
- return kernel_data.integrator.num_portals? portal_pdf / kernel_data.integrator.num_portals: 0.0f;
+ if(ignore_portal >= 0) {
+ /* We have skipped a portal that could be sampled as well. */
+ num_possible++;
+ }
+
+ return (num_possible > 0)? portal_pdf / num_possible: 0.0f;
}
ccl_device int background_num_possible_portals(KernelGlobals *kg, float3 P)
@@ -431,38 +438,28 @@ ccl_device float background_light_pdf(KernelGlobals *kg, float3 P, float3 direct
/* Probability of sampling portals instead of the map. */
float portal_sampling_pdf = kernel_data.integrator.portal_pdf;
+ float portal_pdf = 0.0f, map_pdf = 0.0f;
if(portal_sampling_pdf > 0.0f) {
+ /* Evaluate PDF of sampling this direction by portal sampling. */
bool is_possible = false;
- float portal_pdf = background_portal_pdf(kg, P, direction, -1, &is_possible);
- if(portal_pdf == 0.0f) {
- if(portal_sampling_pdf == 1.0f) {
- /* If there are no possible portals at this point,
- * the fallback sampling would have been used.
- * Otherwise, the direction would not be sampled at all => pdf = 0
- */
- return is_possible? 0.0f: kernel_data.integrator.pdf_lights / M_4PI_F;
- }
- else {
- /* We can only sample the map. */
- return background_map_pdf(kg, direction) * kernel_data.integrator.pdf_lights;
- }
- } else {
+ portal_pdf = background_portal_pdf(kg, P, direction, -1, &is_possible) * portal_sampling_pdf;
+ if(!is_possible) {
+ /* Portal sampling is not possible here because all portals point to the wrong side.
+ * If map sampling is possible, it would be used instead, otherwise fallback sampling is used. */
if(portal_sampling_pdf == 1.0f) {
- /* We can only sample portals. */
- return portal_pdf * kernel_data.integrator.pdf_lights;
+ return kernel_data.integrator.pdf_lights / M_4PI_F;
}
else {
- /* We can sample both, so combine with MIS. */
- return (background_map_pdf(kg, direction) * (1.0f - portal_sampling_pdf)
- + portal_pdf * portal_sampling_pdf) * kernel_data.integrator.pdf_lights;
+ /* Force map sampling. */
+ portal_sampling_pdf = 0.0f;
}
}
}
-
- /* No portals in the scene, so must sample the map.
- * At least one of them is always possible if we have a LIGHT_BACKGROUND.
- */
- return background_map_pdf(kg, direction) * kernel_data.integrator.pdf_lights;
+ if(portal_sampling_pdf < 1.0f) {
+ /* Evaluate PDF of sampling this direction by map sampling. */
+ map_pdf = background_map_pdf(kg, direction) * (1.0f - portal_sampling_pdf);
+ }
+ return (portal_pdf + map_pdf) * kernel_data.integrator.pdf_lights;
}
#endif
@@ -620,12 +617,7 @@ ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp,
}
}
-#if defined(__KERNEL_CUDA__) && (__CUDA_ARCH__ >= 500) && (defined(i386) || defined(_M_IX86))
-ccl_device_noinline
-#else
-ccl_device
-#endif
-bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls)
+ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls)
{
float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
@@ -693,8 +685,10 @@ bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, L
return false;
if(!ray_aligned_disk_intersect(P, D, t,
- lightP, radius, &ls->P, &ls->t))
+ lightP, radius, &ls->P, &ls->t))
+ {
return false;
+ }
ls->Ng = -D;
ls->D = D;
@@ -736,8 +730,10 @@ bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, L
float3 light_P = make_float3(data0.y, data0.z, data0.w);
if(!ray_quad_intersect(P, D, t,
- light_P, axisu, axisv, &ls->P, &ls->t))
+ light_P, axisu, axisv, &ls->P, &ls->t))
+ {
return false;
+ }
ls->D = D;
ls->Ng = Ng;
@@ -757,12 +753,12 @@ ccl_device void object_transform_light_sample(KernelGlobals *kg, LightSample *ls
#ifdef __INSTANCING__
/* instance transform */
if(object >= 0) {
-#ifdef __OBJECT_MOTION__
+# ifdef __OBJECT_MOTION__
Transform itfm;
Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm);
-#else
+# else
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
-#endif
+# endif
ls->P = transform_point(&tfm, ls->P);
ls->Ng = normalize(transform_direction(&tfm, ls->Ng));
@@ -845,7 +841,14 @@ ccl_device bool light_select_reached_max_bounces(KernelGlobals *kg, int index, i
return (bounce > __float_as_int(data4.x));
}
-ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, int bounce, LightSample *ls)
+ccl_device_noinline void light_sample(KernelGlobals *kg,
+ float randt,
+ float randu,
+ float randv,
+ float time,
+ float3 P,
+ int bounce,
+ LightSample *ls)
{
/* sample index */
int index = light_distribution_sample(kg, randt);