I want lines to be displayed only on the contours of polygons. Pictured above from left as the current shader look. At right what i need. I understand that it is necessary to have data on the edges of polygons. Code (CSharp): Shader "Custom/Wireframe" { Properties { _WireColor("WireColor", Color) = (1,0,0,1) _Color("Color", Color) = (1,1,1,1) } SubShader { Pass { CGPROGRAM #include "UnityCG.cginc" #pragma target 5.0 #pragma vertex vert #pragma geometry geom #pragma fragment frag half4 _WireColor, _Color; struct v2g { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; struct g2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float3 dist : TEXCOORD1; }; v2g vert(appdata_base v) { v2g OUT; OUT.pos = mul(UNITY_MATRIX_MVP, v.vertex); OUT.uv = v.texcoord; //the uv's arent used in this shader but are included in case you want to use them return OUT; } [maxvertexcount(3)] void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) { float2 WIN_SCALE = float2(_ScreenParams.x/2.0, _ScreenParams.y/2.0); //frag position float2 p0 = WIN_SCALE * IN[0].pos.xy / IN[0].pos.w; float2 p1 = WIN_SCALE * IN[1].pos.xy / IN[1].pos.w; float2 p2 = WIN_SCALE * IN[2].pos.xy / IN[2].pos.w; //barycentric position float2 v0 = p2-p1; float2 v1 = p2-p0; float2 v2 = p1-p0; //triangles area float area = abs(v1.x*v2.y - v1.y * v2.x); g2f OUT; OUT.pos = IN[0].pos; OUT.uv = IN[0].uv; OUT.dist = float3(area/length(v0),0,0); triStream.Append(OUT); OUT.pos = IN[1].pos; OUT.uv = IN[1].uv; OUT.dist = float3(0,area/length(v1),0); triStream.Append(OUT); OUT.pos = IN[2].pos; OUT.uv = IN[2].uv; OUT.dist = float3(0,0,area/length(v2)); triStream.Append(OUT); } half4 frag(g2f IN) : COLOR { //distance of frag from triangles center float d = min(IN.dist.x, min(IN.dist.y, IN.dist.z)); //fade based on dist from center float I = exp2(-4.0*d*d); return lerp(_Color, _WireColor, I); } ENDCG } } }
That's difficult because you are only selecting the polygons that have a right angle, any edges that are not on the same plane. the code is written with trianges and you would kindof want to do square area outlines. for the moment, you can see if you can just select lines that are at right angles, i.e. only draw edges where the two points share two of their x, y or z coordnates
Doing this in a shader is only possible with shader model 4+. (So also DirectX 10+.) Another way is to change the model and make it consist of (infinitely thin) tubes running over the edges you want to render. This will of course make the model heavier and more complex. Edit: I see you are already using shader model 4+. One way would be to compare the normals of the neighbouring triangles. If the dot product of the two normals is (close to) 1, the edge can be skipped.
Meshes: Added "keep quads" mesh import option; useful for DX11/Console tessellation shaders. Coming soon - Unity 5 closed beta.
jvo3dc: I also believe using face normal is the way to go for a general co planar solution, and bonus you can correct AA for outline wireframe edge. But this require adjacency support in the geometry shader, and I dont believe Unity exposes this ? (doesnt work for me) I have a simple overlay wireframe shader that I use in game mode to show triangle or quad (using SV_VertexID instead of a geo shader), but it assume the vertices are ordered in a predictable sequence. (Add material slot, set shader, done.) Sadly, you can make a more generic Dx9 class wireframe shader by simply passing a stream that include the vertex index ("Primitive point ID") to the shader. This vertex index as been in HW since the first vertex shader implementation (required for the GPU to index memory), so not sure why HW vendor are still keeping this away from developers, but yet they did expose SV_VertexID in Dx10 (that is the vertex stream index, but only when its not parsing indexed primitive)... go figure.