Fix #33158: motion vector pass wrong in cycles in some scenes, wrong vectors
due to float precision problem in matrix inverse.
This commit is contained in:
@@ -60,7 +60,7 @@ public:
|
|||||||
return (CUdeviceptr)mem;
|
return (CUdeviceptr)mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cuda_error_string(CUresult result)
|
static const char *cuda_error_string(CUresult result)
|
||||||
{
|
{
|
||||||
switch(result) {
|
switch(result) {
|
||||||
case CUDA_SUCCESS: return "No errors";
|
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)
|
void device_cuda_info(vector<DeviceInfo>& devices)
|
||||||
{
|
{
|
||||||
|
CUresult result;
|
||||||
int count = 0;
|
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;
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
vector<DeviceInfo> display_devices;
|
vector<DeviceInfo> display_devices;
|
||||||
|
|
||||||
|
@@ -89,13 +89,12 @@ void Camera::update()
|
|||||||
Transform ndctoraster = transform_scale(width, height, 1.0f);
|
Transform ndctoraster = transform_scale(width, height, 1.0f);
|
||||||
|
|
||||||
/* raster to screen */
|
/* raster to screen */
|
||||||
Transform screentoraster = ndctoraster;
|
Transform screentondc =
|
||||||
|
|
||||||
screentoraster = ndctoraster *
|
|
||||||
transform_scale(1.0f/(viewplane.right - viewplane.left),
|
transform_scale(1.0f/(viewplane.right - viewplane.left),
|
||||||
1.0f/(viewplane.top - viewplane.bottom), 1.0f) *
|
1.0f/(viewplane.top - viewplane.bottom), 1.0f) *
|
||||||
transform_translate(-viewplane.left, -viewplane.bottom, 0.0f);
|
transform_translate(-viewplane.left, -viewplane.bottom, 0.0f);
|
||||||
|
|
||||||
|
Transform screentoraster = ndctoraster * screentondc;
|
||||||
Transform rastertoscreen = transform_inverse(screentoraster);
|
Transform rastertoscreen = transform_inverse(screentoraster);
|
||||||
|
|
||||||
/* screen to camera */
|
/* screen to camera */
|
||||||
@@ -105,14 +104,24 @@ void Camera::update()
|
|||||||
screentocamera = transform_inverse(transform_orthographic(nearclip, farclip));
|
screentocamera = transform_inverse(transform_orthographic(nearclip, farclip));
|
||||||
else
|
else
|
||||||
screentocamera = transform_identity();
|
screentocamera = transform_identity();
|
||||||
|
|
||||||
|
Transform cameratoscreen = transform_inverse(screentocamera);
|
||||||
|
|
||||||
rastertocamera = screentocamera * rastertoscreen;
|
rastertocamera = screentocamera * rastertoscreen;
|
||||||
|
cameratoraster = screentoraster * cameratoscreen;
|
||||||
|
|
||||||
cameratoworld = matrix;
|
cameratoworld = matrix;
|
||||||
screentoworld = cameratoworld * screentocamera;
|
screentoworld = cameratoworld * screentocamera;
|
||||||
rastertoworld = cameratoworld * rastertocamera;
|
rastertoworld = cameratoworld * rastertocamera;
|
||||||
ndctoworld = rastertoworld * ndctoraster;
|
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 */
|
/* differentials */
|
||||||
if(type == CAMERA_ORTHOGRAPHIC) {
|
if(type == CAMERA_ORTHOGRAPHIC) {
|
||||||
@@ -160,10 +169,10 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
|
|||||||
kcam->rastertoworld = rastertoworld;
|
kcam->rastertoworld = rastertoworld;
|
||||||
kcam->rastertocamera = rastertocamera;
|
kcam->rastertocamera = rastertocamera;
|
||||||
kcam->cameratoworld = cameratoworld;
|
kcam->cameratoworld = cameratoworld;
|
||||||
kcam->worldtoscreen = transform_inverse(screentoworld);
|
kcam->worldtocamera = worldtocamera;
|
||||||
|
kcam->worldtoscreen = worldtoscreen;
|
||||||
kcam->worldtoraster = worldtoraster;
|
kcam->worldtoraster = worldtoraster;
|
||||||
kcam->worldtondc = transform_inverse(ndctoworld);
|
kcam->worldtondc = worldtondc;
|
||||||
kcam->worldtocamera = transform_inverse(cameratoworld);
|
|
||||||
|
|
||||||
/* camera motion */
|
/* camera motion */
|
||||||
kcam->have_motion = 0;
|
kcam->have_motion = 0;
|
||||||
@@ -181,8 +190,8 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(use_motion) {
|
if(use_motion) {
|
||||||
kcam->motion.pre = transform_inverse(motion.pre * rastertocamera);
|
kcam->motion.pre = cameratoraster * transform_inverse(motion.pre);
|
||||||
kcam->motion.post = transform_inverse(motion.post * rastertocamera);
|
kcam->motion.post = cameratoraster * transform_inverse(motion.post);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
kcam->motion.pre = worldtoraster;
|
kcam->motion.pre = worldtoraster;
|
||||||
|
@@ -82,9 +82,15 @@ public:
|
|||||||
Transform screentoworld;
|
Transform screentoworld;
|
||||||
Transform rastertoworld;
|
Transform rastertoworld;
|
||||||
Transform ndctoworld;
|
Transform ndctoworld;
|
||||||
Transform rastertocamera;
|
|
||||||
Transform cameratoworld;
|
Transform cameratoworld;
|
||||||
|
|
||||||
Transform worldtoraster;
|
Transform worldtoraster;
|
||||||
|
Transform worldtoscreen;
|
||||||
|
Transform worldtondc;
|
||||||
|
Transform worldtocamera;
|
||||||
|
|
||||||
|
Transform rastertocamera;
|
||||||
|
Transform cameratoraster;;
|
||||||
|
|
||||||
float3 dx;
|
float3 dx;
|
||||||
float3 dy;
|
float3 dy;
|
||||||
|
Reference in New Issue
Block a user