Commit e151d1fc authored by Jan Möbius's avatar Jan Möbius

Fix for wireframe/hiddenline on poly meshes.

refs #2029


git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@18317 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 11fc2296
// declare IO mapping prototype
void sg_MapIO(const int);
// emit a screen aligned quad along the edge v1-v2
void createEdgeQuad(const int v0, const int v1, in vec2 screenSize, in float lineWidth)
{
vec4 p0 = gl_in[v0].gl_Position;
vec4 p1 = gl_in[v1].gl_Position;
// convert to screen space
p0.xy = p0.xy / p0.w * screenSize;
p1.xy = p1.xy / p1.w * screenSize;
// compute dir and normal
vec2 lineDir = p1.xy - p0.xy;
vec2 lineNormal = normalize(vec2(-lineDir.y, lineDir.x));
// create screen-aligned quad
vec2 offset = lineNormal * lineWidth;
sg_MapIO(v0); // default IO mapping
gl_Position = vec4( (p0.xy + offset) * p0.w / screenSize, p0.z, p0.w);
EmitVertex();
sg_MapIO(v0); // default IO mapping
gl_Position = vec4( (p0.xy - offset) * p0.w / screenSize, p0.z, p0.w);
EmitVertex();
sg_MapIO(v1); // default IO mapping
gl_Position = vec4( (p1.xy + offset) * p1.w / screenSize, p1.z, p1.w);
EmitVertex();
sg_MapIO(v1); // default IO mapping
gl_Position = vec4( (p1.xy - offset) * p1.w / screenSize, p1.z, p1.w);
EmitVertex();
EndPrimitive();
}
\ No newline at end of file
......@@ -3,6 +3,7 @@
in vec3 outGeometryBary;
uniform float lineWidth;
uniform vec4 bkColor;
float edgeFactor()
{
......@@ -18,7 +19,7 @@ void main()
{
SG_FRAGMENT_BEGIN
sg_cColor.xyz = mix(vec3(0.0), sg_cColor.xyz, 1-edgeFactor());
sg_cColor.xyz = mix(bkColor, sg_cColor.xyz, 1-edgeFactor());
SG_FRAGMENT_END
}
\ No newline at end of file
// modified wireframe/hiddenline shader that works for n-poly faces
// template file for shader generator
in float outGeometryHidden;
uniform vec4 bkColor;
void main()
{
SG_FRAGMENT_BEGIN
sg_cColor.xyz = mix(sg_cColor.xyz, bkColor.xyz, outGeometryHidden);
SG_FRAGMENT_END
}
\ No newline at end of file
// modified wireframe/hiddenline shader that works for n-poly faces
// template file for shader generator
in vec3 outGeometryBary;
in vec3 outGeometryPolyEdge;
uniform float lineWidth;
uniform vec4 bkColor;
void main()
{
SG_FRAGMENT_BEGIN
// compute smoothed barycentric distance to edge
vec3 d = fwidth(outGeometryBary);
vec3 a3 = smoothstep(vec3(0.0), d*lineWidth, outGeometryBary);
// edge factor
float t = 1.0;
// barycentric coordinate = 0 <-> pixel located on opposite edge
// check if opposite edge should be hidden or visible
// distance v0 to edge v1-v2
if (outGeometryPolyEdge.y > 0.5)
t = min(t, a3.x);
// distance v1 to edge v2-v0
if (outGeometryPolyEdge.z > 0.5)
t = min(t, a3.y);
// distance v2 to edge v0-v1
if (outGeometryPolyEdge.x > 0.5)
t = min(t, a3.z);
vec3 dbg = vec3(0,0,0);
/*
if (outGeometryPolyEdge.y < 0.5)
dbg.x = min(dbg.x, a3.x);
// distance v1 to edge v2-v0
if (outGeometryPolyEdge.z > 0.5)
dbg.y = min(dbg.y, a3.y);
// distance v2 to edge v0-v1
if (outGeometryPolyEdge.x > 0.5)
dbg.z = min(dbg.z, a3.z);
*/
if (outGeometryPolyEdge.y < 0.5 && outGeometryPolyEdge.z < 0.5)
dbg.x = min(1, a3.x);
dbg.y = dbg.z = dbg.x;
// distance from vertices
/*
if (a3.x < 0.2 && a3.y < 0.02)
t = min(t,a3.z);
if (a3.x < 0.2 && a3.z < 0.02)
t = min(t,a3.y);
if (a3.y < 0.2 && a3.z < 0.02)
t = min(t,a3.x);
*/
t = 1 - t; // clamp(t, 0.0, 1.0);
sg_cColor.xyz = mix(bkColor.xyz, sg_cColor.xyz, t);
sg_cColor.w = 1;
// sg_cColor.xyz = dbg;
SG_FRAGMENT_END
}
\ No newline at end of file
// modified wireframe/hiddenline shader that works for n-poly faces
// template file for shader generator
void main()
{
SG_FRAGMENT_BEGIN
SG_FRAGMENT_END
}
\ No newline at end of file
// modified wireframe/hiddenline shader that works for n-poly faces
// template file for shader generator
in vec3 outGeometryBary;
in vec3 outGeometryPolyEdge;
uniform float lineWidth;
void main()
{
SG_FRAGMENT_BEGIN
// compute smoothed barycentric distance to edge
vec3 d = fwidth(outGeometryBary);
vec3 a3 = smoothstep(vec3(0.0), d*lineWidth, outGeometryBary);
// edge factor
float t = 1.0;
// barycentric coordinate = 0 <-> pixel located on opposite edge
// check if opposite edge should be hidden or visible
// distance v0 to edge v1-v2
if (outGeometryPolyEdge.y > 0.5)
t = min(t, a3.x);
// distance v1 to edge v2-v0
if (outGeometryPolyEdge.z > 0.5)
t = min(t, a3.y);
// distance v2 to edge v0-v1
if (outGeometryPolyEdge.x > 0.5)
t = min(t, a3.z);
t = 1 - t; // clamp(t, 0.0, 1.0);
// use alpha blending to fade out
sg_cColor.a = t;
// discard pixels inside face
if (t < 0.1)
discard;
SG_FRAGMENT_END
}
\ No newline at end of file
// template file for shader generator
in vec3 outGeometryBary;
uniform float lineWidth;
float edgeFactor()
{
// compute smoothed distance to edge, source:
// http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/
vec3 d = fwidth(outGeometryBary);
vec3 a3 = smoothstep(vec3(0.0), d*lineWidth, outGeometryBary);
return min(min(a3.x, a3.y), a3.z);
}
void main()
{
SG_FRAGMENT_BEGIN
float t = 1-edgeFactor();
// use alpha blending to fade out
sg_cColor.a = t;
// without alpha blending:
// sg_cColor.xyz *= t; //mix(vec3(0.0), sg_cColor.xyz, t);
// discard pixels inside face
if (t < 0.1)
discard;
SG_FRAGMENT_END
}
\ No newline at end of file
// template file for shader generator
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
// send barycentric coords to fragment
out vec3 outGeometryBary;
void main()
{
sg_MapIO(0); // IO mapping provided by ShaderGen, send vertex 0
outGeometryBary = vec3(1, 0, 0);
EmitVertex();
sg_MapIO(1); // IO mapping provided by ShaderGen, send vertex 1
outGeometryBary = vec3(0, 1, 0);
EmitVertex();
sg_MapIO(2); // IO mapping provided by ShaderGen, send vertex 2
outGeometryBary = vec3(0, 0, 1);
EmitVertex();
EndPrimitive();
}
\ No newline at end of file
// modified wireframe/hiddenline shader that works for n-poly faces
// template file for shader generator
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
// stores which triangle edge is a poly edge
uniform usamplerBuffer polyEdgeBuffer;
// send barycentric coords to fragment
out vec3 outGeometryBary;
// mark outer/inner edges of the n-poly triangulation
out vec3 outGeometryPolyEdge;
void main()
{
int polyEdge = int(texelFetch(polyEdgeBuffer, gl_PrimitiveIDIn/2).x);
// Each texel in the poly-edge buffer stores edge visibility for two triangles.
// Address the correct bits in the fetched byte:
int offsetBits = (gl_PrimitiveIDIn&1) * 3;
float e01 = 0;
float e12 = 0;
float e20 = 0;
// determine visible/hidden edges:
if ((polyEdge & (1 << offsetBits)) != 0) e01 = 1;
if ((polyEdge & (2 << offsetBits)) != 0) e12 = 1;
if ((polyEdge & (4 << offsetBits)) != 0) e20 = 1;
outGeometryPolyEdge = vec3(e01, e12, e20);
sg_MapIO(0); // IO mapping provided by ShaderGen, send vertex 0
outGeometryBary = vec3(1, 0, 0);
EmitVertex();
sg_MapIO(1); // IO mapping provided by ShaderGen, send vertex 1
outGeometryBary = vec3(0, 1, 0);
EmitVertex();
sg_MapIO(2); // IO mapping provided by ShaderGen, send vertex 2
outGeometryBary = vec3(0, 0, 1);
EmitVertex();
EndPrimitive();
}
// modified hiddenline shader that works for n-poly faces
layout(triangles) in;
layout(triangle_strip, max_vertices = 15) out;
// stores which triangle edge is a poly edge
// i.e. visible edges of a triangulation
uniform usamplerBuffer polyEdgeBuffer;
uniform float lineWidth;
uniform vec2 screenSize;
out float outGeometryHidden;
#include "createEdgeQuad.glsl"
void main()
{
int polyEdge = int(texelFetch(polyEdgeBuffer, gl_PrimitiveIDIn/2).x);
// Each texel in the poly-edge buffer stores edge visibility for two triangles.
// Address the correct bits in the fetched byte:
int offsetBits = (gl_PrimitiveIDIn&1) * 3;
// draw hidden triangle with background color
outGeometryHidden = 1.0;
sg_MapIO(0);
EmitVertex();
sg_MapIO(1);
EmitVertex();
sg_MapIO(2);
EmitVertex();
EndPrimitive();
// draw edges
outGeometryHidden = 0.0;
// determine visible/hidden edges
if ((polyEdge & (1 << offsetBits)) != 0)
createEdgeQuad(0,1, screenSize, lineWidth);
if ((polyEdge & (2 << offsetBits)) != 0)
createEdgeQuad(1,2, screenSize, lineWidth);
if ((polyEdge & (4 << offsetBits)) != 0)
createEdgeQuad(2,0, screenSize, lineWidth);
}
// modified wireframe shader that works for n-poly faces
layout(triangles) in;
layout(triangle_strip, max_vertices = 12) out;
// stores which triangle edge is a poly edge
// i.e. visible edges of a triangulation
uniform usamplerBuffer polyEdgeBuffer;
uniform float lineWidth;
uniform vec2 screenSize;
#include "createEdgeQuad.glsl"
void main()
{
int polyEdge = int(texelFetch(polyEdgeBuffer, gl_PrimitiveIDIn/2).x);
// Each texel in the poly-edge buffer stores edge visibility for two triangles.
// Address the correct bits in the fetched byte:
int offsetBits = (gl_PrimitiveIDIn&1) * 3;
// determine visible/hidden edges
if ((polyEdge & (1 << offsetBits)) != 0)
createEdgeQuad(0,1, screenSize, lineWidth);
if ((polyEdge & (2 << offsetBits)) != 0)
createEdgeQuad(1,2, screenSize, lineWidth);
if ((polyEdge & (4 << offsetBits)) != 0)
createEdgeQuad(2,0, screenSize, lineWidth);
}
// template file for shader generator
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
// send barycentric coords to fragment
out vec3 outGeometryBary;
void main()
{
sg_MapIO(0); // IO mapping provided by ShaderGen, send vertex 0
outGeometryBary = vec3(1, 0, 0);
EmitVertex();
sg_MapIO(1); // IO mapping provided by ShaderGen, send vertex 1
outGeometryBary = vec3(0, 1, 0);
EmitVertex();
sg_MapIO(2); // IO mapping provided by ShaderGen, send vertex 2
outGeometryBary = vec3(0, 0, 1);
EmitVertex();
EndPrimitive();
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment