2023-10-13 17:59:46 +02:00
|
|
|
/* SPDX-FileCopyrightText: 2018-2023 Blender Authors
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
|
|
2024-10-04 15:48:22 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
2025-09-25 10:57:02 +02:00
|
|
|
#include "draw_view_infos.hh"
|
2024-11-13 12:32:39 +01:00
|
|
|
|
|
|
|
|
SHADER_LIBRARY_CREATE_INFO(draw_view)
|
2024-10-05 10:17:30 +02:00
|
|
|
|
2024-10-04 19:04:40 +02:00
|
|
|
#if !defined(DRAW_VIEW_CREATE_INFO) && !defined(GLSL_CPP_STUBS)
|
2023-10-13 17:59:46 +02:00
|
|
|
# error Missing draw_view additional create info on shader create info
|
|
|
|
|
#endif
|
|
|
|
|
|
2025-03-04 00:45:38 +01:00
|
|
|
/* Returns the current active view. */
|
|
|
|
|
ViewMatrices drw_view()
|
|
|
|
|
{
|
|
|
|
|
return drw_view_buf[drw_view_id];
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 17:59:46 +02:00
|
|
|
/* Returns true if the current view has a perspective projection matrix. */
|
|
|
|
|
bool drw_view_is_perspective()
|
|
|
|
|
{
|
2025-04-11 18:28:45 +02:00
|
|
|
return drw_view().winmat[3][3] == 0.0f;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns the view forward vector, going towards the viewer. */
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_view_forward()
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-03-04 00:45:38 +01:00
|
|
|
return drw_view().viewinv[2].xyz;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns the view origin. */
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_view_position()
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-03-04 00:45:38 +01:00
|
|
|
return drw_view().viewinv[3].xyz;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
2024-04-29 15:19:49 +02:00
|
|
|
/* Positive Z distance from the view origin. Faster than using `drw_point_world_to_view`. */
|
2025-04-14 13:46:41 +02:00
|
|
|
float drw_view_z_distance(float3 P)
|
2024-04-29 15:19:49 +02:00
|
|
|
{
|
|
|
|
|
return dot(P - drw_view_position(), -drw_view_forward());
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 17:59:46 +02:00
|
|
|
/* Returns the projection matrix far clip distance. */
|
|
|
|
|
float drw_view_far()
|
|
|
|
|
{
|
|
|
|
|
if (drw_view_is_perspective()) {
|
2025-04-11 18:28:45 +02:00
|
|
|
return -drw_view().winmat[3][2] / (drw_view().winmat[2][2] + 1.0f);
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
2025-04-11 18:28:45 +02:00
|
|
|
return -(drw_view().winmat[3][2] - 1.0f) / drw_view().winmat[2][2];
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns the projection matrix near clip distance. */
|
|
|
|
|
float drw_view_near()
|
|
|
|
|
{
|
|
|
|
|
if (drw_view_is_perspective()) {
|
2025-04-11 18:28:45 +02:00
|
|
|
return -drw_view().winmat[3][2] / (drw_view().winmat[2][2] - 1.0f);
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
2025-04-11 18:28:45 +02:00
|
|
|
return -(drw_view().winmat[3][2] + 1.0f) / drw_view().winmat[2][2];
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the world incident vector `V` (going towards the viewer)
|
|
|
|
|
* from the world position `P` and the current view.
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_world_incident_vector(float3 P)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
|
|
|
|
return drw_view_is_perspective() ? normalize(drw_view_position() - P) : drw_view_forward();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the view incident vector `vV` (going towards the viewer)
|
|
|
|
|
* from the view position `vP` and the current view.
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_view_incident_vector(float3 vP)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
return drw_view_is_perspective() ? normalize(-vP) : float3(0.0f, 0.0f, 1.0f);
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Transform position on screen UV space [0..1] to Normalized Device Coordinate space [-1..1].
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_screen_to_ndc(float3 ss_P)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-04-11 18:28:45 +02:00
|
|
|
return ss_P * 2.0f - 1.0f;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
float2 drw_screen_to_ndc(float2 ss_P)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-04-11 18:28:45 +02:00
|
|
|
return ss_P * 2.0f - 1.0f;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
float drw_screen_to_ndc(float ss_P)
|
|
|
|
|
{
|
2025-04-11 18:28:45 +02:00
|
|
|
return ss_P * 2.0f - 1.0f;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Transform position in Normalized Device Coordinate [-1..1] to screen UV space [0..1].
|
|
|
|
|
*/
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_ndc_to_screen(float3 ndc_P)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-04-11 18:28:45 +02:00
|
|
|
return ndc_P * 0.5f + 0.5f;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
float2 drw_ndc_to_screen(float2 ndc_P)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-04-11 18:28:45 +02:00
|
|
|
return ndc_P * 0.5f + 0.5f;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
float drw_ndc_to_screen(float ndc_P)
|
|
|
|
|
{
|
2025-04-11 18:28:45 +02:00
|
|
|
return ndc_P * 0.5f + 0.5f;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Transform Normal
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_normal_view_to_world(float3 vN)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-03-04 00:45:38 +01:00
|
|
|
return (to_float3x3(drw_view().viewinv) * vN);
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_normal_world_to_view(float3 N)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-03-04 00:45:38 +01:00
|
|
|
return (to_float3x3(drw_view().viewmat) * N);
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Transform Position
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_perspective_divide(float4 hs_P)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
|
|
|
|
return hs_P.xyz / hs_P.w;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_point_view_to_world(float3 vP)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
return (drw_view().viewinv * float4(vP, 1.0f)).xyz;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 drw_point_view_to_homogenous(float3 vP)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
return (drw_view().winmat * float4(vP, 1.0f));
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_point_view_to_ndc(float3 vP)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
|
|
|
|
return drw_perspective_divide(drw_point_view_to_homogenous(vP));
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_point_world_to_view(float3 P)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
return (drw_view().viewmat * float4(P, 1.0f)).xyz;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
float4 drw_point_world_to_homogenous(float3 P)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
return (drw_view().winmat * (drw_view().viewmat * float4(P, 1.0f)));
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_point_world_to_ndc(float3 P)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
|
|
|
|
return drw_perspective_divide(drw_point_world_to_homogenous(P));
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_point_ndc_to_view(float3 ssP)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
return drw_perspective_divide(drw_view().wininv * float4(ssP, 1.0f));
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_point_ndc_to_world(float3 ssP)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
|
|
|
|
return drw_point_view_to_world(drw_point_ndc_to_view(ssP));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2023-10-14 13:49:50 +11:00
|
|
|
/** \name Transform Screen Positions
|
2023-10-13 17:59:46 +02:00
|
|
|
* \{ */
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_point_view_to_screen(float3 vP)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
|
|
|
|
return drw_ndc_to_screen(drw_point_view_to_ndc(vP));
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_point_world_to_screen(float3 vP)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
|
|
|
|
return drw_ndc_to_screen(drw_point_world_to_ndc(vP));
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_point_screen_to_view(float3 ssP)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
|
|
|
|
return drw_point_ndc_to_view(drw_screen_to_ndc(ssP));
|
|
|
|
|
}
|
2025-04-14 13:46:41 +02:00
|
|
|
float3 drw_point_screen_to_world(float3 ssP)
|
2023-10-13 17:59:46 +02:00
|
|
|
{
|
|
|
|
|
return drw_point_view_to_world(drw_point_screen_to_view(ssP));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float drw_depth_view_to_screen(float v_depth)
|
|
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
return drw_point_view_to_screen(float3(0.0f, 0.0f, v_depth)).z;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
float drw_depth_screen_to_view(float ss_depth)
|
|
|
|
|
{
|
2025-04-14 13:46:41 +02:00
|
|
|
return drw_point_screen_to_view(float3(0.0f, 0.0f, ss_depth)).z;
|
2023-10-13 17:59:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|