Cycles Aperture Ratio - option to produce anamorphic bokeh
authorDalai Felinto <dfelinto@gmail.com>
Wed, 27 Aug 2014 08:51:50 +0000 (10:51 +0200)
committerDalai Felinto <dfelinto@gmail.com>
Wed, 27 Aug 2014 08:51:50 +0000 (10:51 +0200)
Thanks for Aldo Zang for the help with the fix for the panorama/fisheye
depth of field calculation and the overall math.

Reviewed By: sergey, dingto

Subscribers: juicyfruit, gregzaal, #cycles, dingto, matray

Differential Revision: https://developer.blender.org/D753

intern/cycles/app/cycles_xml.cpp
intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_camera.cpp
intern/cycles/kernel/kernel_camera.h
intern/cycles/kernel/kernel_types.h
intern/cycles/render/camera.cpp
intern/cycles/render/camera.h

index 915ef96a517739c5ed2490271e02616ee6b6d4a8..6c001f8889bc08d415173457761fb1d99de1dc7a 100644 (file)
@@ -329,6 +329,7 @@ static void xml_read_camera(const XMLReadState& state, pugi::xml_node node)
        xml_read_float(&cam->aperturesize, node, "aperturesize"); // 0.5*focallength/fstop
        xml_read_float(&cam->focaldistance, node, "focaldistance");
        xml_read_float(&cam->shuttertime, node, "shuttertime");
+       xml_read_float(&cam->aperture_ratio, node, "aperture_ratio");
 
        if(xml_equal_string(node, "type", "orthographic"))
                cam->type = CAMERA_ORTHOGRAPHIC;
index b4a1b10f8b4e7009d1203679bab49c5947605d62..59e60a9eef1a7c4d2d80d028497426bf7144fbb0 100644 (file)
@@ -544,6 +544,13 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
                 subtype='ANGLE',
                 default=0,
                 )
+        cls.aperture_ratio = FloatProperty(
+                name="Aperture Ratio",
+                description="Distortion to simulate anamorphic lens bokeh",
+                min=0.01, soft_min=1.0, soft_max=2.0,
+                default=1.0,
+                precision=4,
+                )
         cls.panorama_type = EnumProperty(
                 name="Panorama Type",
                 description="Distortion to use for the calculation",
index fa827c3b1dc2b15e1ce4ffb9316ebc55c2e1193d..aab9f83d0eda0f3417f34bf0bee98f47e8f0d2bc 100644 (file)
@@ -468,6 +468,7 @@ class CyclesCamera_PT_dof(CyclesButtonsPanel, Panel):
         sub = col.column(align=True)
         sub.prop(ccam, "aperture_blades", text="Blades")
         sub.prop(ccam, "aperture_rotation", text="Rotation")
+        sub.prop(ccam, "aperture_ratio", text="Ratio")
 
 
 class Cycles_PT_context_material(CyclesButtonsPanel, Panel):
index 1a85561c6d554115ff27f69740086a7e9a339542..ce8c64c4819d223c62ff72073bc7f5b1b90ee8ca 100644 (file)
@@ -46,6 +46,8 @@ struct BlenderCamera {
 
        float2 pixelaspect;
 
+       float aperture_ratio;
+
        PanoramaType panorama_type;
        float fisheye_fov;
        float fisheye_lens;
@@ -167,6 +169,7 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, boo
                bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades");
                bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation");
                bcam->focaldistance = blender_camera_focal_distance(b_ob, b_camera);
+               bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio");
 
                bcam->shift.x = b_camera.shift_x();
                bcam->shift.y = b_camera.shift_y();
@@ -328,6 +331,9 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
        cam->fisheye_fov = bcam->fisheye_fov;
        cam->fisheye_lens = bcam->fisheye_lens;
 
+       /* anamorphic lens bokeh */
+       cam->aperture_ratio = bcam->aperture_ratio;
+
        /* perspective */
        cam->fov = 2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio);
        cam->focaldistance = bcam->focaldistance;
index 6b03abe97080418497de20395e7aa5ff5b0f07ee..5c83358a56d4a0c5b37fb957c609e22188374dab 100644 (file)
@@ -21,16 +21,22 @@ CCL_NAMESPACE_BEGIN
 ccl_device float2 camera_sample_aperture(KernelGlobals *kg, float u, float v)
 {
        float blades = kernel_data.cam.blades;
+       float2 bokeh;
 
        if(blades == 0.0f) {
                /* sample disk */
-               return concentric_sample_disk(u, v);
+               bokeh = concentric_sample_disk(u, v);
        }
        else {
                /* sample polygon */
                float rotation = kernel_data.cam.bladesrotation;
-               return regular_polygon_sample(blades, rotation, u, v);
+               bokeh = regular_polygon_sample(blades, rotation, u, v);
        }
+
+       /* anamorphic lens bokeh */
+       bokeh.x *= kernel_data.cam.inv_aperture_ratio;
+
+       return bokeh;
 }
 
 ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float raster_y, float lens_u, float lens_v, Ray *ray)
@@ -183,7 +189,8 @@ ccl_device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float
 
                /* calculate orthonormal coordinates perpendicular to D */
                float3 U, V;
-               make_orthonormals(D, &U, &V);
+               U = normalize(make_float3(1.0f, 0.0f, 0.0f) -  D.x * D);
+               V = normalize(cross(D, U));
 
                /* update ray for effect of lens */
                ray->P = U * lensuv.x + V * lensuv.y;
index 292283cbbfde9ed9b0c332d3411834c2d53a1d30..81306361ea46afb5aa297d234fc05b992ca1733d 100644 (file)
@@ -761,9 +761,12 @@ typedef struct KernelCamera {
        /* render size */
        float width, height;
        int resolution;
+
+       /* anamorphic lens bokeh */
+       float inv_aperture_ratio;
+
        int pad1;
        int pad2;
-       int pad3;
 
        /* more matrices */
        Transform screentoworld;
index 8659fe4f7a3f6239382cc5de0670b2176b7b9c1e..bb0fec759a95369c9e8238a6c9afcb44cc8ce43d 100644 (file)
@@ -38,6 +38,8 @@ Camera::Camera()
        motion.post = transform_identity();
        use_motion = false;
 
+       aperture_ratio = 1.0f;
+
        type = CAMERA_PERSPECTIVE;
        panorama_type = PANORAMA_EQUIRECTANGULAR;
        fisheye_fov = M_PI_F;
@@ -241,6 +243,9 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
        /* type */
        kcam->type = type;
 
+       /* anamorphic lens bokeh */
+       kcam->inv_aperture_ratio = 1.0f / aperture_ratio;
+
        /* panorama */
        kcam->panorama_type = panorama_type;
        kcam->fisheye_fov = fisheye_fov;
@@ -291,6 +296,7 @@ bool Camera::modified(const Camera& cam)
                (viewplane == cam.viewplane) &&
                (border == cam.border) &&
                (matrix == cam.matrix) &&
+               (aperture_ratio == cam.aperture_ratio) &&
                (panorama_type == cam.panorama_type) &&
                (fisheye_fov == cam.fisheye_fov) &&
                (fisheye_lens == cam.fisheye_lens));
index c28670bc55f14c8e6a98c0a6f85e49bc55858b8d..50889968a90141fc4ed485e632b890d2e15357b2 100644 (file)
@@ -54,6 +54,9 @@ public:
        float fisheye_fov;
        float fisheye_lens;
 
+       /* anamorphic lens bokeh */
+       float aperture_ratio;
+
        /* sensor */
        float sensorwidth;
        float sensorheight;