diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-11-21 05:00:03 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-11-21 05:00:03 +0400 |
commit | fdadfde5c5cc2c5b7255834170b32c4d169bdd42 (patch) | |
tree | f681b0c10cf8341d783586874b1c75f4fd7a73db /intern | |
parent | f43e75c4d6decffe813f28b083a54158758ff5f9 (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.cpp | 15 | ||||
-rw-r--r-- | intern/cycles/render/camera.cpp | 27 | ||||
-rw-r--r-- | intern/cycles/render/camera.h | 8 |
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; |