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:
authorMai Lavelle <mai.lavelle@gmail.com>2018-01-12 04:14:27 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-01-13 01:57:45 +0300
commit5bd9b12dc47d6fcfb21025101b41802bb5b2edc0 (patch)
tree71564a0cb96ca9e0f0b83a1b24eb76431c310fff /intern/cycles/kernel
parentb603792fec45b2f9563929c76e95ad3b7270797b (diff)
Cycles: adaptive subdivision support for panoramic cameras.
Adds the code to get screen size of a point in world space, which is used for subdividing geometry to the correct level. The approximate method of treating the point as if it were directly in front of the camera is used, as panoramic projections can become very distorted near the edges of an image. This should be fine for most uses. There is also no support yet for offscreen dicing scale, though panorama cameras are often used for rendering 360° renders anyway. Fixes T49254. Differential Revision: https://developer.blender.org/D2468
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/geom/geom_primitive.h6
-rw-r--r--intern/cycles/kernel/kernel_camera.h64
-rw-r--r--intern/cycles/kernel/kernel_projection.h36
3 files changed, 53 insertions, 53 deletions
diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h
index 90a9c2147cc..60a1e483b84 100644
--- a/intern/cycles/kernel/geom/geom_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -216,19 +216,19 @@ ccl_device_inline float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *
else {
tfm = kernel_data.cam.worldtocamera;
motion_center = normalize(transform_point(&tfm, center));
- motion_center = float2_to_float3(direction_to_panorama(kg, motion_center));
+ motion_center = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_center));
motion_center.x *= kernel_data.cam.width;
motion_center.y *= kernel_data.cam.height;
tfm = kernel_data.cam.motion.pre;
motion_pre = normalize(transform_point(&tfm, motion_pre));
- motion_pre = float2_to_float3(direction_to_panorama(kg, motion_pre));
+ motion_pre = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_pre));
motion_pre.x *= kernel_data.cam.width;
motion_pre.y *= kernel_data.cam.height;
tfm = kernel_data.cam.motion.post;
motion_post = normalize(transform_point(&tfm, motion_post));
- motion_post = float2_to_float3(direction_to_panorama(kg, motion_post));
+ motion_post = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_post));
motion_post.x *= kernel_data.cam.width;
motion_post.y *= kernel_data.cam.height;
}
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 77e3446329a..96cdb04d955 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -18,9 +18,9 @@ CCL_NAMESPACE_BEGIN
/* Perspective Camera */
-ccl_device float2 camera_sample_aperture(KernelGlobals *kg, float u, float v)
+ccl_device float2 camera_sample_aperture(ccl_constant KernelCamera *cam, float u, float v)
{
- float blades = kernel_data.cam.blades;
+ float blades = cam->blades;
float2 bokeh;
if(blades == 0.0f) {
@@ -29,12 +29,12 @@ ccl_device float2 camera_sample_aperture(KernelGlobals *kg, float u, float v)
}
else {
/* sample polygon */
- float rotation = kernel_data.cam.bladesrotation;
+ float rotation = cam->bladesrotation;
bokeh = regular_polygon_sample(blades, rotation, u, v);
}
/* anamorphic lens bokeh */
- bokeh.x *= kernel_data.cam.inv_aperture_ratio;
+ bokeh.x *= cam->inv_aperture_ratio;
return bokeh;
}
@@ -76,7 +76,7 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
if(aperturesize > 0.0f) {
/* sample point on aperture */
- float2 lensuv = camera_sample_aperture(kg, lens_u, lens_v)*aperturesize;
+ float2 lensuv = camera_sample_aperture(&kernel_data.cam, lens_u, lens_v)*aperturesize;
/* compute point on plane of focus */
float ft = kernel_data.cam.focaldistance/D.z;
@@ -124,7 +124,7 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
}
else {
/* Spherical stereo */
- spherical_stereo_transform(kg, &P, &D);
+ spherical_stereo_transform(&kernel_data.cam, &P, &D);
ray->P = P;
ray->D = D;
@@ -138,12 +138,12 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
float3 Pcenter = Pnostereo;
float3 Dcenter = Pcamera;
Dcenter = normalize(transform_direction(&cameratoworld, Dcenter));
- spherical_stereo_transform(kg, &Pcenter, &Dcenter);
+ spherical_stereo_transform(&kernel_data.cam, &Pcenter, &Dcenter);
float3 Px = Pnostereo;
float3 Dx = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
Dx = normalize(transform_direction(&cameratoworld, Dx));
- spherical_stereo_transform(kg, &Px, &Dx);
+ spherical_stereo_transform(&kernel_data.cam, &Px, &Dx);
ray->dP.dx = Px - Pcenter;
ray->dD.dx = Dx - Dcenter;
@@ -151,7 +151,7 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
float3 Py = Pnostereo;
float3 Dy = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
Dy = normalize(transform_direction(&cameratoworld, Dy));
- spherical_stereo_transform(kg, &Py, &Dy);
+ spherical_stereo_transform(&kernel_data.cam, &Py, &Dy);
ray->dP.dy = Py - Pcenter;
ray->dD.dy = Dy - Dcenter;
@@ -186,7 +186,7 @@ ccl_device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, fl
if(aperturesize > 0.0f) {
/* sample point on aperture */
- float2 lensuv = camera_sample_aperture(kg, lens_u, lens_v)*aperturesize;
+ float2 lensuv = camera_sample_aperture(&kernel_data.cam, lens_u, lens_v)*aperturesize;
/* compute point on plane of focus */
float3 Pfocus = D * kernel_data.cam.focaldistance;
@@ -238,17 +238,17 @@ ccl_device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, fl
/* Panorama Camera */
-ccl_device_inline void camera_sample_panorama(KernelGlobals *kg,
+ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
float raster_x, float raster_y,
float lens_u, float lens_v,
ccl_addr_space Ray *ray)
{
- Transform rastertocamera = kernel_data.cam.rastertocamera;
+ Transform rastertocamera = cam->rastertocamera;
float3 Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
/* create ray form raster position */
float3 P = make_float3(0.0f, 0.0f, 0.0f);
- float3 D = panorama_to_direction(kg, Pcamera.x, Pcamera.y);
+ float3 D = panorama_to_direction(cam, Pcamera.x, Pcamera.y);
/* indicates ray should not receive any light, outside of the lens */
if(is_zero(D)) {
@@ -257,15 +257,15 @@ ccl_device_inline void camera_sample_panorama(KernelGlobals *kg,
}
/* modify ray for depth of field */
- float aperturesize = kernel_data.cam.aperturesize;
+ float aperturesize = cam->aperturesize;
if(aperturesize > 0.0f) {
/* sample point on aperture */
- float2 lensuv = camera_sample_aperture(kg, lens_u, lens_v)*aperturesize;
+ float2 lensuv = camera_sample_aperture(cam, lens_u, lens_v)*aperturesize;
/* compute point on plane of focus */
float3 Dfocus = normalize(D);
- float3 Pfocus = Dfocus * kernel_data.cam.focaldistance;
+ float3 Pfocus = Dfocus * cam->focaldistance;
/* calculate orthonormal coordinates perpendicular to Dfocus */
float3 U, V;
@@ -278,18 +278,18 @@ ccl_device_inline void camera_sample_panorama(KernelGlobals *kg,
}
/* transform ray from camera to world */
- Transform cameratoworld = kernel_data.cam.cameratoworld;
+ Transform cameratoworld = cam->cameratoworld;
#ifdef __CAMERA_MOTION__
- if(kernel_data.cam.have_motion) {
+ if(cam->have_motion) {
# ifdef __KERNEL_OPENCL__
- const MotionTransform tfm = kernel_data.cam.motion;
+ const MotionTransform tfm = cam->motion;
transform_motion_interpolate(&cameratoworld,
&tfm,
ray->time);
# else
transform_motion_interpolate(&cameratoworld,
- &kernel_data.cam.motion,
+ &cam->motion,
ray->time);
# endif
}
@@ -299,9 +299,9 @@ ccl_device_inline void camera_sample_panorama(KernelGlobals *kg,
D = normalize(transform_direction(&cameratoworld, D));
/* Stereo transform */
- bool use_stereo = kernel_data.cam.interocular_offset != 0.0f;
+ bool use_stereo = cam->interocular_offset != 0.0f;
if(use_stereo) {
- spherical_stereo_transform(kg, &P, &D);
+ spherical_stereo_transform(cam, &P, &D);
}
ray->P = P;
@@ -313,30 +313,30 @@ ccl_device_inline void camera_sample_panorama(KernelGlobals *kg,
* ray origin and direction for the center and two neighbouring pixels
* and simply take their differences. */
float3 Pcenter = Pcamera;
- float3 Dcenter = panorama_to_direction(kg, Pcenter.x, Pcenter.y);
+ float3 Dcenter = panorama_to_direction(cam, Pcenter.x, Pcenter.y);
Pcenter = transform_point(&cameratoworld, Pcenter);
Dcenter = normalize(transform_direction(&cameratoworld, Dcenter));
if(use_stereo) {
- spherical_stereo_transform(kg, &Pcenter, &Dcenter);
+ spherical_stereo_transform(cam, &Pcenter, &Dcenter);
}
float3 Px = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
- float3 Dx = panorama_to_direction(kg, Px.x, Px.y);
+ float3 Dx = panorama_to_direction(cam, Px.x, Px.y);
Px = transform_point(&cameratoworld, Px);
Dx = normalize(transform_direction(&cameratoworld, Dx));
if(use_stereo) {
- spherical_stereo_transform(kg, &Px, &Dx);
+ spherical_stereo_transform(cam, &Px, &Dx);
}
ray->dP.dx = Px - Pcenter;
ray->dD.dx = Dx - Dcenter;
float3 Py = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
- float3 Dy = panorama_to_direction(kg, Py.x, Py.y);
+ float3 Dy = panorama_to_direction(cam, Py.x, Py.y);
Py = transform_point(&cameratoworld, Py);
Dy = normalize(transform_direction(&cameratoworld, Dy));
if(use_stereo) {
- spherical_stereo_transform(kg, &Py, &Dy);
+ spherical_stereo_transform(cam, &Py, &Dy);
}
ray->dP.dy = Py - Pcenter;
@@ -345,11 +345,11 @@ ccl_device_inline void camera_sample_panorama(KernelGlobals *kg,
#ifdef __CAMERA_CLIPPING__
/* clipping */
- float nearclip = kernel_data.cam.nearclip;
+ float nearclip = cam->nearclip;
ray->P += nearclip * ray->D;
ray->dP.dx += nearclip * ray->dD.dx;
ray->dP.dy += nearclip * ray->dD.dy;
- ray->t = kernel_data.cam.cliplength;
+ ray->t = cam->cliplength;
#else
ray->t = FLT_MAX;
#endif
@@ -415,7 +415,7 @@ ccl_device_inline void camera_sample(KernelGlobals *kg,
else if(kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
camera_sample_orthographic(kg, raster_x, raster_y, lens_u, lens_v, ray);
else
- camera_sample_panorama(kg, raster_x, raster_y, lens_u, lens_v, ray);
+ camera_sample_panorama(&kernel_data.cam, raster_x, raster_y, lens_u, lens_v, ray);
}
/* Utilities */
@@ -472,7 +472,7 @@ ccl_device_inline float3 camera_world_to_ndc(KernelGlobals *kg, ShaderData *sd,
else
P = normalize(transform_direction(&tfm, P));
- float2 uv = direction_to_panorama(kg, P);
+ float2 uv = direction_to_panorama(&kernel_data.cam, P);
return make_float3(uv.x, uv.y, 0.0f);
}
diff --git a/intern/cycles/kernel/kernel_projection.h b/intern/cycles/kernel/kernel_projection.h
index cbb2442d1dc..4540d733af4 100644
--- a/intern/cycles/kernel/kernel_projection.h
+++ b/intern/cycles/kernel/kernel_projection.h
@@ -195,49 +195,49 @@ ccl_device float2 direction_to_mirrorball(float3 dir)
return make_float2(u, v);
}
-ccl_device_inline float3 panorama_to_direction(KernelGlobals *kg, float u, float v)
+ccl_device_inline float3 panorama_to_direction(ccl_constant KernelCamera *cam, float u, float v)
{
- switch(kernel_data.cam.panorama_type) {
+ switch(cam->panorama_type) {
case PANORAMA_EQUIRECTANGULAR:
- return equirectangular_range_to_direction(u, v, kernel_data.cam.equirectangular_range);
+ return equirectangular_range_to_direction(u, v, cam->equirectangular_range);
case PANORAMA_MIRRORBALL:
return mirrorball_to_direction(u, v);
case PANORAMA_FISHEYE_EQUIDISTANT:
- return fisheye_to_direction(u, v, kernel_data.cam.fisheye_fov);
+ return fisheye_to_direction(u, v, cam->fisheye_fov);
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);
+ return fisheye_equisolid_to_direction(u, v, cam->fisheye_lens,
+ cam->fisheye_fov, cam->sensorwidth, cam->sensorheight);
}
}
-ccl_device_inline float2 direction_to_panorama(KernelGlobals *kg, float3 dir)
+ccl_device_inline float2 direction_to_panorama(ccl_constant KernelCamera *cam, float3 dir)
{
- switch(kernel_data.cam.panorama_type) {
+ switch(cam->panorama_type) {
case PANORAMA_EQUIRECTANGULAR:
- return direction_to_equirectangular_range(dir, kernel_data.cam.equirectangular_range);
+ return direction_to_equirectangular_range(dir, cam->equirectangular_range);
case PANORAMA_MIRRORBALL:
return direction_to_mirrorball(dir);
case PANORAMA_FISHEYE_EQUIDISTANT:
- return direction_to_fisheye(dir, kernel_data.cam.fisheye_fov);
+ return direction_to_fisheye(dir, cam->fisheye_fov);
case PANORAMA_FISHEYE_EQUISOLID:
default:
- return direction_to_fisheye_equisolid(dir, kernel_data.cam.fisheye_lens,
- kernel_data.cam.sensorwidth, kernel_data.cam.sensorheight);
+ return direction_to_fisheye_equisolid(dir, cam->fisheye_lens,
+ cam->sensorwidth, cam->sensorheight);
}
}
-ccl_device_inline void spherical_stereo_transform(KernelGlobals *kg, float3 *P, float3 *D)
+ccl_device_inline void spherical_stereo_transform(ccl_constant KernelCamera *cam, float3 *P, float3 *D)
{
- float interocular_offset = kernel_data.cam.interocular_offset;
+ float interocular_offset = cam->interocular_offset;
/* Interocular offset of zero means either non stereo, or stereo without
* spherical stereo. */
kernel_assert(interocular_offset != 0.0f);
- if(kernel_data.cam.pole_merge_angle_to > 0.0f) {
- const float pole_merge_angle_from = kernel_data.cam.pole_merge_angle_from,
- pole_merge_angle_to = kernel_data.cam.pole_merge_angle_to;
+ if(cam->pole_merge_angle_to > 0.0f) {
+ const float pole_merge_angle_from = cam->pole_merge_angle_from,
+ pole_merge_angle_to = cam->pole_merge_angle_to;
float altitude = fabsf(safe_asinf((*D).z));
if(altitude > pole_merge_angle_to) {
interocular_offset = 0.0f;
@@ -257,7 +257,7 @@ ccl_device_inline void spherical_stereo_transform(KernelGlobals *kg, float3 *P,
/* Convergence distance is FLT_MAX in the case of parallel convergence mode,
* no need to modify direction in this case either. */
- const float convergence_distance = kernel_data.cam.convergence_distance;
+ const float convergence_distance = cam->convergence_distance;
if(convergence_distance != FLT_MAX)
{