diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-05-17 15:12:29 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-05-18 11:56:57 +0300 |
commit | cbe7f9dd03634a29082f51d05a2b1b71c6fc6aef (patch) | |
tree | c078fa28ca7fd0484076e4d7bd0a61924ee7d248 | |
parent | 7b356a856540a1affa5dc85360183418e6337a5a (diff) |
Cycles: Pole merging for spherical stereo
The idea of pole merge is to fade interocular distance after a certain
altitude to zero when altitude goes closer to a pole. This should prevent
annoyances looking up in the sky or down to the bottom.
Works for both panorama and perspective cameras when Spherical Stereo
is enabled.
Reviewers: dfelinto, brecht
Reviewed By: brecht
Subscribers: sebastian_k
Differential Revision: https://developer.blender.org/D1998
-rw-r--r-- | intern/cycles/blender/blender_camera.cpp | 11 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_projection.h | 17 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/camera.cpp | 11 | ||||
-rw-r--r-- | intern/cycles/render/camera.h | 3 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_camera.py | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/camera.c | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_270.c | 11 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_camera_types.h | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_camera.c | 18 |
10 files changed, 88 insertions, 3 deletions
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index 6b459ae575f..9dec489ce33 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -65,6 +65,9 @@ struct BlenderCamera { bool use_spherical_stereo; float interocular_distance; float convergence_distance; + bool use_pole_merge; + float pole_merge_angle_from; + float pole_merge_angle_to; enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit; float sensor_width; @@ -183,6 +186,10 @@ static void blender_camera_from_object(BlenderCamera *bcam, } bcam->use_spherical_stereo = b_engine.use_spherical_stereo(b_ob); + bcam->use_pole_merge = b_camera.stereo().use_pole_merge(); + bcam->pole_merge_angle_from = b_camera.stereo().pole_merge_angle_from(); + bcam->pole_merge_angle_to = b_camera.stereo().pole_merge_angle_to(); + bcam->ortho_scale = b_camera.ortho_scale(); bcam->lens = b_camera.lens(); @@ -427,6 +434,10 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->stereo_eye = Camera::STEREO_NONE; } + cam->use_pole_merge = bcam->use_pole_merge; + cam->pole_merge_angle_from = bcam->pole_merge_angle_from; + cam->pole_merge_angle_to = bcam->pole_merge_angle_to; + /* 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 c1a359e9269..8be6742699a 100644 --- a/intern/cycles/kernel/kernel_projection.h +++ b/intern/cycles/kernel/kernel_projection.h @@ -225,7 +225,7 @@ ccl_device float3 spherical_stereo_position(KernelGlobals *kg, float3 dir, float3 pos) { - const float interocular_offset = kernel_data.cam.interocular_offset; + float interocular_offset = kernel_data.cam.interocular_offset; /* Interocular offset of zero means either non stereo, or stereo without * spherical stereo. @@ -234,6 +234,21 @@ ccl_device float3 spherical_stereo_position(KernelGlobals *kg, return pos; } + if(kernel_data.cam.pole_merge_angle_to > 0.0f) { + float3 normalized_direction = normalize(dir); + const float pole_merge_angle_from = kernel_data.cam.pole_merge_angle_from, + pole_merge_angle_to = kernel_data.cam.pole_merge_angle_to; + float altitude = fabsf(safe_asinf(normalized_direction.z)); + if(altitude > pole_merge_angle_to) { + interocular_offset = 0.0f; + } + else if(altitude > pole_merge_angle_from) { + float fac = (altitude - pole_merge_angle_from) / (pole_merge_angle_to - pole_merge_angle_from); + float fade = cosf(fac * M_PI_2_F); + interocular_offset *= fade; + } + } + float3 up = make_float3(0.0f, 0.0f, 1.0f); float3 side = normalize(cross(dir, up)); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 02e69c7d75f..cc261ed37f8 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -909,9 +909,10 @@ typedef struct KernelCamera { float4 equirectangular_range; /* stereo */ - int pad1, pad2; float interocular_offset; float convergence_distance; + float pole_merge_angle_from; + float pole_merge_angle_to; /* matrices */ Transform cameratoworld; diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index ad96473e5d2..d992cac5312 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -76,6 +76,9 @@ Camera::Camera() stereo_eye = STEREO_NONE; interocular_distance = 0.065f; convergence_distance = 30.0f * 0.065f; + use_pole_merge = false; + pole_merge_angle_from = 60.0f * M_PI_F / 180.0f; + pole_merge_angle_to = 75.0f * M_PI_F / 180.0f; sensorwidth = 0.036f; sensorheight = 0.024f; @@ -367,6 +370,14 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) } kcam->convergence_distance = convergence_distance; + if(use_pole_merge) { + kcam->pole_merge_angle_from = pole_merge_angle_from; + kcam->pole_merge_angle_to = pole_merge_angle_to; + } + else { + kcam->pole_merge_angle_from = -1.0f; + kcam->pole_merge_angle_to = -1.0f; + } /* sensor size */ kcam->sensorwidth = sensorwidth; diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 684b4458dfc..57b9960e70b 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -104,6 +104,9 @@ public: bool use_spherical_stereo; float interocular_distance; float convergence_distance; + bool use_pole_merge; + float pole_merge_angle_from; + float pole_merge_angle_to; /* anamorphic lens bokeh */ float aperture_ratio; diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 58a4820e27a..c6fa77aec00 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -165,7 +165,15 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): if is_spherical_stereo: col.separator() - col.prop(st, "use_spherical_stereo") + row = col.row() + row.prop(st, "use_spherical_stereo") + sub = row.row() + sub.active = st.use_spherical_stereo + sub.prop(st, "use_pole_merge") + row = col.row(align=True) + row.active = st.use_pole_merge + row.prop(st, "pole_merge_angle_from") + row.prop(st, "pole_merge_angle_to") col.label(text="Pivot:") row = col.row() diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index bdf3432e6ea..96bac2c2f41 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -76,6 +76,8 @@ void BKE_camera_init(Camera *cam) /* stereoscopy 3d */ cam->stereo.interocular_distance = 0.065f; cam->stereo.convergence_distance = 30.f * 0.065f; + cam->stereo.pole_merge_angle_from = DEG2RAD(60.0f); + cam->stereo.pole_merge_angle_to = DEG2RAD(75.0f); } void *BKE_camera_add(Main *bmain, const char *name) diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 58542d05879..0ea4078a5cb 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -1190,4 +1190,15 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } } + + { + for (Camera *camera = main->camera.first; camera != NULL; camera = camera->id.next) { + if (camera->stereo.pole_merge_angle_from == 0.0f && + camera->stereo.pole_merge_angle_to == 0.0f) + { + camera->stereo.pole_merge_angle_from = DEG2RAD(60.0f); + camera->stereo.pole_merge_angle_to = DEG2RAD(75.0f); + } + } + } } diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h index 7f2e1aaadf9..68741578f27 100644 --- a/source/blender/makesdna/DNA_camera_types.h +++ b/source/blender/makesdna/DNA_camera_types.h @@ -53,6 +53,10 @@ typedef struct CameraStereoSettings { short pivot; short flag; short pad; + /* Cut-off angle at which interocular distance start to fade down. */ + float pole_merge_angle_from; + /* Cut-off angle at which interocular distance stops to fade down. */ + float pole_merge_angle_to; } CameraStereoSettings; typedef struct Camera { @@ -152,6 +156,7 @@ enum { /* stereo->flag */ enum { CAM_S3D_SPHERICAL = (1 << 0), + CAM_S3D_POLE_MERGE = (1 << 1), }; #ifdef __cplusplus diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c index fd81f3aa46c..dcb4d65f3f9 100644 --- a/source/blender/makesrna/intern/rna_camera.c +++ b/source/blender/makesrna/intern/rna_camera.c @@ -151,6 +151,24 @@ static void rna_def_camera_stereo_data(BlenderRNA *brna) "Render every pixel rotating the camera around the " "middle of the interocular distance"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "use_pole_merge", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_S3D_POLE_MERGE); + RNA_def_property_ui_text(prop, "Use Pole Merge", + "Fade interocular distance to 0 after the given cutoff angle"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "pole_merge_angle_from", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_range(prop, 0.0f, M_PI / 2.0f); + RNA_def_property_ui_text(prop, "Pole Merge Start Angle", + "Angle at which interocular distance starts to fade to 0"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "pole_merge_angle_to", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_range(prop, 0.0f, M_PI / 2.0f); + RNA_def_property_ui_text(prop, "Pole Merge End Angle", + "Angle at which interocular distance is 0"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); } void RNA_def_camera(BlenderRNA *brna) |