From 9f0e2d4b724213f1697044f562baddd7306dbe25 Mon Sep 17 00:00:00 2001 From: Rhys Mainwaring Date: Sat, 23 Oct 2021 12:37:39 +0100 Subject: [PATCH] [Metal] update shaders to fix lidar near plane clipping - Update Metal shaders to match changes made in PR #356 - Update CrossPlatformSettings_piece to #define outVs_gl_ClipDistance - Update Ign_piece_vs_any to use cross platform version of gl_ClipDistance - cherry-pick a2a37602ed98822d4e4289a5616c8f3f3c4cf76c Signed-off-by: Rhys Mainwaring --- .../GLSL/CrossPlatformSettings_piece_all.glsl | 1 + .../HLSL/CrossPlatformSettings_piece_all.hlsl | 1 + .../Metal/CrossPlatformSettings_piece_all.metal | 1 + ogre2/src/media/Hlms/Ignition/Ign_piece_vs.any | 2 +- .../programs/Metal/plain_color_vs.metal | 16 ++++++++++++++++ .../media/materials/scripts/gpu_rays.material | 3 +++ .../src/media/materials/scripts/picker.material | 3 +++ .../src/media/materials/scripts/thermal.material | 3 +++ 8 files changed, 29 insertions(+), 1 deletion(-) diff --git a/ogre2/src/media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl b/ogre2/src/media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl index 44b3e0af5..a6cdd4c8f 100644 --- a/ogre2/src/media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl +++ b/ogre2/src/media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl @@ -92,6 +92,7 @@ #define outVs_Position gl_Position #define outVs_viewportIndex gl_ViewportIndex +#define outVs_clipDistance gl_ClipDistance #define outVs_clipDistance0 gl_ClipDistance[0] #define gl_SampleMaskIn0 gl_SampleMaskIn[0] diff --git a/ogre2/src/media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl b/ogre2/src/media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl index f5e17e02d..0b4913410 100644 --- a/ogre2/src/media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl +++ b/ogre2/src/media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl @@ -49,6 +49,7 @@ #define outVs_Position outVs.gl_Position #define outVs_viewportIndex outVs.gl_ViewportIndex +#define outVs_clipDistance outVs.gl_ClipDistance #define outVs_clipDistance0 outVs.gl_ClipDistance0.x #define gl_SampleMaskIn0 gl_SampleMask diff --git a/ogre2/src/media/Hlms/Common/Metal/CrossPlatformSettings_piece_all.metal b/ogre2/src/media/Hlms/Common/Metal/CrossPlatformSettings_piece_all.metal index b20ae2372..336f10ee1 100644 --- a/ogre2/src/media/Hlms/Common/Metal/CrossPlatformSettings_piece_all.metal +++ b/ogre2/src/media/Hlms/Common/Metal/CrossPlatformSettings_piece_all.metal @@ -72,6 +72,7 @@ inline float3x3 toMat3x3( float3x4 m ) #define outVs_Position outVs.gl_Position #define outVs_viewportIndex outVs.gl_ViewportIndex +#define outVs_clipDistance outVs.gl_ClipDistance #define outVs_clipDistance0 outVs.gl_ClipDistance[0] #define gl_SampleMaskIn0 gl_SampleMask diff --git a/ogre2/src/media/Hlms/Ignition/Ign_piece_vs.any b/ogre2/src/media/Hlms/Ignition/Ign_piece_vs.any index 757b8166a..1c989d4ce 100644 --- a/ogre2/src/media/Hlms/Ignition/Ign_piece_vs.any +++ b/ogre2/src/media/Hlms/Ignition/Ign_piece_vs.any @@ -8,7 +8,7 @@ // Ogre 2.2 should use outVs_clipDistanceN for compatibility with all // APIs // Rare case of geometry without normals. - gl_ClipDistance[@value(ign_spherical_clip_idx)] = + outVs_clipDistance[@value(ign_spherical_clip_idx)] = distance( worldPos.xyz, passBuf.ignCameraPos.xyz ) - passBuf.ignMinClipDistance; @end diff --git a/ogre2/src/media/materials/programs/Metal/plain_color_vs.metal b/ogre2/src/media/materials/programs/Metal/plain_color_vs.metal index d6b4554e7..6b0ee7be8 100644 --- a/ogre2/src/media/materials/programs/Metal/plain_color_vs.metal +++ b/ogre2/src/media/materials/programs/Metal/plain_color_vs.metal @@ -26,11 +26,14 @@ struct VS_INPUT struct PS_INPUT { float4 gl_Position [[position]]; + float gl_ClipDistance [[clip_distance]] [1]; }; struct Params { float4x4 worldViewProj; + float4x4 worldView; + float ignMinClipDistance; }; vertex PS_INPUT main_metal @@ -43,5 +46,18 @@ vertex PS_INPUT main_metal outVs.gl_Position = ( p.worldViewProj * input.position ).xyzw; + if( p.ignMinClipDistance > 0.0f ) + { + // Frustum is rectangular; but the minimum lidar distance is spherical, + // so we can't rely on near plane to clip geometry that is too close, + // we have to do it by hand + float3 viewSpacePos = (p.worldView * input.position).xyz; + outVs.gl_ClipDistance[0] = length( viewSpacePos.xyz ) - p.ignMinClipDistance; + } + else + { + outVs.gl_ClipDistance[0] = 1.0f; + } + return outVs; } diff --git a/ogre2/src/media/materials/scripts/gpu_rays.material b/ogre2/src/media/materials/scripts/gpu_rays.material index a95301e56..0d50ca9c5 100644 --- a/ogre2/src/media/materials/scripts/gpu_rays.material +++ b/ogre2/src/media/materials/scripts/gpu_rays.material @@ -198,10 +198,13 @@ fragment_program laser_retro_fs_GLSL glsl vertex_program laser_retro_vs_Metal metal { source plain_color_vs.metal + num_clip_distances 1 default_params { param_named_auto worldViewProj worldviewproj_matrix + param_named_auto worldView worldview_matrix + param_named ignMinClipDistance float 0.0 } } diff --git a/ogre2/src/media/materials/scripts/picker.material b/ogre2/src/media/materials/scripts/picker.material index b95b79693..a849b51b0 100644 --- a/ogre2/src/media/materials/scripts/picker.material +++ b/ogre2/src/media/materials/scripts/picker.material @@ -26,10 +26,13 @@ fragment_program plaincolor_fs_GLSL glsl vertex_program plaincolor_vs_Metal metal { source plain_color_vs.metal + num_clip_distances 1 default_params { param_named_auto worldViewProj worldviewproj_matrix + param_named_auto worldView worldview_matrix + param_named ignMinClipDistance float 0.0 } } diff --git a/ogre2/src/media/materials/scripts/thermal.material b/ogre2/src/media/materials/scripts/thermal.material index 1c7b0b6f9..c6be0f2e1 100644 --- a/ogre2/src/media/materials/scripts/thermal.material +++ b/ogre2/src/media/materials/scripts/thermal.material @@ -115,10 +115,13 @@ fragment_program heat_source_fs_GLSL glsl vertex_program heat_source_vs_Metal metal { source plain_color_vs.metal + num_clip_distances 1 default_params { param_named_auto worldViewProj worldviewproj_matrix + param_named_auto worldView worldview_matrix + param_named ignMinClipDistance float 0.0 } }