Fix #56355: Cycles: Wrong differentials for panoramic camera
The code to compute differentials mixed up the camera-space locations of the raster coordinate and the camera itself, which caused the dP differential to be set even when the ray origin is always the same. This commit fixes that, reorganizes the code so that the Px/Py are no longer used for both values to avoid future confusion, and skips some unnecessary calculations stereo rendering isn't being used.
This commit is contained in:
parent
aa87b747c5
commit
1f44be97e6
|
@ -224,18 +224,23 @@ ccl_device void camera_sample_orthographic(KernelGlobals kg,
|
|||
|
||||
/* Panorama Camera */
|
||||
|
||||
ccl_device_inline float3 camera_panorama_direction(ccl_constant KernelCamera *cam,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
float3 Pcamera = transform_perspective(&cam->rastertocamera, make_float3(x, y, 0.0f));
|
||||
return panorama_to_direction(cam, Pcamera.x, Pcamera.y);
|
||||
}
|
||||
|
||||
ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
|
||||
ccl_global const DecomposedTransform *cam_motion,
|
||||
const float2 raster,
|
||||
const float2 rand_lens,
|
||||
ccl_private Ray *ray)
|
||||
{
|
||||
ProjectionTransform rastertocamera = cam->rastertocamera;
|
||||
float3 Pcamera = transform_perspective(&rastertocamera, float2_to_float3(raster));
|
||||
|
||||
/* create ray form raster position */
|
||||
float3 P = zero_float3();
|
||||
float3 D = panorama_to_direction(cam, Pcamera.x, Pcamera.y);
|
||||
float3 D = camera_panorama_direction(cam, raster.x, raster.y);
|
||||
|
||||
/* indicates ray should not receive any light, outside of the lens */
|
||||
if (is_zero(D)) {
|
||||
|
@ -246,6 +251,11 @@ ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
|
|||
/* modify ray for depth of field */
|
||||
float aperturesize = cam->aperturesize;
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
/* keep pre-DoF value for differentials later */
|
||||
float3 Dcenter = D;
|
||||
#endif
|
||||
|
||||
if (aperturesize > 0.0f) {
|
||||
/* sample point on aperture */
|
||||
float2 lens_uv = camera_sample_aperture(cam, rand_lens) * aperturesize;
|
||||
|
@ -289,38 +299,32 @@ ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
|
|||
* because we don't want to be affected by depth of field. We compute
|
||||
* ray origin and direction for the center and two neighboring pixels
|
||||
* and simply take their differences. */
|
||||
float3 Pcenter = Pcamera;
|
||||
float3 Dcenter = panorama_to_direction(cam, Pcenter.x, Pcenter.y);
|
||||
float3 Dx = camera_panorama_direction(cam, raster.x + 1.0f, raster.y);
|
||||
float3 Dy = camera_panorama_direction(cam, raster.x, raster.y + 1.0f);
|
||||
|
||||
if (use_stereo) {
|
||||
float3 Pcenter = zero_float3();
|
||||
float3 Px = zero_float3();
|
||||
float3 Py = zero_float3();
|
||||
spherical_stereo_transform(cam, &Pcenter, &Dcenter);
|
||||
}
|
||||
Pcenter = transform_point(&cameratoworld, Pcenter);
|
||||
Dcenter = normalize(transform_direction(&cameratoworld, Dcenter));
|
||||
|
||||
float3 Px = transform_perspective(&rastertocamera, make_float3(raster.x + 1.0f, raster.y, 0.0f));
|
||||
float3 Dx = panorama_to_direction(cam, Px.x, Px.y);
|
||||
if (use_stereo) {
|
||||
spherical_stereo_transform(cam, &Px, &Dx);
|
||||
}
|
||||
Px = transform_point(&cameratoworld, Px);
|
||||
Dx = normalize(transform_direction(&cameratoworld, Dx));
|
||||
|
||||
differential3 dP, dD;
|
||||
dP.dx = Px - Pcenter;
|
||||
dD.dx = Dx - Dcenter;
|
||||
|
||||
float3 Py = transform_perspective(&rastertocamera, make_float3(raster.x, raster.y + 1.0f, 0.0f));
|
||||
float3 Dy = panorama_to_direction(cam, Py.x, Py.y);
|
||||
if (use_stereo) {
|
||||
spherical_stereo_transform(cam, &Py, &Dy);
|
||||
}
|
||||
Py = transform_point(&cameratoworld, Py);
|
||||
Dy = normalize(transform_direction(&cameratoworld, Dy));
|
||||
|
||||
dP.dy = Py - Pcenter;
|
||||
dD.dy = Dy - Dcenter;
|
||||
differential3 dP;
|
||||
Pcenter = transform_point(&cameratoworld, Pcenter);
|
||||
dP.dx = transform_point(&cameratoworld, Px) - Pcenter;
|
||||
dP.dy = transform_point(&cameratoworld, Py) - Pcenter;
|
||||
ray->dP = differential_make_compact(dP);
|
||||
}
|
||||
else {
|
||||
ray->dP = differential_zero_compact();
|
||||
}
|
||||
|
||||
differential3 dD;
|
||||
Dcenter = normalize(transform_direction(&cameratoworld, Dcenter));
|
||||
dD.dx = normalize(transform_direction(&cameratoworld, Dx)) - Dcenter;
|
||||
dD.dy = normalize(transform_direction(&cameratoworld, Dy)) - Dcenter;
|
||||
ray->dD = differential_make_compact(dD);
|
||||
ray->dP = differential_make_compact(dP);
|
||||
#endif
|
||||
|
||||
/* clipping */
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 5e21b8c590ae0375da698df2ec4319055acd438d
|
||||
Subproject commit b9accb676b11fdf7b99253fa82b475b58c98d73e
|
Loading…
Reference in New Issue