Commit: cbe7f9dd03634a29082f51d05a2b1b71c6fc6aef
Author: Sergey Sharybin
Date:   Tue May 17 14:12:29 2016 +0200
Branches: master
https://developer.blender.org/rBcbe7f9dd03634a29082f51d05a2b1b71c6fc6aef

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

===================================================================

M       intern/cycles/blender/blender_camera.cpp
M       intern/cycles/kernel/kernel_projection.h
M       intern/cycles/kernel/kernel_types.h
M       intern/cycles/render/camera.cpp
M       intern/cycles/render/camera.h
M       release/scripts/startup/bl_ui/properties_data_camera.py
M       source/blender/blenkernel/intern/camera.c
M       source/blender/blenloader/intern/versioning_270.c
M       source/blender/makesdna/DNA_camera_types.h
M       source/blender/makesrna/intern/rna_camera.c

===================================================================

diff --git a/intern/cycles/blender/blender_camera.cpp 
b/intern/cycles/blender/blender_camera.cpp
index 6b459ae..9dec489 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 c1a359e..8be6742 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 02e69c7..cc261ed 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 ad96473..d992cac 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 684b445..57b9960 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 58a4820..c6fa77a 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 bdf3432..96bac2c 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 58542d0..0ea4078 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 7f2e1aa..6874157 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 fd81f3a..dcb4d65 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)

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to