在线框着色器中没有获得均匀的厚度

时间:2017-06-22 10:08:43

标签: unity3d graphics shader fragment-shader

Shader "Custom/Geometry/Wireframe"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _WireframeVal ("Wireframe width", Range(0.000, 0.035)) = 0.05
        _Color ("color", color) = (1, 1, 1, 1)
        _BackColor ("Back color", color) = (1, 1, 1, 1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Glowable" = "True" }


        Pass
        {
            Cull Back
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma geometry geom
            #include "UnityCG.cginc"

            struct v2g {
                float4 pos : SV_POSITION;
            };

            struct g2f {
                float4 pos : SV_POSITION;
                float3 center : TEXCOORD0;
            };

            v2g vert(appdata_base v) {
                v2g o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                return o;
            }


            [maxvertexcount(3)]
            void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {

                float2 p0 = IN[0].pos.xy / IN[0].pos.w;
                float2 p1 = IN[1].pos.xy / IN[1].pos.w;
                float2 p2 = IN[2].pos.xy / IN[2].pos.w;

                float2 edge0 = p1 - p0;
                float2 edge1 = p2 - p1;
                float2 edge2 = p0 - p2;

                float area = abs(edge1.x * edge2.y - edge1.y * edge2.x);

                g2f o;
                o.pos = IN[0].pos;
                o.center = float3(area/length(edge1)  , 0, 0);
                triStream.Append(o);
                o.pos = IN[1].pos;
                o.center = float3(0, 0, area/length(edge2) );
                triStream.Append(o);
                o.pos = IN[2].pos;
                o.center = float3(0, area/length(edge0), 0);
                triStream.Append(o);
            }

            float _WireframeVal;
            fixed4 _BackColor;
            float4 _Color;

            fixed4 frag(g2f i) : SV_Target 
            {

                if(min(i.center.x ,(min(i.center.y,i.center.z))) > _WireframeVal)
                {
                    discard;
                }
                return _BackColor;

            }

            ENDCG
        }


    }
}

这是我的线框着色器代码 我并没有得到统一的边缘 enter image description here enter image description here

此外,当我将宽度几乎减小到零(0.0001)时,没有绘制一些像素的电线,我能做些什么呢?我想制作线框着色器,因为统一构建了线框模式,我该如何实现呢?

1 个答案:

答案 0 :(得分:0)

实际上, 均匀厚度。你只是想着什么&#34;厚度&#34;在这种情况下,由于对象的绘制方式。

在面向相机的立方体边缘,它看起来比其他边缘更厚。好吧,你是对的。那里有 更多的白色像素。

但原因是因为那里有两条边!每一个都为线框的厚度贡献了所需的值。

Cube with edges drawn, showing individual faces

两个蓝色轮廓面红色轮廓面对边缘的厚度有贡献,而在相邻面指向远离相机的角落(比如,蓝色轮廓面的底边),只有一个面对整体效果有贡献。

当厚度非常小或非常远时(因为0.2像素+0.2像素= 0.4像素,向上舍入:1像素),这并不明显,但在较高厚度值时会变得明显,或者如果你非均匀地缩放对象。例如,我在几个星期前正在进行的项目中有这个(记住,我也画了背面并且alpha深度排序已关闭):

Wireframe cube non-uniformly scaled

原因是因为&#34; edge&#34;是通过计算三角形的重心坐标来完成的,这只是一个近似值,如果三角形不是等边的,会产生偏斜的结果。