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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-11-21 05:00:03 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-11-21 05:00:03 +0400
commitfdadfde5c5cc2c5b7255834170b32c4d169bdd42 (patch)
treef681b0c10cf8341d783586874b1c75f4fd7a73db /intern/cycles/render/camera.cpp
parentf43e75c4d6decffe813f28b083a54158758ff5f9 (diff)
Fix #33158: motion vector pass wrong in cycles in some scenes, wrong vectors
due to float precision problem in matrix inverse.
Diffstat (limited to 'intern/cycles/render/camera.cpp')
-rw-r--r--intern/cycles/render/camera.cpp27
1 files changed, 18 insertions, 9 deletions
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 308ebd0794a..32c273c1248 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -89,13 +89,12 @@ void Camera::update()
Transform ndctoraster = transform_scale(width, height, 1.0f);
/* raster to screen */
- Transform screentoraster = ndctoraster;
-
- screentoraster = ndctoraster *
+ Transform screentondc =
transform_scale(1.0f/(viewplane.right - viewplane.left),
1.0f/(viewplane.top - viewplane.bottom), 1.0f) *
transform_translate(-viewplane.left, -viewplane.bottom, 0.0f);
+ Transform screentoraster = ndctoraster * screentondc;
Transform rastertoscreen = transform_inverse(screentoraster);
/* screen to camera */
@@ -105,14 +104,24 @@ void Camera::update()
screentocamera = transform_inverse(transform_orthographic(nearclip, farclip));
else
screentocamera = transform_identity();
+
+ Transform cameratoscreen = transform_inverse(screentocamera);
rastertocamera = screentocamera * rastertoscreen;
+ cameratoraster = screentoraster * cameratoscreen;
cameratoworld = matrix;
screentoworld = cameratoworld * screentocamera;
rastertoworld = cameratoworld * rastertocamera;
ndctoworld = rastertoworld * ndctoraster;
- worldtoraster = transform_inverse(rastertoworld);
+
+ /* note we recompose matrices instead of taking inverses of the above, this
+ * is needed to avoid inverting near degenerate matrices that happen due to
+ * precision issues with large scenes */
+ worldtocamera = transform_inverse(matrix);
+ worldtoscreen = cameratoscreen * worldtocamera;
+ worldtondc = screentondc * worldtoscreen;
+ worldtoraster = ndctoraster * worldtondc;
/* differentials */
if(type == CAMERA_ORTHOGRAPHIC) {
@@ -160,10 +169,10 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kcam->rastertoworld = rastertoworld;
kcam->rastertocamera = rastertocamera;
kcam->cameratoworld = cameratoworld;
- kcam->worldtoscreen = transform_inverse(screentoworld);
+ kcam->worldtocamera = worldtocamera;
+ kcam->worldtoscreen = worldtoscreen;
kcam->worldtoraster = worldtoraster;
- kcam->worldtondc = transform_inverse(ndctoworld);
- kcam->worldtocamera = transform_inverse(cameratoworld);
+ kcam->worldtondc = worldtondc;
/* camera motion */
kcam->have_motion = 0;
@@ -181,8 +190,8 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
}
else {
if(use_motion) {
- kcam->motion.pre = transform_inverse(motion.pre * rastertocamera);
- kcam->motion.post = transform_inverse(motion.post * rastertocamera);
+ kcam->motion.pre = cameratoraster * transform_inverse(motion.pre);
+ kcam->motion.post = cameratoraster * transform_inverse(motion.post);
}
else {
kcam->motion.pre = worldtoraster;