diff options
Diffstat (limited to 'intern/cycles/kernel/kernel_projection.h')
-rw-r--r-- | intern/cycles/kernel/kernel_projection.h | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/intern/cycles/kernel/kernel_projection.h b/intern/cycles/kernel/kernel_projection.h index 6744471d659..62922df3286 100644 --- a/intern/cycles/kernel/kernel_projection.h +++ b/intern/cycles/kernel/kernel_projection.h @@ -55,18 +55,18 @@ ccl_device float3 spherical_to_direction(float theta, float phi) /* Equirectangular coordinates <-> Cartesian direction */ -ccl_device float2 direction_to_equirectangular(float3 dir) +ccl_device float2 direction_to_equirectangular_range(float3 dir, float4 range) { - float u = -atan2f(dir.y, dir.x)/(M_2PI_F) + 0.5f; - float v = atan2f(dir.z, hypotf(dir.x, dir.y))/M_PI_F + 0.5f; + float u = (atan2f(dir.y, dir.x) - range.y) / range.x; + float v = (acosf(dir.z / len(dir)) - range.w) / range.z; return make_float2(u, v); } -ccl_device float3 equirectangular_to_direction(float u, float v) +ccl_device float3 equirectangular_range_to_direction(float u, float v, float4 range) { - float phi = M_PI_F*(1.0f - 2.0f*u); - float theta = M_PI_F*(1.0f - v); + float phi = range.x*u + range.y; + float theta = range.z*v + range.w; return make_float3( sinf(theta)*cosf(phi), @@ -74,6 +74,16 @@ ccl_device float3 equirectangular_to_direction(float u, float v) cosf(theta)); } +ccl_device float2 direction_to_equirectangular(float3 dir) +{ + return direction_to_equirectangular_range(dir, make_float4(-M_2PI_F, M_PI_F, -M_PI_F, M_PI_F)); +} + +ccl_device float3 equirectangular_to_direction(float u, float v) +{ + return equirectangular_range_to_direction(u, v, make_float4(-M_2PI_F, M_PI_F, -M_PI_F, M_PI_F)); +} + /* Fisheye <-> Cartesian direction */ ccl_device float2 direction_to_fisheye(float3 dir, float fov) @@ -153,6 +163,10 @@ ccl_device float3 mirrorball_to_direction(float u, float v) dir.x = 2.0f*u - 1.0f; dir.z = 2.0f*v - 1.0f; + + if(dir.x*dir.x + dir.z*dir.z > 1.0f) + return make_float3(0.0f, 0.0f, 0.0f); + dir.y = -sqrtf(max(1.0f - dir.x*dir.x - dir.z*dir.z, 0.0f)); /* reflection */ @@ -180,7 +194,9 @@ ccl_device float3 panorama_to_direction(KernelGlobals *kg, float u, float v) { switch(kernel_data.cam.panorama_type) { case PANORAMA_EQUIRECTANGULAR: - return equirectangular_to_direction(u, v); + return equirectangular_range_to_direction(u, v, kernel_data.cam.equirectangular_range); + case PANORAMA_MIRRORBALL: + return mirrorball_to_direction(u, v); case PANORAMA_FISHEYE_EQUIDISTANT: return fisheye_to_direction(u, v, kernel_data.cam.fisheye_fov); case PANORAMA_FISHEYE_EQUISOLID: @@ -194,7 +210,9 @@ ccl_device float2 direction_to_panorama(KernelGlobals *kg, float3 dir) { switch(kernel_data.cam.panorama_type) { case PANORAMA_EQUIRECTANGULAR: - return direction_to_equirectangular(dir); + return direction_to_equirectangular_range(dir, kernel_data.cam.equirectangular_range); + case PANORAMA_MIRRORBALL: + return direction_to_mirrorball(dir); case PANORAMA_FISHEYE_EQUIDISTANT: return direction_to_fisheye(dir, kernel_data.cam.fisheye_fov); case PANORAMA_FISHEYE_EQUISOLID: |