Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2012-05-04 20:20:51 +0400
committerDalai Felinto <dfelinto@gmail.com>2012-05-04 20:20:51 +0400
commitd7fbe03a8a128408c86687ef34273adddccdb347 (patch)
tree26d5768781582b1ed0164c20098449c7700051d9 /intern/cycles/kernel
parentb6edcc4b33e782b4a91a61d1c46136c52a4172c9 (diff)
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.
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/kernel_camera.h42
-rw-r--r--intern/cycles/kernel/kernel_montecarlo.h51
-rw-r--r--intern/cycles/kernel/kernel_path.h7
-rw-r--r--intern/cycles/kernel/kernel_types.h21
4 files changed, 106 insertions, 15 deletions
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index e4b10f6151c..6d49fd96dd7 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -132,16 +132,40 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa
#endif
}
-/* Environment Camera */
+/* Panorama Camera */
-__device void camera_sample_environment(KernelGlobals *kg, float raster_x, float raster_y, Ray *ray)
+__device float3 panorama_to_direction(KernelGlobals *kg, float u, float v, Ray *ray)
+{
+ switch (kernel_data.cam.panorama_type) {
+ case PANORAMA_EQUIRECTANGULAR:
+ return equirectangular_to_direction(u, v);
+ break;
+ case PANORAMA_FISHEYE_EQUIDISTANT:
+ return fisheye_to_direction(u, v, kernel_data.cam.fisheye_fov, ray);
+ break;
+ case PANORAMA_FISHEYE_EQUISOLID:
+ default:
+ return fisheye_equisolid_to_direction(u, v, kernel_data.cam.fisheye_lens, kernel_data.cam.fisheye_fov, kernel_data.cam.sensorwidth, kernel_data.cam.sensorheight, ray);
+ break;
+ }
+}
+
+__device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float raster_y, Ray *ray)
{
Transform rastertocamera = kernel_data.cam.rastertocamera;
float3 Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
/* create ray form raster position */
ray->P = make_float3(0.0f, 0.0f, 0.0f);
- ray->D = equirectangular_to_direction(Pcamera.x, Pcamera.y);
+
+#ifdef __CAMERA_CLIPPING__
+ /* clipping */
+ ray->t = kernel_data.cam.cliplength;
+#else
+ ray->t = FLT_MAX;
+#endif
+
+ ray->D = panorama_to_direction(kg, Pcamera.x, Pcamera.y, ray);
/* transform ray from camera to world */
Transform cameratoworld = kernel_data.cam.cameratoworld;
@@ -161,17 +185,11 @@ __device void camera_sample_environment(KernelGlobals *kg, float raster_x, float
ray->dP.dy = make_float3(0.0f, 0.0f, 0.0f);
Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
- ray->dD.dx = normalize(transform_direction(&cameratoworld, equirectangular_to_direction(Pcamera.x, Pcamera.y))) - ray->D;
+ ray->dD.dx = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y, ray))) - ray->D;
Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
- ray->dD.dy = normalize(transform_direction(&cameratoworld, equirectangular_to_direction(Pcamera.x, Pcamera.y))) - ray->D;
-#endif
+ ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y, ray))) - ray->D;
-#ifdef __CAMERA_CLIPPING__
- /* clipping */
- ray->t = kernel_data.cam.cliplength;
-#else
- ray->t = FLT_MAX;
#endif
}
@@ -198,7 +216,7 @@ __device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, flo
else if(kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
camera_sample_orthographic(kg, raster_x, raster_y, ray);
else
- camera_sample_environment(kg, raster_x, raster_y, ray);
+ camera_sample_panorama(kg, raster_x, raster_y, ray);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h
index 68f007cfd97..3fb4d41ce06 100644
--- a/intern/cycles/kernel/kernel_montecarlo.h
+++ b/intern/cycles/kernel/kernel_montecarlo.h
@@ -224,6 +224,57 @@ __device float3 equirectangular_to_direction(float u, float v)
cos(theta));
}
+/* Fisheye <- Cartesian direction */
+
+__device float3 fisheye_to_direction(float u, float v, float fov, Ray *ray)
+{
+ u = (u - 0.5f) * 2.f;
+ v = (v - 0.5f) * 2.f;
+
+ float r = sqrt(u*u + v*v);
+
+ if (r > 1.0) {
+ ray->t = 0.f;
+ return make_float3(0.f,0.f,0.f);
+ }
+
+ float phi = acosf((r!=0.f)?u/r:0.f);
+ float theta = asinf(r) * (fov / M_PI_F);
+
+ if (v < 0.f) phi = -phi;
+
+ return make_float3(
+ cosf(theta),
+ -cosf(phi)*sinf(theta),
+ sinf(phi)*sinf(theta)
+ );
+}
+
+__device float3 fisheye_equisolid_to_direction(float u, float v, float lens, float fov, float width, float height, Ray *ray)
+{
+ u = (u - 0.5f) * width;
+ v = (v - 0.5f) * height;
+
+ float rmax = 2.f * lens * sinf(fov * 0.5f);
+ float r = sqrt(u*u + v*v);
+
+ if (r > rmax) {
+ ray->t = 0.f;
+ return make_float3(0.f,0.f,0.f);
+ }
+
+ float phi = acosf((r!=0.f)?u/r:0.f);
+ float theta = 2.f * asinf(r/(2.f * lens));
+
+ if (v < 0.f) phi = -phi;
+
+ return make_float3(
+ cosf(theta),
+ -cosf(phi)*sinf(theta),
+ sinf(phi)*sinf(theta)
+ );
+}
+
/* Mirror Ball <-> Cartesion direction */
__device float3 mirrorball_to_direction(float u, float v)
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 87d996ef9e2..d53951a1f34 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -474,7 +474,12 @@ __device void kernel_path_trace(KernelGlobals *kg,
camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, &ray);
/* integrate */
- float4 L = kernel_path_integrate(kg, &rng, sample, ray, buffer);
+ float4 L;
+
+ if (ray.t != 0.f)
+ L = kernel_path_integrate(kg, &rng, sample, ray, buffer);
+ else
+ L = make_float4(0.f, 0.f, 0.f, 0.f);
/* accumulate result in output buffer */
kernel_write_pass_float4(buffer, sample, L);
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 85ee16fc5c6..25ff7f73888 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -268,7 +268,15 @@ typedef enum LightType {
enum CameraType {
CAMERA_PERSPECTIVE,
CAMERA_ORTHOGRAPHIC,
- CAMERA_ENVIRONMENT
+ CAMERA_PANORAMA
+};
+
+/* Panorama Type */
+
+enum PanoramaType {
+ PANORAMA_EQUIRECTANGULAR,
+ PANORAMA_FISHEYE_EQUIDISTANT,
+ PANORAMA_FISHEYE_EQUISOLID
};
/* Differential */
@@ -452,7 +460,11 @@ typedef struct ShaderData {
typedef struct KernelCamera {
/* type */
int type;
- int pad1, pad2, pad3;
+
+ /* panorama */
+ int panorama_type;
+ float fisheye_fov;
+ float fisheye_lens;
/* matrices */
Transform cameratoworld;
@@ -476,6 +488,11 @@ typedef struct KernelCamera {
float nearclip;
float cliplength;
+ /* sensor size */
+ float sensorwidth;
+ float sensorheight;
+ int pad1, pad2;
+
/* more matrices */
Transform screentoworld;
Transform rastertoworld;