[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [52417] trunk/blender/intern/cycles: Fix #33158: motion vector pass wrong in cycles in some scenes, wrong vectors

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Nov 21 02:00:09 CET 2012


Revision: 52417
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=52417
Author:   blendix
Date:     2012-11-21 01:00:03 +0000 (Wed, 21 Nov 2012)
Log Message:
-----------
Fix #33158: motion vector pass wrong in cycles in some scenes, wrong vectors
due to float precision problem in matrix inverse.

Modified Paths:
--------------
    trunk/blender/intern/cycles/device/device_cuda.cpp
    trunk/blender/intern/cycles/render/camera.cpp
    trunk/blender/intern/cycles/render/camera.h

Modified: trunk/blender/intern/cycles/device/device_cuda.cpp
===================================================================
--- trunk/blender/intern/cycles/device/device_cuda.cpp	2012-11-21 00:31:47 UTC (rev 52416)
+++ trunk/blender/intern/cycles/device/device_cuda.cpp	2012-11-21 01:00:03 UTC (rev 52417)
@@ -60,7 +60,7 @@
 		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 @@
 
 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;
 	

Modified: trunk/blender/intern/cycles/render/camera.cpp
===================================================================
--- trunk/blender/intern/cycles/render/camera.cpp	2012-11-21 00:31:47 UTC (rev 52416)
+++ trunk/blender/intern/cycles/render/camera.cpp	2012-11-21 01:00:03 UTC (rev 52417)
@@ -89,13 +89,12 @@
 	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,15 +104,25 @@
 		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) {
 		dx = transform_direction(&rastertocamera, make_float3(1, 0, 0));
@@ -160,10 +169,10 @@
 	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 @@
 		}
 		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;

Modified: trunk/blender/intern/cycles/render/camera.h
===================================================================
--- trunk/blender/intern/cycles/render/camera.h	2012-11-21 00:31:47 UTC (rev 52416)
+++ trunk/blender/intern/cycles/render/camera.h	2012-11-21 01:00:03 UTC (rev 52417)
@@ -82,10 +82,16 @@
 	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;
 




More information about the Bf-blender-cvs mailing list