Metal: Fix Workbench-Next shader compilation errors

This commit is contained in:
Clément Foucault
2023-05-04 16:33:55 +02:00
parent 6b5b777ca3
commit aa31d9be80
5 changed files with 53 additions and 10 deletions

View File

@@ -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")

View File

@@ -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);

View File

@@ -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));

View File

@@ -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);

View File

@@ -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. */