diff options
Diffstat (limited to 'source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl')
-rw-r--r-- | source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl new file mode 100644 index 00000000000..948392bd8ee --- /dev/null +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl @@ -0,0 +1,85 @@ +#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 6 +# endif +#else +# ifdef USE_INVOC_EXT +# define invoc_ct 2 +# else +# define vert_ct 6 +# endif +#endif + +#ifdef USE_INVOC_EXT +layout(triangles, invocations = invoc_ct) in; +layout(triangle_strip, max_vertices = 3) out; +#else +layout(triangles) 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[]; + +vec4 get_pos(int v, bool backface) +{ + return (backface) ? vData[v].backPosition : vData[v].frontPosition; +} + +void emit_cap(const bool front, bool reversed) +{ + if (front) { + gl_Position = vData[0].frontPosition; EmitVertex(); + gl_Position = vData[reversed ? 2 : 1].frontPosition; EmitVertex(); + gl_Position = vData[reversed ? 1 : 2].frontPosition; EmitVertex(); + } + else { + gl_Position = vData[0].backPosition; EmitVertex(); + gl_Position = vData[reversed ? 1 : 2].backPosition; EmitVertex(); + gl_Position = vData[reversed ? 2 : 1].backPosition; EmitVertex(); + } + EndPrimitive(); +} + +void main() +{ + vec3 v10 = vData[0].pos - vData[1].pos; + vec3 v12 = vData[2].pos - vData[1].pos; + + vec3 n = cross(v12, v10); + float facing = dot(n, lightDirection); + + bool backface = facing > 0.0; + +#ifdef DOUBLE_MANIFOLD + /* In case of non manifold geom, we only increase/decrease + * the stencil buffer by one but do every faces as they were facing the light. */ + bool invert = backface; +#else + const bool invert = false; + if (!backface) { +#endif +#ifdef USE_INVOC_EXT + bool do_front = (gl_InvocationID & 1) == 0; + emit_cap(do_front, invert); +#else + emit_cap(true, invert); + emit_cap(false, invert); +#endif +#ifndef DOUBLE_MANIFOLD + } +#endif +} |