mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-05-08 14:46:46 +02:00
131 lines
4.2 KiB
GLSL
131 lines
4.2 KiB
GLSL
#version 330 core
|
|
|
|
layout( triangles ) in;
|
|
layout( triangle_strip, max_vertices = 3 ) out;
|
|
|
|
in EyeSpaceVertex {
|
|
vec3 position;
|
|
vec3 normal;
|
|
} gs_in[];
|
|
|
|
out WireframeVertex {
|
|
vec3 position;
|
|
vec3 normal;
|
|
noperspective vec4 edgeA;
|
|
noperspective vec4 edgeB;
|
|
flat int configuration;
|
|
} gs_out;
|
|
|
|
uniform mat4 viewportMatrix;
|
|
|
|
const int infoA[] = int[]( 0, 0, 0, 0, 1, 1, 2 );
|
|
const int infoB[] = int[]( 1, 1, 2, 0, 2, 1, 2 );
|
|
const int infoAd[] = int[]( 2, 2, 1, 1, 0, 0, 0 );
|
|
const int infoBd[] = int[]( 2, 2, 1, 2, 0, 2, 1 );
|
|
|
|
vec2 transformToViewport( const in vec4 p )
|
|
{
|
|
return vec2( viewportMatrix * ( p / p.w ) );
|
|
}
|
|
|
|
void main()
|
|
{
|
|
gs_out.configuration = int(gl_in[0].gl_Position.z < 0) * int(4)
|
|
+ int(gl_in[1].gl_Position.z < 0) * int(2)
|
|
+ int(gl_in[2].gl_Position.z < 0);
|
|
|
|
// If all vertices are behind us, cull the primitive
|
|
if (gs_out.configuration == 7)
|
|
return;
|
|
|
|
// Transform each vertex into viewport space
|
|
vec2 p[3];
|
|
p[0] = transformToViewport( gl_in[0].gl_Position );
|
|
p[1] = transformToViewport( gl_in[1].gl_Position );
|
|
p[2] = transformToViewport( gl_in[2].gl_Position );
|
|
|
|
if (gs_out.configuration == 0)
|
|
{
|
|
// Common configuration where all vertices are within the viewport
|
|
gs_out.edgeA = vec4(0.0);
|
|
gs_out.edgeB = vec4(0.0);
|
|
|
|
// Calculate lengths of 3 edges of triangle
|
|
float a = length( p[1] - p[2] );
|
|
float b = length( p[2] - p[0] );
|
|
float c = length( p[1] - p[0] );
|
|
|
|
// Calculate internal angles using the cosine rule
|
|
float alpha = acos( ( b * b + c * c - a * a ) / ( 2.0 * b * c ) );
|
|
float beta = acos( ( a * a + c * c - b * b ) / ( 2.0 * a * c ) );
|
|
|
|
// Calculate the perpendicular distance of each vertex from the opposing edge
|
|
float ha = abs( c * sin( beta ) );
|
|
float hb = abs( c * sin( alpha ) );
|
|
float hc = abs( b * sin( alpha ) );
|
|
|
|
// Now add this perpendicular distance as a per-vertex property in addition to
|
|
// the position and normal calculated in the vertex shader.
|
|
|
|
// Vertex 0 (a)
|
|
gs_out.edgeA = vec4( ha, 0.0, 0.0, 0.0 );
|
|
gs_out.normal = gs_in[0].normal;
|
|
gs_out.position = gs_in[0].position;
|
|
gl_Position = gl_in[0].gl_Position;
|
|
EmitVertex();
|
|
|
|
// Vertex 1 (b)
|
|
gs_out.edgeA = vec4( 0.0, hb, 0.0, 0.0 );
|
|
gs_out.normal = gs_in[1].normal;
|
|
gs_out.position = gs_in[1].position;
|
|
gl_Position = gl_in[1].gl_Position;
|
|
EmitVertex();
|
|
|
|
// Vertex 2 (c)
|
|
gs_out.edgeA = vec4( 0.0, 0.0, hc, 0.0 );
|
|
gs_out.normal = gs_in[2].normal;
|
|
gs_out.position = gs_in[2].position;
|
|
gl_Position = gl_in[2].gl_Position;
|
|
EmitVertex();
|
|
|
|
// Finish the primitive off
|
|
EndPrimitive();
|
|
}
|
|
else
|
|
{
|
|
// Viewport projection breaks down for one or two vertices.
|
|
// Caclulate what we can here and defer rest to fragment shader.
|
|
// Since this is coherent for the entire primitive the conditional
|
|
// in the fragment shader is still cheap as all concurrent
|
|
// fragment shader invocations will take the same code path.
|
|
|
|
// Copy across the viewport-space points for the (up to) two vertices
|
|
// in the viewport
|
|
gs_out.edgeA.xy = p[infoA[gs_out.configuration]];
|
|
gs_out.edgeB.xy = p[infoB[gs_out.configuration]];
|
|
|
|
// Copy across the viewport-space edge vectors for the (up to) two vertices
|
|
// in the viewport
|
|
gs_out.edgeA.zw = normalize( gs_out.edgeA.xy - p[ infoAd[gs_out.configuration] ] );
|
|
gs_out.edgeB.zw = normalize( gs_out.edgeB.xy - p[ infoBd[gs_out.configuration] ] );
|
|
|
|
// Pass through the other vertex attributes
|
|
gs_out.normal = gs_in[0].normal;
|
|
gs_out.position = gs_in[0].position;
|
|
gl_Position = gl_in[0].gl_Position;
|
|
EmitVertex();
|
|
|
|
gs_out.normal = gs_in[1].normal;
|
|
gs_out.position = gs_in[1].position;
|
|
gl_Position = gl_in[1].gl_Position;
|
|
EmitVertex();
|
|
|
|
gs_out.normal = gs_in[2].normal;
|
|
gs_out.position = gs_in[2].position;
|
|
gl_Position = gl_in[2].gl_Position;
|
|
EmitVertex();
|
|
|
|
// Finish the primitive off
|
|
EndPrimitive();
|
|
}
|
|
}
|