Commit: f68634a379519eba5da34f0876990615eb453596 Author: Weizhen Huang Date: Wed Dec 7 18:51:26 2022 +0100 Branches: master https://developer.blender.org/rBf68634a379519eba5da34f0876990615eb453596
Cleanup: store tan instead of cot in area lights to increase precision =================================================================== M intern/cycles/kernel/light/area.h M intern/cycles/kernel/types.h M intern/cycles/scene/light.cpp =================================================================== diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index 02cd22c543e..23c69bdac4e 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -91,7 +91,7 @@ ccl_device_inline float area_light_rect_sample(float3 P, ccl_device float area_light_spread_attenuation(const float3 D, const float3 lightNg, - const float cot_half_spread, + const float tan_half_spread, const float normalize_spread) { /* Model a soft-box grid, computing the ratio of light not hidden by the @@ -99,7 +99,7 @@ ccl_device float area_light_spread_attenuation(const float3 D, const float cos_a = -dot(D, lightNg); const float sin_a = safe_sqrtf(1.0f - sqr(cos_a)); const float tan_a = sin_a / cos_a; - return max((1.0f - (cot_half_spread * tan_a)) * normalize_spread, 0.0f); + return max((tan_half_spread - tan_a) * normalize_spread, 0.0f); } /* Compute the minimal rectangle, circle or ellipse that covers the valid sample region, to reduce @@ -111,7 +111,7 @@ ccl_device bool area_light_spread_clamp_light(const float3 P, ccl_private float *len_u, ccl_private float3 *axis_v, ccl_private float *len_v, - const float cot_half_spread, + const float tan_half_spread, ccl_private bool *sample_rectangle) { /* Closest point in area light plane and distance to that plane. */ @@ -119,7 +119,7 @@ ccl_device bool area_light_spread_clamp_light(const float3 P, const float t = len(closest_P - P); /* Radius of circle on area light that actually affects the shading point. */ - const float r_spread = t / cot_half_spread; + const float r_spread = t * tan_half_spread; /* Local uv coordinates of closest point. */ const float spread_u = dot(*axis_u, closest_P - *lightP); @@ -261,7 +261,7 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, float sample_len_u = len_u; float sample_len_v = len_v; - if (klight->area.cot_half_spread > 0.0f) { + if (klight->area.normalize_spread > 0) { if (!area_light_spread_clamp_light(P, Ng, &ls->P, @@ -269,7 +269,7 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, &sample_len_u, &sample_axis_v, &sample_len_v, - klight->area.cot_half_spread, + klight->area.tan_half_spread, &sample_rectangle)) { return false; } @@ -307,10 +307,10 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, ls->eval_fac = 0.25f * invarea; - if (klight->area.cot_half_spread > 0.0f) { + if (klight->area.normalize_spread > 0) { /* Area Light spread angle attenuation */ ls->eval_fac *= area_light_spread_attenuation( - ls->D, ls->Ng, klight->area.cot_half_spread, klight->area.normalize_spread); + ls->D, ls->Ng, klight->area.tan_half_spread, klight->area.normalize_spread); } if (!sample_rectangle) { @@ -328,10 +328,10 @@ ccl_device_forceinline void area_light_update_position(const ccl_global KernelLi ls->D = normalize_len(ls->P - P, &ls->t); ls->pdf = invarea; - if (klight->area.cot_half_spread > 0.f) { + if (klight->area.tan_half_spread > 0) { ls->eval_fac = 0.25f * invarea; ls->eval_fac *= area_light_spread_attenuation( - ls->D, ls->Ng, klight->area.cot_half_spread, klight->area.normalize_spread); + ls->D, ls->Ng, klight->area.tan_half_spread, klight->area.normalize_spread); } } @@ -401,7 +401,7 @@ ccl_device_inline bool area_light_sample_from_intersection( bool is_ellipse = (klight->area.invarea < 0.0f); bool sample_rectangle = !is_ellipse; - if (klight->area.cot_half_spread > 0.0f) { + if (klight->area.normalize_spread > 0) { if (!area_light_spread_clamp_light(ray_P, Ng, &light_P, @@ -409,7 +409,7 @@ ccl_device_inline bool area_light_sample_from_intersection( &sample_len_u, &sample_axis_v, &sample_len_v, - klight->area.cot_half_spread, + klight->area.tan_half_spread, &sample_rectangle)) { return false; } @@ -425,10 +425,10 @@ ccl_device_inline bool area_light_sample_from_intersection( ls->eval_fac = 0.25f * invarea; - if (klight->area.cot_half_spread > 0.0f) { + if (klight->area.normalize_spread > 0) { /* Area Light spread angle attenuation */ ls->eval_fac *= area_light_spread_attenuation( - ls->D, ls->Ng, klight->area.cot_half_spread, klight->area.normalize_spread); + ls->D, ls->Ng, klight->area.tan_half_spread, klight->area.normalize_spread); if (ls->eval_fac == 0.0f) { return false; } diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 0dada42b909..100f0806ed2 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -1307,7 +1307,7 @@ typedef struct KernelAreaLight { float len_v; packed_float3 dir; float invarea; - float cot_half_spread; + float tan_half_spread; float normalize_spread; float pad[2]; } KernelAreaLight; diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index 450618afce4..fa5affa8c68 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -1041,11 +1041,11 @@ void LightManager::device_update_lights(Device *device, DeviceScene *dscene, Sce /* Clamping to a minimum angle to avoid excessive noise. */ const float min_spread = 1.0f * M_PI_F / 180.0f; const float half_spread = 0.5f * max(light->spread, min_spread); - /* cot_half_spread is h in D10594#269626 */ - const float cot_half_spread = tanf(M_PI_2_F - half_spread); + const float tan_half_spread = light->spread == M_PI_F ? FLT_MAX : tanf(half_spread); /* Normalization computed using: - * integrate cos(x) * (1 - tan(x) / tan(a)) * sin(x) from x = 0 to a, a being half_spread */ - const float normalize_spread = 1.0f / (1.0f - half_spread * cot_half_spread); + * integrate cos(x) * (1 - tan(x) / tan(a)) * sin(x) from x = 0 to a, a being half_spread. + * Divided by tan_half_spread to simplify the attentuation computation in `area.h`. */ + const float normalize_spread = 1.0f / (tan_half_spread - half_spread); dir = safe_normalize(dir); @@ -1059,7 +1059,7 @@ void LightManager::device_update_lights(Device *device, DeviceScene *dscene, Sce klights[light_index].area.len_v = len_v; klights[light_index].area.invarea = invarea; klights[light_index].area.dir = dir; - klights[light_index].area.cot_half_spread = cot_half_spread; + klights[light_index].area.tan_half_spread = tan_half_spread; klights[light_index].area.normalize_spread = normalize_spread; } else if (light->light_type == LIGHT_SPOT) { _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs