Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl')
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl118
1 files changed, 118 insertions, 0 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
new file mode 100644
index 00000000000..5a31aa34932
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
@@ -0,0 +1,118 @@
+#extension GL_ARB_gpu_shader5 : enable
+
+#ifdef GL_ARB_gpu_shader5
+#define USE_INVOC_EXT
+#endif
+
+#ifdef DOUBLE_MANIFOLD
+# ifdef USE_INVOC_EXT
+# define invoc_ct 2
+# else
+# define vert_ct 8
+# endif
+#else
+# ifdef USE_INVOC_EXT
+# define invoc_ct 1
+# else
+# define vert_ct 4
+# endif
+#endif
+
+#ifdef USE_INVOC_EXT
+layout(lines_adjacency, invocations = invoc_ct) in;
+layout(triangle_strip, max_vertices = 4) out;
+#else
+layout(lines_adjacency) in;
+layout(triangle_strip, max_vertices = vert_ct) out;
+#endif
+
+uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
+
+in VertexData {
+ vec3 pos; /* local position */
+ vec4 frontPosition; /* final ndc position */
+ vec4 backPosition;
+} vData[];
+
+#define DEGENERATE_THRESHOLD 1e-12
+
+#define len_sqr(a) dot(a, a)
+
+void extrude_edge(bool invert)
+{
+ /* Reverse order if backfacing the light. */
+ ivec2 idx = (invert) ? ivec2(1, 2) : ivec2(2, 1);
+ gl_Position = vData[idx.x].frontPosition; EmitVertex();
+ gl_Position = vData[idx.y].frontPosition; EmitVertex();
+ gl_Position = vData[idx.x].backPosition; EmitVertex();
+ gl_Position = vData[idx.y].backPosition; EmitVertex();
+ EndPrimitive();
+}
+
+void main()
+{
+ vec3 v10 = vData[0].pos - vData[1].pos;
+ vec3 v12 = vData[2].pos - vData[1].pos;
+ vec3 v13 = vData[3].pos - vData[1].pos;
+
+#ifdef DEGENERATE_THRESHOLD
+ vec3 v20 = vData[0].pos - vData[2].pos;
+ vec3 v23 = vData[3].pos - vData[2].pos;
+
+ vec4 edges_lensqr = vec4(len_sqr(v10), len_sqr(v13), len_sqr(v20), len_sqr(v23));
+ bvec4 degen_edges = lessThan(edges_lensqr, vec4(DEGENERATE_THRESHOLD));
+
+ /* Both triangles are degenerate, abort. */
+ if (any(degen_edges.xz) && any(degen_edges.yw))
+ return;
+#endif
+
+ vec3 n1 = cross(v12, v10);
+ vec3 n2 = cross(v13, v12);
+ vec2 facing = vec2(dot(n1, lightDirection),
+ dot(n2, lightDirection));
+
+ /* WATCH: maybe unpredictable in some cases. */
+ bool is_manifold = any(notEqual(vData[0].pos, vData[3].pos));
+
+ bvec2 backface = greaterThan(facing, vec2(0.0));
+
+#ifdef DEGENERATE_THRESHOLD
+# ifndef DOUBLE_MANIFOLD
+ /* If the mesh is known to be manifold and we don't use double count,
+ * only create an quad if the we encounter a facing geom. */
+ if ((any(degen_edges.xz) && backface.y) ||
+ (any(degen_edges.yw) && backface.x))
+ return;
+# endif
+
+ /* If one of the 2 triangles is degenerate, replace edge by a non-manifold one. */
+ backface.x = (any(degen_edges.xz)) ? !backface.y : backface.x;
+ backface.y = (any(degen_edges.yw)) ? !backface.x : backface.y;
+ is_manifold = (any(degen_edges)) ? false : is_manifold;
+#endif
+
+ /* If both faces face the same direction it's not an outline edge. */
+ if (backface.x == backface.y)
+ return;
+
+#ifdef USE_INVOC_EXT
+ if (gl_InvocationID == 0) {
+ extrude_edge(backface.x);
+ }
+ else if (is_manifold) {
+# ifdef DOUBLE_MANIFOLD
+ /* Increment/Decrement twice for manifold edges. */
+ extrude_edge(backface.x);
+# endif
+ }
+#else
+ extrude_edge(backface.x);
+ if (is_manifold) {
+# ifdef DOUBLE_MANIFOLD
+ /* Increment/Decrement twice for manifold edges. */
+ extrude_edge(backface.x);
+# endif
+ }
+#endif
+}