[Bf-blender-cvs] [776ce62] soc-2014-cycles: Cycles: Further optimizations for Volume Light Sampling.
Thomas Dinges
noreply at git.blender.org
Tue Jul 29 18:00:52 CEST 2014
Commit: 776ce62bee4df7ad59b7c2172e9eec9435607d60
Author: Thomas Dinges
Date: Tue Jul 29 17:58:14 2014 +0200
Branches: soc-2014-cycles
https://developer.blender.org/rB776ce62bee4df7ad59b7c2172e9eec9435607d60
Cycles: Further optimizations for Volume Light Sampling.
* Now we calculate ls->P only, which is needed for equi-angular sampling. If the scattering is successful, we call the regular light_sample() functions.
===================================================================
M intern/cycles/kernel/kernel_light.h
M intern/cycles/kernel/kernel_path_volume.h
===================================================================
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 37230d4..199a2c2 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -208,46 +208,39 @@ ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3
return t*t/cos_pi;
}
-ccl_device void lamp_light_sample_new_position(KernelGlobals *kg, int lamp,
+ccl_device void lamp_light_sample_position(KernelGlobals *kg, int lamp,
float randu, float randv, float3 P, LightSample *ls)
{
- if(ls->type == LIGHT_POINT || ls->type == LIGHT_SPOT) {
- float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
- float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
+ float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
+ float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
+ LightType type = (LightType)__float_as_int(data0.x);
+
+ if(type == LIGHT_DISTANT || type == LIGHT_BACKGROUND) {
+ /* Distant lights, no equi-angular sampling */
+ ls->t = FLT_MAX;
+ }
+ else {
+ /* calculate ls->P for equi-angular sampling */
ls->P = make_float3(data0.y, data0.z, data0.w);
- float radius = data1.y;
+ if(type == LIGHT_POINT || type == LIGHT_SPOT) {
+ float radius = data1.y;
- if(radius > 0.0f)
+ if(radius > 0.0f)
/* sphere light */
- ls->P += sphere_light_sample(P, ls->P, radius, randu, randv);
-
- ls->D = normalize_len(ls->P - P, &ls->t);
- ls->Ng = -ls->D;
-
- float invarea = data1.z;
- ls->pdf = invarea;
-
- if(ls->type == LIGHT_SPOT) {
- /* spot light attenuation */
- float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
- ls->eval_fac = (0.25f*M_1_PI_F)*invarea*kernel_data.integrator.inv_pdf_lights;
- ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
+ ls->P += sphere_light_sample(P, ls->P, radius, randu, randv);
}
- }
- else if(ls->type == LIGHT_AREA) {
+ else {
+ /* area light */
float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
- ls->pdf = data2.x;
- ls->D = normalize_len(ls->P - P, &ls->t);
- }
- else {
- /* Distant Lights */
- return;
- }
+ float3 axisu = make_float3(data1.y, data1.z, data1.w);
+ float3 axisv = make_float3(data2.y, data2.z, data2.w);
- ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ ls->P += area_light_sample(axisu, axisv, randu, randv);
+ }
+ }
}
ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp,
@@ -554,8 +547,7 @@ ccl_device int light_distribution_sample(KernelGlobals *kg, float randt)
return clamp(first-1, 0, kernel_data.integrator.num_distribution-1);
}
-/* ToDo: Better function name */
-ccl_device void light_sample_new_position(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls)
+ccl_device void light_sample_position(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls)
{
/* sample index */
int index = light_distribution_sample(kg, randt);
@@ -565,13 +557,12 @@ ccl_device void light_sample_new_position(KernelGlobals *kg, float randt, float
int prim = __float_as_int(l.y);
if(prim >= 0) {
- /* compute incoming direction, distance and pdf */
- ls->D = normalize_len(ls->P - P, &ls->t);
- ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ /* compute distance, although this probably never becomes FLT_MAX */
+ ls->t = len(ls->P - P);
}
else {
int lamp = -prim-1;
- lamp_light_sample_new_position(kg, lamp, randu, randv, P, ls);
+ lamp_light_sample_position(kg, lamp, randu, randv, P, ls);
}
}
diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h
index 32980ad..731937d 100644
--- a/intern/cycles/kernel/kernel_path_volume.h
+++ b/intern/cycles/kernel/kernel_path_volume.h
@@ -134,7 +134,6 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
LightSample ls;
- lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls);
float3 tp = throughput;
@@ -143,13 +142,18 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
float rphase = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_PHASE);
float rscatter = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_SCATTER_DISTANCE);
+ lamp_light_sample_position(kg, i, light_u, light_v, ray->P, &ls);
+
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
if(result != VOLUME_PATH_SCATTERED)
continue;
- lamp_light_sample_new_position(kg, i, light_u, light_v, sd->P, &ls);
+ lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls);
+ }
+ else {
+ lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls);
}
if(ls.pdf == 0.0f)
@@ -186,7 +190,6 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
light_t = 0.5f*light_t;
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, &ls);
float3 tp = throughput;
@@ -195,13 +198,18 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
float rphase = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_PHASE);
float rscatter = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_SCATTER_DISTANCE);
+ light_sample_position(kg, light_t, light_u, light_v, sd->time, ray->P, &ls);
+
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
if(result != VOLUME_PATH_SCATTERED)
continue;
- light_sample_new_position(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ }
+ else {
+ light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, &ls);
}
if(ls.pdf == 0.0f)
@@ -235,13 +243,18 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE);
float rscatter = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE);
+ light_sample_position(kg, light_t, light_u, light_v, sd->time, ray->P, &ls);
+
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
if(result != VOLUME_PATH_SCATTERED)
return;
- light_sample_new_position(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ }
+ else {
+ light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, &ls);
}
if(ls.pdf == 0.0f)
More information about the Bf-blender-cvs
mailing list