Fix #133576: EEVEE: 'offscreen.draw_view3d' projection matrix broken

This was caused by the input matrix not being used.
Instead EEVEE was trying to derive the projection matrix
again based on the actual viewport state. But this state
was not reflecting the input matrix.

To fix this, we remove any camera setup from the rv3d during
the offscreen drawing and set the lens param to 0.
This ensure EEVEE loads the input projection matrix.
This commit is contained in:
Clément Foucault
2025-02-05 19:36:31 +01:00
parent 9a9e2e19a9
commit 0f9c2e47e5

View File

@@ -1673,6 +1673,8 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
/* #View3D */
eDrawType v3d_shading_type;
Object *v3d_camera;
float v3d_lens;
/* #Region */
int region_winx, region_winy;
@@ -1684,11 +1686,15 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
* Without this the #wmPaintCursor can't use the pixel size & view matrices for drawing.
*/
RV3DMatrixStore *rv3d_mats;
char rv3d_persp;
} orig{};
orig.v3d_shading_type = eDrawType(v3d->shading.type);
orig.v3d_camera = v3d->camera;
orig.v3d_lens = v3d->lens;
orig.region_winx = region->winx;
orig.region_winy = region->winy;
orig.region_winrct = region->winrct;
orig.rv3d_persp = rv3d->persp;
orig.rv3d_mats = ED_view3d_mats_rv3d_backup(static_cast<RegionView3D *>(region->regiondata));
UI_Theme_Store(&orig.theme_state);
@@ -1715,6 +1721,16 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
BKE_image_free_anim_gputextures(G.main);
}
if (viewmat) {
/* WORKAROUND: Disable camera view to avoid EEVEE being confused and try to
* get the projection matrix from the camera.
* Set the `lens` parameter to 0 to make EEVEE prefer the winmat from the rv3d instead of
* trying to redirive it. Note that this produces incorrect result with overscan. */
rv3d->persp = (winmat[3][3] == 0.0f) ? RV3D_PERSP : RV3D_ORTHO;
v3d->camera = nullptr;
v3d->lens = 0.0f;
}
GPU_matrix_push_projection();
GPU_matrix_identity_set();
GPU_matrix_push();
@@ -1758,10 +1774,13 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
ED_view3d_mats_rv3d_restore(static_cast<RegionView3D *>(region->regiondata), orig.rv3d_mats);
}
MEM_freeN(orig.rv3d_mats);
rv3d->persp = orig.rv3d_persp;
UI_Theme_Restore(&orig.theme_state);
v3d->shading.type = orig.v3d_shading_type;
v3d->camera = orig.v3d_camera;
v3d->lens = orig.v3d_lens;
G.f &= ~G_FLAG_RENDER_VIEWPORT;
}