diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-07-15 15:35:57 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-07-15 20:51:55 +0300 |
commit | 5dcf60e053b9b9e3cb6dbf5c7b9fc783d6af6f3d (patch) | |
tree | 7406f3677c7503506bf0d193b2a9e61c325fa3ab /source/blender | |
parent | f1104c2828868b8ffd6135671f2ff3926365813a (diff) |
DRW: View: Add ViewVecs calculation
This will remove some code duplication between draw engines.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/intern/draw_manager.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.c | 46 | ||||
-rw-r--r-- | source/blender/draw/intern/shaders/common_view_lib.glsl | 4 |
3 files changed, 51 insertions, 0 deletions
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index ab87760942c..a448a94185a 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -380,6 +380,7 @@ typedef struct DRWViewUboStorage { float wininv[4][4]; float clipplanes[6][4]; + float viewvecs[2][4]; /* Should not be here. Not view dependent (only main view). */ float viewcamtexcofac[4]; } DRWViewUboStorage; diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 52238d2ffa4..5dc40bcdc76 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -1656,6 +1656,52 @@ static void draw_view_matrix_state_update(DRWViewUboStorage *storage, mul_m4_m4m4(storage->persmat, winmat, viewmat); invert_m4_m4(storage->persinv, storage->persmat); + + const bool is_persp = (winmat[3][3] == 0.0f); + + /* Near clip distance. */ + storage->viewvecs[0][3] = (is_persp) ? -winmat[3][2] / (winmat[2][2] - 1.0f) : + -(winmat[3][2] + 1.0f) / winmat[2][2]; + + /* Far clip distance. */ + storage->viewvecs[1][3] = (is_persp) ? -winmat[3][2] / (winmat[2][2] + 1.0f) : + -(winmat[3][2] - 1.0f) / winmat[2][2]; + + /* view vectors for the corners of the view frustum. + * Can be used to recreate the world space position easily */ + float view_vecs[4][3] = { + {-1.0f, -1.0f, -1.0f}, + {1.0f, -1.0f, -1.0f}, + {-1.0f, 1.0f, -1.0f}, + {-1.0f, -1.0f, 1.0f}, + }; + + /* convert the view vectors to view space */ + for (int i = 0; i < 4; i++) { + mul_project_m4_v3(storage->wininv, view_vecs[i]); + /* normalized trick see: + * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */ + if (is_persp) { + /* Divide XY by Z. */ + mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]); + } + } + + /** + * If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and + * view_vecs[1] is the vector going from the near-bottom-left corner to + * the far-top-right corner. + * If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner + * when Z = 1, and top-left corner if Z = 1. + * view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed) + * distance from the near plane to the far clip plane. + */ + copy_v3_v3(storage->viewvecs[0], view_vecs[0]); + + /* we need to store the differences */ + storage->viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0]; + storage->viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1]; + storage->viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2]; } /* Create a view with culling. */ diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl index 1054f4d11c9..2188c38ee63 100644 --- a/source/blender/draw/intern/shaders/common_view_lib.glsl +++ b/source/blender/draw/intern/shaders/common_view_lib.glsl @@ -14,6 +14,10 @@ layout(std140) uniform viewBlock vec4 clipPlanes[6]; + /* View frustum corners [NDC(-1.0, -1.0, -1.0) & NDC(1.0, 1.0, 1.0)]. + * Fourth components are near and far values. */ + vec4 ViewVecs[2]; + /* TODO move it elsewhere. */ vec4 CameraTexCoFactors; }; |