#version 410 //**************************************************************************/ // Copyright (c) 2015 Autodesk, Inc. // All rights reserved. // // These coded instructions, statements, and computer programs contain // unpublished proprietary information written by Autodesk, Inc., and are // protected by Federal copyright law. They may not be disclosed to third // parties or copied or duplicated in any form, in whole or in part, without // the prior written consent of Autodesk, Inc. //**************************************************************************/ // Based on public domain code found here: http://prideout.net/blog/?p=54 // ----------------------------------- Per Frame -------------------------------------- uniform mat4 gWVPXf : WorldViewProjection; uniform mat4 world : World < string UIWidget = "None"; >; uniform vec3 EdgeColor < string UIName = "Edge Color"; string UIWidget = "ColorPicker"; string UIGroup = "Diffuse"; > = {0.0,0.0,0.0}; uniform vec3 FaceColor < string UIName = "Face Color"; string UIWidget = "ColorPicker"; string UIGroup = "Diffuse"; > = {0.7,0.7,0.7}; uniform vec2 FatLineScreenSize : ViewportPixelSize ; uniform float FatLineWidth = 5; // -------------------------------------- ShaderVertex -------------------------------------- attribute APPDATA { vec3 inPosition : POSITION; vec3 inNormal : NORMAL; }; attribute GEODATA { vec3 vNormal : NORMAL; }; attribute SHADERDATA { vec3 triColor; float gDist; }; GLSLShader ShaderVertex { void main(void) { VS_OUT.vNormal = (world * vec4(inNormal, 1.0)).xyz; gl_Position = gWVPXf * vec4(inPosition, 1.0); } } // -------------------------------------- ShaderGeometry -------------------------------------- GLSLShader ShaderGeometry { layout(triangles_adjacency) in; layout(triangle_strip, max_vertices = 15) out; bool IsFront(vec3 A, vec3 B, vec3 C) { float area = (A.x * B.y - B.x * A.y) + (B.x * C.y - C.x * B.y) + (C.x * A.y - A.x * C.y); return area > 0; } void EmitEdge(vec4 P0, vec4 P1) { vec4 out0 = P0; vec4 out1 = P1; vec4 Pc0 = out0; vec4 Pc1 = out1; float depthPriority = 0.001; Pc0.z -= depthPriority; Pc1.z -= depthPriority; vec3 aline = Pc0.xyz / Pc0.w - Pc1.xyz / Pc1.w; float len = length(aline); aline /= len; vec3 norm = vec3(0,0,1.0); vec3 ortho = cross(normalize(aline - dot(aline, norm) * norm), norm); float extlen = FatLineWidth / sqrt(aline.x*aline.x*FatLineScreenSize.x*FatLineScreenSize.x + aline.y*aline.y*FatLineScreenSize.y*FatLineScreenSize.y); float lambda = extlen / len; float lambdaN = -lambda; float lambdaC = (Pc0.w * lambdaN) / ((Pc0.w * lambdaN) + Pc1.w * (1 - lambdaN)); lambdaC = lambdaC > 0 ? -1.0e3f : lambdaC; vec4 ext0 = (1 - lambdaC) * Pc0 + lambdaC * Pc1; out0 = ext0; vec3 scale = vec3(1, 1, 1); scale.xy = vec2((out0.w) / FatLineScreenSize.x, (out0.w) / FatLineScreenSize.y); ortho *= FatLineWidth; out0.xyz += ortho * scale; gl_Position = out0; GS_OUT.triColor = EdgeColor; EmitVertex(); out0.xyz -= (ortho * 2) * scale; gl_Position = out0; GS_OUT.triColor = EdgeColor; EmitVertex(); lambdaN = 1 + lambda; lambdaC = (Pc0.w * lambdaN) / ((Pc0.w * lambdaN) + Pc1.w * (1 - lambdaN)); lambdaC = lambdaC < 0 ? 1.0e3f : lambdaC; vec4 ext1 = (1 - lambdaC) * Pc0 + lambdaC * Pc1; out1 = ext1; scale.xy = vec2((out1.w) / FatLineScreenSize.x, (out1.w) / FatLineScreenSize.y); out1.xyz += ortho * scale; gl_Position = out1; GS_OUT.triColor = EdgeColor; EmitVertex(); out1.xyz -= (ortho * 2) * scale; gl_Position = out1; GS_OUT.triColor = EdgeColor; EmitVertex(); EndPrimitive(); } void main() { vec3 v0 = gl_in[0].gl_Position.xyz / gl_in[0].gl_Position.w; vec3 v1 = gl_in[1].gl_Position.xyz / gl_in[1].gl_Position.w; vec3 v2 = gl_in[2].gl_Position.xyz / gl_in[2].gl_Position.w; vec3 v3 = gl_in[3].gl_Position.xyz / gl_in[3].gl_Position.w; vec3 v4 = gl_in[4].gl_Position.xyz / gl_in[4].gl_Position.w; vec3 v5 = gl_in[5].gl_Position.xyz / gl_in[5].gl_Position.w; // Output center face: GS_OUT.triColor = FaceColor; gl_Position = gl_in[0].gl_Position; EmitVertex(); gl_Position = gl_in[2].gl_Position; EmitVertex(); gl_Position = gl_in[4].gl_Position; EmitVertex(); EndPrimitive(); // Then output optional silhouette edges: if (IsFront(v0, v2, v4)) { if (!IsFront(v0, v1, v2)) EmitEdge(gl_in[0].gl_Position, gl_in[2].gl_Position); if (!IsFront(v2, v3, v4)) EmitEdge(gl_in[2].gl_Position, gl_in[4].gl_Position); if (!IsFront(v0, v4, v5)) EmitEdge(gl_in[4].gl_Position, gl_in[0].gl_Position); } } } // -------------------------------------- ShaderPixel -------------------------------------- attribute PIXELDATA { vec4 outColor : COLOR0; }; GLSLShader ShaderPixel { void main(void) { outColor = vec4(PS_IN.triColor, 1.0); } } // -------------------------------------- technique T0 --------------------------------------- technique T0 < string index_buffer_type = "GLSL_TRIADJ"; > { pass P0 < string drawContext = "colorPass"; > { VertexShader (in APPDATA, out GEODATA VS_OUT) = ShaderVertex; GeometryShader (in GEODATA GS_IN, out SHADERDATA GS_OUT) = ShaderGeometry; PixelShader (in SHADERDATA PS_IN, out PIXELDATA) = ShaderPixel; } }