diff options
author | Lukas Stockner <lukas.stockner@freenet.de> | 2015-01-14 21:14:45 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-01-14 21:22:24 +0300 |
commit | 4118c1b4e6ae04988c310d785bd1802c46187e3a (patch) | |
tree | a645f7be743dae48886283579236b1022c867c2f /intern/cycles | |
parent | 193871ae7da35548688d7b9ccadde66e4f35d2fd (diff) |
Cycles: Adding field-of-view options to the equirectangular panorama camera
This patch adds the option to set minimum/maximum latitude/longitude values for
the equirectangular panorama camera in Cycles, as discussed in T34400.
The separate functions in kernel_projection.h are needed because the regular
ones are also used as helper functions for environment map sampling.
Reviewers: #cycles, sergey
Reviewed By: #cycles, sergey
Subscribers: dingto, sergey, brecht
Differential Revision: https://developer.blender.org/D960
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 28 | ||||
-rw-r--r-- | intern/cycles/blender/blender_camera.cpp | 13 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_projection.h | 26 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/camera.cpp | 12 | ||||
-rw-r--r-- | intern/cycles/render/camera.h | 4 |
6 files changed, 75 insertions, 9 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index b61cc66b83c..10c5f2bb58c 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -582,6 +582,34 @@ class CyclesCameraSettings(bpy.types.PropertyGroup): min=0.01, soft_max=15.0, max=100.0, default=10.5, ) + cls.latitude_min = FloatProperty( + name="Min latitude", + description="Minimum latitude (vertical angle) for the equirectangular lens", + min=-0.5 * math.pi, max=0.5 * math.pi, + subtype='ANGLE', + default=-0.5 * math.pi, + ) + cls.latitude_max = FloatProperty( + name="Max latitude", + description="Maximum latitude (vertical angle) for the equirectangular lens", + min=-0.5 * math.pi, max=0.5 * math.pi, + subtype='ANGLE', + default=0.5 * math.pi, + ) + cls.longitude_min = FloatProperty( + name="Min longitude", + description="Minimum longitude (horizontal angle) for the equirectangular lens", + min=-math.pi, max=math.pi, + subtype='ANGLE', + default=-math.pi, + ) + cls.longitude_max = FloatProperty( + name="Max longitude", + description="Maximum longitude (horizontal angle) for the equirectangular lens", + min=-math.pi, max=math.pi, + subtype='ANGLE', + default=math.pi, + ) @classmethod def unregister(cls): diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index ad98c062d25..e5214fb5c30 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -53,6 +53,10 @@ struct BlenderCamera { PanoramaType panorama_type; float fisheye_fov; float fisheye_lens; + float latitude_min; + float latitude_max; + float longitude_min; + float longitude_max; enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit; float sensor_width; @@ -147,6 +151,10 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, boo bcam->fisheye_fov = RNA_float_get(&ccamera, "fisheye_fov"); bcam->fisheye_lens = RNA_float_get(&ccamera, "fisheye_lens"); + bcam->latitude_min = RNA_float_get(&ccamera, "latitude_min"); + bcam->latitude_max = RNA_float_get(&ccamera, "latitude_max"); + bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min"); + bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max"); bcam->ortho_scale = b_camera.ortho_scale(); @@ -332,6 +340,11 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->panorama_type = bcam->panorama_type; cam->fisheye_fov = bcam->fisheye_fov; cam->fisheye_lens = bcam->fisheye_lens; + cam->latitude_min = bcam->latitude_min; + cam->latitude_max = bcam->latitude_max; + + cam->longitude_min = bcam->longitude_min; + cam->longitude_max = bcam->longitude_max; /* anamorphic lens bokeh */ cam->aperture_ratio = bcam->aperture_ratio; diff --git a/intern/cycles/kernel/kernel_projection.h b/intern/cycles/kernel/kernel_projection.h index 6744471d659..ab63f460371 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_2_PI_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_2_PI_F, M_PI_F, -M_PI_F, M_PI_F)); +} + /* Fisheye <-> Cartesian direction */ ccl_device float2 direction_to_fisheye(float3 dir, float fov) @@ -180,7 +190,7 @@ 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_FISHEYE_EQUIDISTANT: return fisheye_to_direction(u, v, kernel_data.cam.fisheye_fov); case PANORAMA_FISHEYE_EQUISOLID: @@ -194,7 +204,7 @@ 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_FISHEYE_EQUIDISTANT: return direction_to_fisheye(dir, kernel_data.cam.fisheye_fov); case PANORAMA_FISHEYE_EQUISOLID: diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index a230acb2fbc..77d3ea874d0 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -767,6 +767,7 @@ typedef struct KernelCamera { int panorama_type; float fisheye_fov; float fisheye_lens; + float4 equirectangular_range; /* matrices */ Transform cameratoworld; diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 54f1be2f384..5b0d51e60c2 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -47,6 +47,10 @@ Camera::Camera() panorama_type = PANORAMA_EQUIRECTANGULAR; fisheye_fov = M_PI_F; fisheye_lens = 10.5f; + latitude_min = -M_PI_2_F; + latitude_max = M_PI_2_F; + longitude_min = -M_PI_F; + longitude_max = M_PI_F; fov = M_PI_4_F; sensorwidth = 0.036f; @@ -253,6 +257,8 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) kcam->panorama_type = panorama_type; kcam->fisheye_fov = fisheye_fov; kcam->fisheye_lens = fisheye_lens; + kcam->equirectangular_range = make_float4(longitude_min - longitude_max, -longitude_min, + latitude_min - latitude_max, -latitude_min + M_PI_2_F); /* sensor size */ kcam->sensorwidth = sensorwidth; @@ -316,7 +322,11 @@ bool Camera::modified(const Camera& cam) (aperture_ratio == cam.aperture_ratio) && (panorama_type == cam.panorama_type) && (fisheye_fov == cam.fisheye_fov) && - (fisheye_lens == cam.fisheye_lens)); + (fisheye_lens == cam.fisheye_lens) && + (latitude_min == cam.latitude_min) && + (latitude_max == cam.latitude_max) && + (longitude_min == cam.longitude_min) && + (longitude_max == cam.longitude_max)); } bool Camera::motion_modified(const Camera& cam) diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index f809c060741..9525cce8109 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -53,6 +53,10 @@ public: PanoramaType panorama_type; float fisheye_fov; float fisheye_lens; + float latitude_min; + float latitude_max; + float longitude_min; + float longitude_max; /* anamorphic lens bokeh */ float aperture_ratio; |