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/light')
-rw-r--r--intern/cycles/kernel/light/light.h90
-rw-r--r--intern/cycles/kernel/light/sample.h10
2 files changed, 66 insertions, 34 deletions
diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h
index 6e445f862db..d05fe47cc2c 100644
--- a/intern/cycles/kernel/light/light.h
+++ b/intern/cycles/kernel/light/light.h
@@ -113,22 +113,30 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
ls->P = make_float3(klight->co[0], klight->co[1], klight->co[2]);
if (type == LIGHT_SPOT) {
- ls->Ng = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
- float radius = klight->spot.radius;
+ const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+ const float radius = klight->spot.radius;
+ const float3 dir = make_float3(
+ klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
+ /* disk oriented normal */
+ const float3 lightN = normalize(P - center);
+ ls->P = center;
if (radius > 0.0f)
- /* sphere light */
- ls->P += disk_light_sample(ls->Ng, randu, randv) * radius;
+ /* disk light */
+ ls->P += disk_light_sample(lightN, randu, randv) * radius;
+
+ const float invarea = klight->spot.invarea;
+ ls->pdf = invarea;
ls->D = normalize_len(ls->P - P, &ls->t);
+ /* we set the light normal to the outgoing direction to support texturing */
+ ls->Ng = -ls->D;
- float invarea = klight->spot.invarea;
ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
- ls->pdf = invarea;
/* spot light attenuation */
ls->eval_fac *= spot_light_attenuation(
- ls->Ng, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
+ dir, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
if (!in_volume_segment && ls->eval_fac == 0.0f) {
return false;
}
@@ -137,32 +145,33 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
ls->u = uv.x;
ls->v = uv.y;
- ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ ls->pdf *= lamp_light_pdf(kg, lightN, -ls->D, ls->t);
}
else if (type == LIGHT_POINT) {
float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
float radius = klight->spot.radius;
+ /* disk oriented normal */
+ const float3 lightN = normalize(P - center);
ls->P = center;
- float pdf = 1.0;
if (radius > 0.0f) {
- ls->Ng = normalize(P - center);
- ls->P += disk_light_sample(ls->Ng, randu, randv) * radius;
- pdf = klight->spot.invarea;
- ls->D = normalize_len(ls->P - P, &ls->t);
- }
- else {
- ls->Ng = normalize(P - center);
+ ls->P += disk_light_sample(lightN, randu, randv) * radius;
}
+ ls->pdf = klight->spot.invarea;
ls->D = normalize_len(ls->P - P, &ls->t);
- ls->pdf = pdf;
+ /* we set the light normal to the outgoing direction to support texturing */
+ ls->Ng = -ls->D;
+
ls->eval_fac = M_1_PI_F * 0.25f * klight->spot.invarea;
+ if (!in_volume_segment && ls->eval_fac == 0.0f) {
+ return false;
+ }
float2 uv = map_to_sphere(ls->Ng);
ls->u = uv.x;
ls->v = uv.y;
- ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ ls->pdf *= lamp_light_pdf(kg, lightN, -ls->D, ls->t);
}
else {
/* area light */
@@ -263,14 +272,16 @@ ccl_device bool lights_intersect(KernelGlobals kg,
if (type == LIGHT_SPOT) {
/* Spot/Disk light. */
+ const float mis_ray_t = INTEGRATOR_STATE(state, path, mis_ray_t);
+ const float3 ray_P = ray->P - ray->D * mis_ray_t;
+
const float3 lightP = make_float3(klight->co[0], klight->co[1], klight->co[2]);
- const float3 lightN = make_float3(
- klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
const float radius = klight->spot.radius;
if (radius == 0.0f) {
continue;
}
-
+ /* disk oriented normal */
+ const float3 lightN = normalize(ray_P - lightP);
/* One sided. */
if (dot(ray->D, lightN) >= 0.0f) {
continue;
@@ -292,9 +303,10 @@ ccl_device bool lights_intersect(KernelGlobals kg,
continue;
}
+ /* disk oriented normal */
+ const float3 lightN = normalize(ray_P - lightP);
float3 P;
- const float3 lsN = normalize(ray_P - lightP);
- if (!ray_disk_intersect(ray->P, ray->D, ray->t, lightP, lsN, radius, &P, &t)) {
+ if (!ray_disk_intersect(ray->P, ray->D, ray->t, lightP, lightN, radius, &P, &t)) {
continue;
}
}
@@ -418,8 +430,8 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
LightType type = (LightType)klight->type;
ls->type = type;
ls->shader = klight->shader_id;
- ls->object = PRIM_NONE;
- ls->prim = PRIM_NONE;
+ ls->object = isect->object;
+ ls->prim = isect->prim;
ls->lamp = lamp;
/* todo: missing texture coordinates */
ls->t = isect->t;
@@ -427,7 +439,12 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
ls->D = ray_D;
if (type == LIGHT_SPOT) {
- ls->Ng = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
+ const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+ const float3 dir = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
+ /* the normal of the oriented disk */
+ const float3 lightN = normalize(ray_P - center);
+ /* we set the light normal to the outgoing direction to support texturing*/
+ ls->Ng = -ls->D;
float invarea = klight->spot.invarea;
ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
@@ -435,7 +452,7 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
/* spot light attenuation */
ls->eval_fac *= spot_light_attenuation(
- ls->Ng, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
+ dir, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
if (ls->eval_fac == 0.0f) {
return false;
@@ -447,23 +464,32 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
/* compute pdf */
if (ls->t != FLT_MAX)
- ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ ls->pdf *= lamp_light_pdf(kg, lightN, -ls->D, ls->t);
+ else
+ ls->pdf = 0.f;
}
else if (type == LIGHT_POINT) {
- float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+ const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+ const float3 lighN = normalize(ray_P - center);
+
+ /* we set the light normal to the outgoing direction to support texturing*/
+ ls->Ng = -ls->D;
- ls->Ng = normalize(ray_P - center);
float invarea = klight->spot.invarea;
ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
ls->pdf = invarea;
+ if (ls->eval_fac == 0.0f) {
+ return false;
+ }
+
float2 uv = map_to_sphere(ls->Ng);
ls->u = uv.x;
ls->v = uv.y;
/* compute pdf */
if (ls->t != FLT_MAX)
- ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ ls->pdf *= lamp_light_pdf(kg, lighN, -ls->D, ls->t);
else
ls->pdf = 0.f;
}
@@ -921,4 +947,4 @@ ccl_device_inline bool light_distribution_sample_new_position(KernelGlobals kg,
}
}
-CCL_NAMESPACE_END
+CCL_NAMESPACE_END \ No newline at end of file
diff --git a/intern/cycles/kernel/light/sample.h b/intern/cycles/kernel/light/sample.h
index 7dbc783b1bb..521ad2f7066 100644
--- a/intern/cycles/kernel/light/sample.h
+++ b/intern/cycles/kernel/light/sample.h
@@ -198,7 +198,7 @@ ccl_device_inline float3 shadow_ray_offset(KernelGlobals kg,
float NL = dot(sd->N, L);
bool transmit = (NL < 0.0f);
float3 Ng = (transmit ? -sd->Ng : sd->Ng);
- float3 P = ray_offset(sd->P, Ng);
+ float3 P = sd->P;
if ((sd->type & PRIMITIVE_TRIANGLE) && (sd->shader & SHADER_SMOOTH_NORMAL)) {
const float offset_cutoff =
@@ -243,7 +243,7 @@ ccl_device_inline void shadow_ray_setup(ccl_private const ShaderData *ccl_restri
}
else {
/* other lights, avoid self-intersection */
- ray->D = ray_offset(ls->P, ls->Ng) - P;
+ ray->D = ls->P - P;
ray->D = normalize_len(ray->D, &ray->t);
}
}
@@ -257,6 +257,12 @@ ccl_device_inline void shadow_ray_setup(ccl_private const ShaderData *ccl_restri
ray->dP = differential_make_compact(sd->dP);
ray->dD = differential_zero_compact();
ray->time = sd->time;
+
+ /* Fill in intersection surface and light details. */
+ ray->self.prim = sd->prim;
+ ray->self.object = sd->object;
+ ray->self.light_prim = ls->prim;
+ ray->self.light_object = ls->object;
}
/* Create shadow ray towards light sample. */