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
path: root/intern
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
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')
-rw-r--r--intern/cycles/device/device_cuda.cpp15
-rw-r--r--intern/cycles/render/camera.cpp27
-rw-r--r--intern/cycles/render/camera.h8
3 files changed, 37 insertions, 13 deletions
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index d797c0f09ca..14f8cfa8767 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -60,7 +60,7 @@ public:
return (CUdeviceptr)mem;
}
- const char *cuda_error_string(CUresult result)
+ static const char *cuda_error_string(CUresult result)
{
switch(result) {
case CUDA_SUCCESS: return "No errors";
@@ -915,12 +915,21 @@ Device *device_cuda_create(DeviceInfo& info, Stats &stats, bool background)
void device_cuda_info(vector<DeviceInfo>& devices)
{
+ CUresult result;
int count = 0;
- if(cuInit(0) != CUDA_SUCCESS)
+ result = cuInit(0);
+ if(result != CUDA_SUCCESS) {
+ if(result != CUDA_ERROR_NO_DEVICE)
+ fprintf(stderr, "CUDA cuInit: %s\n", CUDADevice::cuda_error_string(result));
return;
- if(cuDeviceGetCount(&count) != CUDA_SUCCESS)
+ }
+
+ result = cuDeviceGetCount(&count);
+ if(result != CUDA_SUCCESS) {
+ fprintf(stderr, "CUDA cuDeviceGetCount: %s\n", CUDADevice::cuda_error_string(result));
return;
+ }
vector<DeviceInfo> display_devices;
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;
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 4c2de7b50b8..9696161180d 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -82,9 +82,15 @@ public:
Transform screentoworld;
Transform rastertoworld;
Transform ndctoworld;
- Transform rastertocamera;
Transform cameratoworld;
+
Transform worldtoraster;
+ Transform worldtoscreen;
+ Transform worldtondc;
+ Transform worldtocamera;
+
+ Transform rastertocamera;
+ Transform cameratoraster;;
float3 dx;
float3 dy;