I would like to achieve a “perspective” Wireframe using baked Barycentric coordinates (without a geometry pass). Ie a wireframe where the thickness is a constant with reference to the world space (right side of the reference image).
Most of the references I’ve found use fwidth or ddx & ddy to scale the wireframe relative to the screen space. This means that the wireframe looks thicker when the object is further away (left side of the reference image).
An example of such a shader is:
From Optimal way of rendering lines by @bgolus
Shader "Wireframe using Baked Barycentric Coordinates"
{
Properties {
_Color ("Color", Color) = (1,1,1,1)
_Width ("Line Width (Pixels)", Range(1, 50)) = 2
}
SubShader {
Tags { "Queue"="Transparent" "RenderType"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
Cull Off ZWrite Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_Position;
float3 coord : TEXCOORD0;
};
half4 _Color;
float _Width;
void vert (appdata_full v
, out v2f o
// , uint vid : SV_VertexID
)
{
o.pos = UnityObjectToClipPos(v.vertex);
o.coord = v.color.xyz;
// hack to get barycentric coords on the default plane mesh
// vid += (uint)round(v.vertex.z + 1000);
// uint colIndex = vid % 3;
// o.coord = float3(colIndex == 0, colIndex == 1, colIndex == 2);
}
half4 frag (v2f i) : SV_Target
{
float3 coordScale = fwidth(i.coord);
// more accurate alternative to fwidth
// float3 coordScale = sqrt(pow(ddx(i.coord), 2) + pow(ddy(i.coord), 2));
float3 scaledCoord = i.coord / coordScale;
float dist = min(scaledCoord.x, min(scaledCoord.y, scaledCoord.z));
float halfWidth = _Width * 0.5;
float wire = smoothstep(halfWidth + 0.5, halfWidth - 0.5, dist);
return half4(_Color.rgb, _Color.a * wire);
}
ENDCG
}
}
}
How can I modify such a shader so that the Wireframe thickness is constant with reference to the world space (right side of the reference image) please?
