【发布时间】:2018-08-27 05:57:08
【问题描述】:
我有一个显示三角形的线框着色器,例如在左侧立方体上,我想对其进行更新,使其仅显示四边形,例如在右侧立方体上。
代码如下:
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;
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
}
}
有人提到,一种方法是比较相邻三角形的法线。如果两条法线的点积接近1,则可以跳过边缘。但我不知道如何实现它,因为我对几何着色器一无所知。
你能帮我编辑这个着色器吗?
谢谢。
【问题讨论】:
-
这不是一个容易解决的问题,假设它完全可以解决。例如,如果您只渲染任何给定三角形的最短 2 条边(即假设穿过四边形的对角线比两条边长),您希望 this quad 如何渲染?
-
实际上这个解决方案可能适用于我的项目。你能告诉我如何在着色器中实现它吗?我想测试一下。
-
我隐约记得几年前曾尝试过类似的事情,但我不记得我做了什么,也从未坚持过这种特定的尝试。
标签: unity3d shader geometry-shader wireframe