From aa31d9be80c832bdaaec44c38cb5ac80d6faaeca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Thu, 4 May 2023 16:33:55 +0200 Subject: [PATCH] Metal: Fix Workbench-Next shader compilation errors --- .../shaders/infos/workbench_shadow_info.hh | 2 -- .../workbench_shadow_caps_vert_no_geom.glsl | 27 ++++++++++++++++-- .../shaders/workbench_shadow_geom.glsl | 4 +++ .../shaders/workbench_shadow_vert.glsl | 2 +- .../workbench_shadow_vert_no_geom.glsl | 28 ++++++++++++++++--- 5 files changed, 53 insertions(+), 10 deletions(-) diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_shadow_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_shadow_info.hh index a81c1b5712e..267dd69ffd4 100644 --- a/source/blender/draw/engines/workbench/shaders/infos/workbench_shadow_info.hh +++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_shadow_info.hh @@ -29,10 +29,8 @@ GPU_SHADER_CREATE_INFO(workbench_shadow_common_geom) GPU_SHADER_CREATE_INFO(workbench_next_shadow_common) .vertex_in(0, Type::VEC3, "pos") - .vertex_out(workbench_shadow_iface) .define("WORKBENCH_NEXT") .uniform_buf(1, "ShadowPassData", "pass_data") - .define("lightDirection", "vData[0].light_direction_os") .typedef_source("workbench_shader_shared.h") .additional_info("draw_view") .additional_info("draw_modelmat_new") diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl index b7347ce4864..d4fa0f5f31a 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl @@ -27,6 +27,23 @@ vec4 get_pos(int v, bool backface) return (backface) ? vData[v].backPosition : vData[v].frontPosition; } +vec3 extrude_offset(vec3 ls_P) +{ +#ifdef WORKBENCH_NEXT + vec3 ws_P = point_object_to_world(ls_P); + float extrude_distance = 1e5f; + float L_dot_FP = dot(pass_data.light_direction_ws, pass_data.far_plane.xyz); + if (L_dot_FP > 0.0) { + float signed_distance = dot(pass_data.far_plane.xyz, ws_P) - pass_data.far_plane.w; + extrude_distance = -signed_distance / L_dot_FP; + } + vec3 ls_light_direction = normal_world_to_object(vec3(pass_data.light_direction_ws)); + return ls_light_direction * extrude_distance; +#else + return lightDirection * lightDistance; +#endif +} + void emit_cap(const bool front, bool reversed, int triangle_vertex_id) { /* Inverse. */ @@ -69,18 +86,22 @@ void main() /* Calculate front/back Positions. */ vData[0].frontPosition = point_object_to_ndc(vData[0].pos); - vData[0].backPosition = point_object_to_ndc(vData[0].pos + lightDirection * lightDistance); + vData[0].backPosition = point_object_to_ndc(vData[0].pos + extrude_offset(vData[0].pos)); vData[1].frontPosition = point_object_to_ndc(vData[1].pos); - vData[1].backPosition = point_object_to_ndc(vData[1].pos + lightDirection * lightDistance); + vData[1].backPosition = point_object_to_ndc(vData[1].pos + extrude_offset(vData[1].pos)); vData[2].frontPosition = point_object_to_ndc(vData[2].pos); - vData[2].backPosition = point_object_to_ndc(vData[2].pos + lightDirection * lightDistance); + vData[2].backPosition = point_object_to_ndc(vData[2].pos + extrude_offset(vData[2].pos)); /* Geometry shader equivalent calc. */ vec3 v10 = vData[0].pos - vData[1].pos; vec3 v12 = vData[2].pos - vData[1].pos; +#ifdef WORKBENCH_NEXT + vec3 lightDirection = normal_world_to_object(vec3(pass_data.light_direction_ws)); +#endif + vec3 n = cross(v12, v10); float facing = dot(n, lightDirection); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl index 9902884fc12..91cbe4320a6 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl @@ -42,7 +42,11 @@ void main() } #endif +#ifdef WORKBENCH_NEXT + vec2 facing = vec2(dot(n1, vData[0].light_direction_os), dot(n2, vData[0].light_direction_os)); +#else vec2 facing = vec2(dot(n1, lightDirection), dot(n2, lightDirection)); +#endif /* WATCH: maybe unpredictable in some cases. */ bool is_manifold = any(notEqual(vData[0].pos, vData[3].pos)); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl index 1df514c9081..c011a3b3f57 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl @@ -6,7 +6,7 @@ void main() vData.pos = pos; vData.frontPosition = point_object_to_ndc(pos); #ifdef WORKBENCH_NEXT - vData.light_direction_os = normal_world_to_object(pass_data.light_direction_ws); + vData.light_direction_os = normal_world_to_object(vec3(pass_data.light_direction_ws)); vec3 pos_ws = point_object_to_world(pos); float extrude_distance = 1e5f; float LDoFP = dot(pass_data.light_direction_ws, pass_data.far_plane.xyz); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl index 0da97d5325a..bba91fa2728 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl @@ -58,6 +58,23 @@ void extrude_edge(bool invert, int output_vertex_id) gl_Position.z += 0.00005; } +vec3 extrude_offset(vec3 ls_P) +{ +#ifdef WORKBENCH_NEXT + vec3 ws_P = point_object_to_world(ls_P); + float extrude_distance = 1e5f; + float L_dot_FP = dot(pass_data.light_direction_ws, pass_data.far_plane.xyz); + if (L_dot_FP > 0.0) { + float signed_distance = dot(pass_data.far_plane.xyz, ws_P) - pass_data.far_plane.w; + extrude_distance = -signed_distance / L_dot_FP; + } + vec3 ls_light_direction = normal_world_to_object(vec3(pass_data.light_direction_ws)); + return ls_light_direction * extrude_distance; +#else + return lightDirection * lightDistance; +#endif +} + void main() { /* Output Data indexing. */ @@ -83,16 +100,16 @@ void main() /* Calculate front/back Positions. */ vData[0].frontPosition = point_object_to_ndc(vData[0].pos); - vData[0].backPosition = point_object_to_ndc(vData[0].pos + lightDirection * lightDistance); + vData[0].backPosition = point_object_to_ndc(vData[0].pos + extrude_offset(vData[0].pos)); vData[1].frontPosition = point_object_to_ndc(vData[1].pos); - vData[1].backPosition = point_object_to_ndc(vData[1].pos + lightDirection * lightDistance); + vData[1].backPosition = point_object_to_ndc(vData[1].pos + extrude_offset(vData[1].pos)); vData[2].frontPosition = point_object_to_ndc(vData[2].pos); - vData[2].backPosition = point_object_to_ndc(vData[2].pos + lightDirection * lightDistance); + vData[2].backPosition = point_object_to_ndc(vData[2].pos + extrude_offset(vData[2].pos)); vData[3].frontPosition = point_object_to_ndc(vData[3].pos); - vData[3].backPosition = point_object_to_ndc(vData[3].pos + lightDirection * lightDistance); + vData[3].backPosition = point_object_to_ndc(vData[3].pos + extrude_offset(vData[3].pos)); /* Geometry shader equivalent path. */ vec3 v10 = vData[0].pos - vData[1].pos; @@ -112,6 +129,9 @@ void main() } #endif +#ifdef WORKBENCH_NEXT + vec3 lightDirection = normal_world_to_object(vec3(pass_data.light_direction_ws)); +#endif vec2 facing = vec2(dot(n1, lightDirection), dot(n2, lightDirection)); /* WATCH: maybe unpredictable in some cases. */