Fisheye Camera for Cycles

For sample images see:
http://www.dalaifelinto.com/?p=399 (equisolid)
http://www.dalaifelinto.com/?p=389 (equidistant)

The 'use_panorama' option is now part of a new Camera type: 'Panorama'.
Created two other panorama cameras:

- Equisolid: most of lens in the market simulate this lens - e.g. Nikon, Canon, ...)
             this works as a real lens up to an extent. The final result takes the
             sensor dimensions into account also.
             .:. to simulate a Nikon DX2S with a 10.5mm lens do:
                 sensor: 23.7 x 15.7
                 fisheye lens: 10.5
                 fisheye fov: 180
                 render dimensions: 4288 x 2848

- Equidistant: this is not a real lens model. Although the old equidistant lens simulate
               this lens. The result is always as a circular fisheye that takes the whole sensor
               (in other words, it doesn't take the sensor into consideration).
               This is perfect for fulldomes ;)

               For the UI we have 10 to 360 as soft values and 10 to 3600 as hard values (because we can).


Reference material:
http://www.hdrlabs.com/tutorials/downloads_files/HDRI%20for%20CGI.pdf
http://www.bobatkins.com/photography/technical/field_of_view.html

Note, this is not a real simulation of the light path through the lens.
The ideal solution would be this:
https://graphics.stanford.edu/wikis/cs348b-11/Assignment3
http://www.graphics.stanford.edu/papers/camera/


Thanks Brecht for the fix, suggestions and code review.
Kudos for the dome community for keeping me stimulated on the topic since 2009 ;)

Patch partly implemented during lab time at VisGraf, IMPA - Rio de Janeiro.
This commit is contained in:
Dalai Felinto
2012-05-04 16:20:51 +00:00
parent b6edcc4b33
commit d7fbe03a8a
18 changed files with 262 additions and 43 deletions

View File

@@ -141,7 +141,7 @@ void object_camera_mode(RenderData *rd, Object *cam_ob)
if (cam_ob && cam_ob->type==OB_CAMERA) {
Camera *cam= cam_ob->data;
if (cam->type == CAM_ORTHO) rd->mode |= R_ORTHO;
if (cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA;
if (cam->type == CAM_PANO) rd->mode |= R_PANORAMA;
}
}

View File

@@ -138,7 +138,7 @@ UvCameraInfo *project_camera_info(Object *ob, float(*rotmat)[4], float winx, flo
UvCameraInfo uci;
Camera *camera = ob->data;
uci.do_pano = (camera->flag & CAM_PANORAMA);
uci.do_pano = (camera->type == CAM_PANO);
uci.do_persp = (camera->type == CAM_PERSP);
uci.camangle = focallength_to_fov(camera->lens, camera->sensor_x) / 2.0f;

View File

@@ -7398,6 +7398,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 4))
{
Camera *cam;
for (cam = main->camera.first; cam; cam = cam->id.next) {
if (cam->flag & CAM_PANORAMA) {
cam->type = CAM_PANO;
cam->flag &= ~CAM_PANORAMA;
}
}
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */

View File

@@ -67,8 +67,10 @@ void CamerasExporter::operator()(Object *ob, Scene *sce)
Camera *cam = (Camera*)ob->data;
std::string cam_id(get_camera_id(ob));
std::string cam_name(id_name(cam));
if (cam->type == CAM_PERSP) {
switch (cam->type) {
case CAM_PANO:
case CAM_PERSP: {
COLLADASW::PerspectiveOptic persp(mSW);
persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov");
persp.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch), false, "aspect_ratio");
@@ -76,8 +78,11 @@ void CamerasExporter::operator()(Object *ob, Scene *sce)
persp.setZNear(cam->clipsta, false, "znear");
COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name);
addCamera(ccam);
break;
}
else {
case CAM_ORTHO:
default:
{
COLLADASW::OrthographicOptic ortho(mSW);
ortho.setXMag(cam->ortho_scale, "xmag");
ortho.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch), false, "aspect_ratio");
@@ -85,5 +90,6 @@ void CamerasExporter::operator()(Object *ob, Scene *sce)
ortho.setZNear(cam->clipsta, false, "znear");
COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name);
addCamera(ccam);
}
}
break;
}}
}

View File

@@ -48,7 +48,7 @@ typedef struct Camera {
ID id;
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
char type; /* CAM_PERSP or CAM_ORTHO */
char type; /* CAM_PERSP, CAM_ORTHO or CAM_PANO */
char dtx; /* draw type extra */
short flag;
float passepartalpha;
@@ -75,6 +75,7 @@ typedef struct Camera {
/* type */
#define CAM_PERSP 0
#define CAM_ORTHO 1
#define CAM_PANO 2
/* dtx */
#define CAM_DTX_CENTER 1
@@ -94,7 +95,7 @@ typedef struct Camera {
#define CAM_SHOWNAME 16
#define CAM_ANGLETOGGLE 32
#define CAM_DS_EXPAND 64
#define CAM_PANORAMA 128
#define CAM_PANORAMA 128 /* deprecated */
#define CAM_SHOWSENSOR 256
/* yafray: dof sampling switch */

View File

@@ -97,6 +97,7 @@ void RNA_def_camera(BlenderRNA *brna)
static EnumPropertyItem prop_type_items[] = {
{CAM_PERSP, "PERSP", 0, "Perspective", ""},
{CAM_ORTHO, "ORTHO", 0, "Orthographic", ""},
{CAM_PANO, "PANO", 0, "Panoramic", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem prop_draw_type_extra_items[] = {
{CAM_DTX_CENTER, "CENTER", 0, "Center", ""},
@@ -271,12 +272,6 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_lens_unit_items);
RNA_def_property_ui_text(prop, "Lens Unit", "Unit to edit lens in for the user interface");
prop = RNA_def_property(srna, "use_panorama", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_PANORAMA);
RNA_def_property_ui_text(prop, "Panorama",
"Render the scene with a cylindrical camera for pseudo-fisheye lens effects");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
/* pointers */
rna_def_animdata_common(srna);

View File

@@ -193,7 +193,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
if (projectors[i].ob->type == OB_CAMERA) {
cam = (Camera *)projectors[i].ob->data;
if (cam->flag & CAM_PANORAMA) {
if (cam->type == CAM_PANO) {
projectors[i].uci= project_camera_info(projectors[i].ob, NULL, aspx, aspy);
project_camera_info_scale(projectors[i].uci, scax, scay);
free_uci= 1;