Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/light/tree.h
| Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| max_importance = 0.0f; | max_importance = 0.0f; | ||||
| min_importance = 0.0f; | min_importance = 0.0f; | ||||
| const float sin_theta_u = safe_sqrtf(1.0f - sqr(cos_theta_u)); | const float sin_theta_u = safe_sqrtf(1.0f - sqr(cos_theta_u)); | ||||
| float cos_theta, cos_theta_i, sin_theta_i; | float cos_theta, cos_theta_i, sin_theta_i; | ||||
| /* cos(theta_i') in the paper, omitted for volume */ | /* cos(theta_i') in the paper, omitted for volume */ | ||||
| float cos_min_incidence_angle = 1.0f; | float cos_min_incidence_angle = 1.0f; | ||||
| float cos_max_incidence_angle = 1.0f; | |||||
| /* when sampling the light tree for the second time in `shade_volume.h` and when query the pdf in | /* when sampling the light tree for the second time in `shade_volume.h` and when query the pdf in | ||||
| * `sample.h` */ | * `sample.h` */ | ||||
| const bool in_volume = (dot(N_or_D, N_or_D) < 5e-4f); | const bool in_volume = (dot(N_or_D, N_or_D) < 5e-4f); | ||||
| if (in_volume_segment) { | if (in_volume_segment) { | ||||
| const float3 D = N_or_D; | const float3 D = N_or_D; | ||||
| const float3 v0 = -normalize(point_to_centroid); | const float3 v0 = -normalize(point_to_centroid); | ||||
| const float3 v1 = normalize(-point_to_centroid + D * fminf(t, 1e12f)); | const float3 v1 = normalize(-point_to_centroid + D * fminf(t, 1e12f)); | ||||
| Show All 18 Lines | if (!in_volume) { | ||||
| cos_theta_i = has_transmission ? fabsf(dot(point_to_centroid, N)) : | cos_theta_i = has_transmission ? fabsf(dot(point_to_centroid, N)) : | ||||
| dot(point_to_centroid, N); | dot(point_to_centroid, N); | ||||
| sin_theta_i = safe_sqrtf(1.0f - sqr(cos_theta_i)); | sin_theta_i = safe_sqrtf(1.0f - sqr(cos_theta_i)); | ||||
| /* cos_min_incidence_angle = cos(max{theta_i - theta_u, 0}) = cos(theta_i') in the paper */ | /* cos_min_incidence_angle = cos(max{theta_i - theta_u, 0}) = cos(theta_i') in the paper */ | ||||
| cos_min_incidence_angle = cos_theta_i > cos_theta_u ? | cos_min_incidence_angle = cos_theta_i > cos_theta_u ? | ||||
| 1.0f : | 1.0f : | ||||
| cos_theta_i * cos_theta_u + sin_theta_i * sin_theta_u; | cos_theta_i * cos_theta_u + sin_theta_i * sin_theta_u; | ||||
| /* cos_max_incidence_angle = cos(min{theta_i + theta_u, pi}) */ | |||||
| cos_max_incidence_angle = fmaxf(cos_theta_i * cos_theta_u - sin_theta_i * sin_theta_u, 0.0f); | |||||
| /* If the node is guaranteed to be behind the surface we're sampling, and the surface is | /* If the node is guaranteed to be behind the surface we're sampling, and the surface is | ||||
| * opaque, then we can give the node an importance of 0 as it contributes nothing to the | * opaque, then we can give the node an importance of 0 as it contributes nothing to the | ||||
| * surface. This is more accurate than the bbox test if we are calculating the importance of | * surface. This is more accurate than the bbox test if we are calculating the importance of | ||||
| * an emitter with radius */ | * an emitter with radius */ | ||||
| if (!has_transmission && cos_min_incidence_angle < 0) { | if (!has_transmission && cos_min_incidence_angle < 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| Show All 28 Lines | ccl_device void light_tree_cluster_importance(const float3 N_or_D, | ||||
| } | } | ||||
| /* TODO: find a good approximation for f_a. */ | /* TODO: find a good approximation for f_a. */ | ||||
| const float f_a = 1.0f; | const float f_a = 1.0f; | ||||
| /* TODO: also consider t (or theta_a, theta_b) for volume */ | /* TODO: also consider t (or theta_a, theta_b) for volume */ | ||||
| max_importance = fabsf(f_a * cos_min_incidence_angle * energy * cos_min_outgoing_angle / | max_importance = fabsf(f_a * cos_min_incidence_angle * energy * cos_min_outgoing_angle / | ||||
| (in_volume_segment ? min_distance : sqr(min_distance))); | (in_volume_segment ? min_distance : sqr(min_distance))); | ||||
| /* TODO: also min importance for volume? */ | |||||
| if (in_volume_segment || in_volume) { | |||||
weizhen: When `in_volume_segment`, we use the shortest distance from a point to the ray, so using… | |||||
| min_importance = max_importance; | |||||
| return; | |||||
| } | |||||
| /* compute mininum importance */ | |||||
| /* cos_max_incidence_angle = cos(min{theta_i + theta_u, pi}) */ | |||||
| const float cos_max_incidence_angle = fmaxf( | |||||
| cos_theta_i * cos_theta_u - sin_theta_i * sin_theta_u, 0.0f); | |||||
| /* cos(theta + theta_o + theta_u) if theta + theta_o + theta_u < theta_e, 0 otherwise */ | /* cos(theta + theta_o + theta_u) if theta + theta_o + theta_u < theta_e, 0 otherwise */ | ||||
| float cos_max_outgoing_angle; | float cos_max_outgoing_angle; | ||||
| const float cos_theta_plus_theta_u = cos_theta * cos_theta_u - sin_theta * sin_theta_u; | const float cos_theta_plus_theta_u = cos_theta * cos_theta_u - sin_theta * sin_theta_u; | ||||
| if (theta_e - theta_o < 0 || cos_theta < 0 || cos_theta_u < 0 || | if (theta_e - theta_o < 0 || cos_theta < 0 || cos_theta_u < 0 || | ||||
| cos_theta_plus_theta_u < cos(theta_e - theta_o)) { | cos_theta_plus_theta_u < cos(theta_e - theta_o)) { | ||||
| min_importance = 0.0f; | min_importance = 0.0f; | ||||
| } | } | ||||
| else { | else { | ||||
| ▲ Show 20 Lines • Show All 705 Lines • Show Last 20 Lines | |||||
When in_volume_segment, we use the shortest distance from a point to the ray, so using max_distance does not make sense; instead, we want to add \theta_a and \theta_b in the future (see Eq 4. in the original paper). But when in_volume, we have a shading point and could compute the importance the same way as we are not in a volume, except that cos_incidence_angle = 1.0f. So please keep this block with if (in_volume_segment) { for now, otherwise it looks fine.