zoukankan      html  css  js  c++  java
  • Unity 中使用Geomotry Shader(几何着色器)扩展点创建其他图形(并实现处理锯齿)

    问题背景:

    我们开发中需要有“点”对象,可以是像素的(不具备透视效果),始终等大,还有就是3D场景下的矢量点(随相机距离透视变化的)。

    问题解决思路:

    方案1:使用GS扩充顶点,并扩充三角面,通过GS直接绘制出想要图形点(我这里有几种图形的点)

    方案2:使用GS扩充顶点,绘制出正方形面,到FS中去截取想要的形状

    这两种方案基本思想都是一样的,我这里提供两种方案是因为我这个点的边框是有要求的,用GS扩线围一圈效果不好

    知识扩展:

    Geomotry Shader(几何着色器):几何着色器是可选的着色器,它位于顶点和片段着色器之间,它以一个或多个表示为一个单独基本图形(primitive)即图元的顶点作为输入,比如可以是一个点或者三角形,几何着色器在将这些顶点发送到下一个着色阶段之前,可以将这些顶点转变为它认为合适的内容。几何着色器有意思的地方在于它可以把(一个或多个)顶点转变为完全不同的基本图形(primitive),从而生成比原来多得多的顶点。

     

    上面是官方解释,通俗来讲:就是GeometryShader接收的实际上是VS输出的图元,对这些图元进行添加,修改,删除,然后输出新的图元信息。

     

    图片说明:

    这也就是人们常见的shader流程图。

    具体实现代码:

    方案一:

      1 Shader "Vector/Point"
      2 {
      3     Properties
      4     {
      5         _Color("MianColor",color)=(1,1,1,1)
      6     }
      7     SubShader
      8     {
      9         Pass
     10         {
     11             Tags { "RenderType"="Opaque" }
     12             LOD 100 
     13             Cull Off
     14             CGPROGRAM
     15             #pragma target 4.0
     16             #pragma vertex vert
     17             #pragma fragment frag
     18             #pragma geometry geom            
     19             #include "UnityCG.cginc" 
     20             struct appdata
     21             {
     22                 float4 vertex : POSITION;
     23                 float2 uv : TEXCOORD0;
     24                 float3 normal : NORMAL;
     25             }; 
     26             struct v2g
     27             {
     28                 float4 vertex : POSITION;
     29                 float3 nor:NORMAL;
     30             };
     31             struct g2f
     32             {
     33                 float4 vertex : SV_POSITION;
     34                 float3 norg:NORMAL;
     35             };
     36 
     37             fixed4 _LightColor0;
     38             fixed4 _Color;
     39             float radius;
     40             float initOffsetAngle=0;
     41             float verticesNumber=3;
     42             float IsEqualPixelPoint=0.0;
     43 
     44             v2g vert(appdata_base v)
     45             {
     46                 v2g o;
     47                 o.vertex = v.vertex;
     48                 o.nor=v.normal;
     49                 return o;
     50             }
     51  
     52         void ADD_VERTEX(float3 v,g2f o,inout TriangleStream<g2f> tristream)
     53         {
     54            o.vertex = UnityObjectToClipPos(v); 
     55            tristream.Append(o);
     56         }      
     57         void  ADD_INFO(float3 p0,float3 p1,float3 p2,g2f o,inout TriangleStream<g2f> tristream)
     58         {
     59 
     60             ADD_VERTEX(p0,o,tristream);
     61             ADD_VERTEX(p1,o,tristream);
     62             ADD_VERTEX(p2,o,tristream);
     63             tristream.RestartStrip();
     64         }
     65                   
     66        // 根据模型坐标获得屏幕坐标
     67        float4 GetScreenPos(float4 vertex)
     68         {
     69           float4 pos = UnityObjectToClipPos(vertex);
     70           //return getScreenPosByClipPos(pos);
     71 
     72           pos = ComputeScreenPos(pos);
     73           pos.xy = pos.xy / pos.w;
     74           pos.xy = pos.xy * _ScreenParams.xy;
     75           return pos;
     76        }
     77 
     78         //将旋转完的坐标转回剪裁空间下
     79         void ADD_VERTEX_Other(float4 v,g2f o,inout TriangleStream<g2f> tristream)
     80         {
     81             float4 pos=v;
     82             pos.xy=v.xy/_ScreenParams.xy;
     83             pos.xy=pos.xy * v.w;
     84 
     85             pos.y= (pos.y-(0.5*pos.w))/(_ProjectionParams.x * 0.5);
     86             pos.x=(pos.x-(0.5*pos.w))/0.5;
     87 
     88             o.vertex = pos; 
     89             tristream.Append(o);
     90         }     
     91         
     92         void  ADD_INFO_Other(float4 p0,float4 p1,float4 p2,g2f o,inout TriangleStream<g2f> tristream)
     93         {
     94             ADD_VERTEX_Other(p0,o,tristream);
     95             ADD_VERTEX_Other(p1,o,tristream);
     96             ADD_VERTEX_Other(p2,o,tristream);
     97             tristream.RestartStrip();
     98         }
     99 
    100         [maxvertexcount(60)]
    101         void geom(triangle v2g IN[3], inout TriangleStream<g2f> tristream)
    102         {
    103            g2f o; 
    104            if(IsEqualPixelPoint==0.0)
    105            {
    106             float3 p0=float3(0,0,0);
    107             float3 dir=normalize( mul(unity_WorldToObject,_WorldSpaceCameraPos)-IN[0].vertex);
    108             float3 cy=float3(0,1,0);
    109             float3 right=normalize(cross(cy, dir));
    110             float3 up=normalize(cross(dir,right));
    111             float3 p=cy * radius;
    112             //第一个点
    113             float3 p1=float3((cos(radians(initOffsetAngle)) * (p).x)-(sin(radians(initOffsetAngle)) * (p).y),(sin(radians(initOffsetAngle)) * (p).x)+(cos(radians(initOffsetAngle)) * (p).y),(p).z);
    114             float3 p2=float3(0,0,0);
    115             float3 p3=float3(0,0,0);
    116             float angle= radians(360/verticesNumber);
    117             p2=float3((cos(angle) * (p1).x)-(sin(angle) * (p1).y),(sin(angle) * (p1).x)+(cos(angle) * (p1).y),(p1).z);
    118 
    119             float3 p1p=(p1.x*right+p1.y*up+p1.z*dir);
    120             p2=(p2.x*right+p2.y*up+p2.z*dir);
    121 
    122             float3 edgeA = p2 - p1p;
    123             float3 edgeB = p3 - p1p;
    124             float3 normalFace = normalize(cross(edgeA, edgeB));
    125             o.norg=-normalFace;
    126 
    127             ADD_INFO(p0,p1p,p2,o,tristream);
    128 
    129             for (float i=1.0; i<verticesNumber;i+=1.0)
    130             {
    131                 p2=float3((cos(i*angle) * (p1).x)-(sin(i*angle) * (p1).y),(sin(i*angle) * (p1).x) + (cos(i*angle) * (p1).y),(p1).z);
    132                 p3=float3((cos((i+1)*angle) * (p1).x)-(sin((i+1)*angle) * (p1).y),(sin((i+1) * angle) * (p1).x)+(cos((i+1) * angle) * (p1).y),(p1).z);
    133     
    134                 p2=(p2.x*right+p2.y*up+p2.z*dir);
    135                 p3=(p3.x*right+p3.y*up+p3.z*dir);
    136 
    137                 float3 edgeA = p2 - p1;
    138                 float3 edgeB = p3 - p1;
    139                 float3 normalFace = normalize(cross(edgeA, edgeB));
    140                 o.norg=-normalFace;
    141 
    142                 ADD_INFO(p0,p2,p3,o,tristream);
    143             }
    144           }
    145           else
    146           {
    147             //等像素
    148             float4 pp0=float4(0,0,0,1);
    149             pp0= GetScreenPos(pp0);
    150             float2 up=float2(0,1);
    151             float2 pp=up * radius;
    152             //第一个点
    153             float4 pp1=pp0;
    154             float4 pp2=pp0;
    155             float4 pp3=pp0;
    156             pp1.xy= float2((cos(radians(initOffsetAngle)) * (pp).x)-(sin(radians(initOffsetAngle)) * (pp).y),(sin(radians(initOffsetAngle)) * (pp).x)+(cos(radians(initOffsetAngle)) * (pp).y));
    157             float angle= radians(360/verticesNumber);
    158             pp2.xy=float2((cos(angle) * (pp1).x)-(sin(angle) * (pp1).y),(sin(angle) * (pp1).x)+(cos(angle) * (pp1).y));
    159             float3 edgeA = pp2 - pp1;
    160             float3 edgeB = pp3 - pp1;
    161             float3 normalFace = normalize(cross(edgeA, edgeB));
    162             o.norg=-normalFace;
    163 
    164             ADD_INFO_Other(pp0,pp1+float4(pp0.xy,0,0),pp2+float4(pp0.xy,0,0),o,tristream);
    165 
    166            for (float i=1.0; i<verticesNumber;i+=1.0)
    167             {
    168                 pp2=pp0;
    169                 pp3=pp0;
    170                 pp2.xy=float2((cos(i*angle) * (pp1).x)-(sin(i*angle) * (pp1).y),(sin(i*angle) * (pp1).x) + (cos(i*angle) * (pp1).y));
    171                 pp3.xy=float2((cos((i+1)*angle) * (pp1).x)-(sin((i+1)*angle) * (pp1).y),(sin((i+1) * angle) * (pp1).x)+(cos((i+1) * angle) * (pp1).y));
    172 
    173                 float3 edgeA = pp2 - pp1;
    174                 float3 edgeB = pp3 - pp1;
    175                 float3 normalFace = normalize(cross(edgeA, edgeB));
    176                 o.norg=-normalFace;
    177 
    178                 ADD_INFO_Other(pp0,pp2+float4(pp0.xy,0,0),pp3+float4(pp0.xy,0,0),o,tristream);
    179             }
    180           }
    181         } 
    182             fixed4 frag (g2f i) : SV_Target
    183             {
    184               return _Color;
    185             }
    186             ENDCG
    187         }
    188     }
    189 }

    代码分析:

    1.从模型坐标-剪裁空间坐标-屏幕空间坐标,如下:

            float4 GetScreenPos(float4 vertex)
              {
                float4 pos = UnityObjectToClipPos(vertex);
                //return getScreenPosByClipPos(pos);
     
               pos = ComputeScreenPos(pos);
              pos.xy = pos.xy / pos.w;
                pos.xy = pos.xy * _ScreenParams.xy;
                return pos;
            }
    

    2.屏幕坐标扩展完坐标转回剪裁空间

           //将旋转完的坐标转回剪裁空间下
             void ADD_VERTEX_Other(float4 v,g2f o,inout TriangleStream<g2f> tristream)
            {
                 float4 pos=v;
                  pos.xy=v.xy/_ScreenParams.xy;
                  pos.xy=pos.xy * v.w;
      
                 pos.y= (pos.y-(0.5*pos.w))/(_ProjectionParams.x * 0.5);
                 pos.x=(pos.x-(0.5*pos.w))/0.5;
      
                 o.vertex = pos; 
                  tristream.Append(o);
              }     
    

     这个地方就是转屏幕坐标的逆运算,主要注意的是定义位于UnityCG.cginc中的内置方法ComputeScreenPos,它的具体逻辑是这样:

    inline float4 ComputeScreenPos (float4 pos)
    {
        float4 o = pos * 0.5f;
        o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w;
        o.zw = pos.zw;
        
        return o;
    }
    即主要做的是就是这:

    o.x = (pos.x * 0.5 + pos.w * 0.5)

    o.y = (pos.y * 0.5 * _ProjectionParams.x + pos.w * 0.5)

    这一步别忘了逆运算回去。

    3.这里的算法逻辑是这样:给我一个中心点坐标,我求出正上方点坐标,根据你是几边形,去旋转(乘以旋转矩阵)得到扩展点。上面矢量点主要问题在于,我构建了本地坐标系,旋转就会有坑,因为我正上方点是通过构建坐标系去求得,然而旋转应该在自身坐标系下,
    正上方点就是(0,1,0 )而不是自己构建坐标系下的up,记得转完返回去,所以这是一个坑。


    方案二:

      1 Shader "MyShader/PointTwo"
      2 {
      3     Properties
      4     {
      5         _Color("MianColor",color)=(1,1,1,1)
      6     }
      7     SubShader
      8     {
      9 
     10         Tags { "RenderType"="Opaque" }
     11         LOD 100 
     12         Cull Off
     13 
     14         CGINCLUDE
     15     
     16         #include "UnityCG.cginc" 
     17 
     18         struct appdata
     19         {
     20             float4 vertex : POSITION;
     21             float2 uv : TEXCOORD0;
     22             float3 normal : NORMAL;
     23             fixed4 color : COLOR; //顶点自身的颜色
     24         }; 
     25 
     26         struct v2g
     27         {
     28             float4 vertex : POSITION;
     29             float3 nor:NORMAL;
     30             fixed4 color : COLOR; //顶点自身的颜色
     31         };
     32         
     33         struct g2f
     34         {
     35             float4 vertex : SV_POSITION;
     36             float3 pos: TEXCOORD0;
     37             float3 centerPos: TEXCOORD1;
     38             float3 norg:NORMAL;
     39             fixed4 color : COLOR; //顶点自身的颜色
     40         };
     41 
     42         //点的颜色
     43         fixed4 _Color;
     44         //边框的颜色
     45         fixed4 _LineColor;
     46         //点的半径大小(四边形内切圆)
     47         float _Radius;
     48         //点的线框宽度
     49         uniform float _LineWidth=5;
     50         //什么图形(-1圆/)
     51         float _PointType=-1;
     52         //是否是像素点
     53         float IsEqualPixelPoint=0.0;
     54         //交叉点宽度
     55         float _CrossPointWidth;
     56  
     57         //矢量点添加扩展点坐标转换      
     58         void ADD_VERTEX(float3 v,g2f o,inout TriangleStream<g2f> tristream)
     59         {
     60            o.vertex = UnityObjectToClipPos(v);
     61            o.pos = v;
     62            tristream.Append(o);
     63         }
     64 
     65         //矢量点添加扩展点面逻辑      
     66         void  ADD_INFO(float3 p0,float3 p1,float3 p2,g2f o,inout TriangleStream<g2f> tristream)
     67         {
     68             ADD_VERTEX(p0,o,tristream);
     69             ADD_VERTEX(p1,o,tristream);
     70             ADD_VERTEX(p2,o,tristream);
     71             tristream.RestartStrip();
     72         }
     73                   
     74        // (像素点)根据模型坐标获得屏幕坐标
     75        float4 GetScreenPos(float4 vertex)
     76         {
     77           float4 pos = UnityObjectToClipPos(vertex);
     78 
     79           pos = ComputeScreenPos(pos);
     80           pos.xy = pos.xy / pos.w;
     81           pos.xy = pos.xy * _ScreenParams.xy;
     82           return pos;
     83        }
     84 
     85         //(像素点)将旋转完的坐标转回剪裁空间下
     86         void ADD_VERT_Other(float4 v,g2f o,inout TriangleStream<g2f> tristream)
     87         {
     88             float4 pos=v;
     89             pos.xy=v.xy/_ScreenParams.xy;
     90             pos.xy=pos.xy * v.w;
     91 
     92             pos.y= (pos.y-(0.5*pos.w))/(_ProjectionParams.x * 0.5);
     93             pos.x=(pos.x-(0.5*pos.w))/0.5;
     94 
     95             o.vertex = pos; 
     96             o.pos=v;
     97             tristream.Append(o);
     98         }     
     99         
    100         //像素点添加点
    101         void  ADD_INFO_Other(float4 p0,float4 p1,float4 p2,g2f o,inout TriangleStream<g2f> tristream)
    102         {
    103             ADD_VERTEX_Other(p0,o,tristream);
    104             ADD_VERTEX_Other(p1,o,tristream);
    105             ADD_VERTEX_Other(p2,o,tristream);
    106             tristream.RestartStrip();
    107         }
    108 
    109         // 判断点是否在三角形内
    110         float PointinTriangle(float2 A, float2 B, float2 C, float2 P)
    111         {
    112             float2 ab=B-A;
    113             float2 ac=C-A;
    114             float2 ap=P-A;
    115              
    116             float u=(dot(ab,ab) *dot(ap,ac)-dot(ac,ab)* dot(ap,ab)) / (dot(ac,ac) * dot(ab,ab)-dot(ac,ab) * dot(ab,ac));
    117             float v=(dot(ac,ac) *dot(ap,ab)-dot(ac,ab)* dot(ap,ac)) / (dot(ac,ac) * dot(ab,ab)-dot(ac,ab) * dot(ab,ac));
    118 
    119                if (u < 0 || u > 1) // if u out of range, return directly
    120                {
    121                   return 2 ;
    122                }
    123 
    124                if (v < 0 || v > 1) // if v out of range, return directly
    125                 {
    126                     return 2 ;
    127                 }
    128                 return u+v;
    129         }
    130 
    131         //截圆点
    132         void DrawCirclePoint(g2f i,float type)
    133         {
    134 
    135             //边框
    136             _LineWidth=5;
    137 
    138             float _R = abs(type) < 0.05 ? _Radius :  (_Radius - _LineWidth);
    139 
    140             float dis=distance(i.centerPos,i.pos);
    141               
    142             //剔除圆
    143             if(dis > _R)
    144             {
    145               discard;
    146             }
    147             
    148         }  
    149 
    150         //截正方形点
    151         void DrawSquarePoint(g2f i,float type)
    152         {
    153             //边框
    154             _LineWidth=5;
    155 
    156             float _R = abs(type) < 0.05 ? 0.9 * _Radius :  (0.9 *_Radius - _LineWidth);
    157 
    158              //计算边缘点
    159              float2 leftTop=float2(i.centerPos.x  - _R , i.centerPos.y +  _R);
    160              float2 leftButtom=float2(i.centerPos.x  - _R , i.centerPos.y -  _R);
    161              float2 rightTop=float2(i.centerPos.x  + _R , i.centerPos.y +  _R);
    162              float2 rightButtom=float2(i.centerPos.x  + _R , i.centerPos.y -  _R);
    163                
    164              //正方形剔除
    165              if(i.pos.x < leftTop.x | i.pos.x > rightTop.x | i.pos.y < leftButtom.y | i.pos.y > rightTop.y)
    166              {
    167                  discard;
    168              }
    176         }
    177 
    178         //截三角形点
    179         void DrawTrianglePoint(g2f i,float type)
    180         {
    181             //边框
    182             _LineWidth=5;
    183 
    184             float _R = abs(type) < 0.05 ? _Radius :  (_Radius - _LineWidth);
    185              
    186             //计算边缘点
    187             float2 leftTop=float2(i.centerPos.x  - _R , i.centerPos.y +  _R);
    188             float2 leftButtom=float2(i.centerPos.x  - _R , i.centerPos.y -  _R);
    189             float2 rightTop=float2(i.centerPos.x  + _R , i.centerPos.y +  _R);
    190             float2 rightButtom=float2(i.centerPos.x  + _R , i.centerPos.y -  _R);
    191 
    192             //三角形顶点
    193             float2 topCenter=(leftTop+rightTop)/2;
    194             float2 rightB=float2((i.centerPos.x + 0.707 * _R),i.centerPos.y - 0.5 *_R);
    195             float2 leftB=float2((i.centerPos.x - 0.707 * _R),i.centerPos.y - 0.5 *_R);
    196 
    197             if(PointinTriangle(topCenter,rightB, leftB, i.pos.xy)>1)
    198             {
    199                 discard;
    200             }
    259         }
    260         
    261         //截交叉十字形点
    262         void DrawCrossPoint(g2f i,float type)
    263         {
    264 
    265              //边框
    266             _LineWidth=5;
    267 
    268             _CrossPointWidth=16;
    269 
    270             float _R = abs(type) < 0.05 ? 0.9* _Radius :  (0.92 * _Radius - _LineWidth);
    271 
    272             float _InPoint = abs(type) < 0.05 ? _CrossPointWidth / 2 :  (_CrossPointWidth - _LineWidth) / 2;
    273 
    274             //计算边缘点
    275             float2 leftTop=float2(i.centerPos.x  - _R , i.centerPos.y +  _R);
    276             float2 leftButtom=float2(i.centerPos.x  - _R , i.centerPos.y -  _R);
    277             float2 rightTop=float2(i.centerPos.x  + _R , i.centerPos.y +  _R);
    278             float2 rightButtom=float2(i.centerPos.x  + _R , i.centerPos.y -  _R);
    279 
    280             //十字架内角点  
    281             float2 inRightTop=float2(i.centerPos.x  + _InPoint , i.centerPos.y +  _InPoint);
    282             float2 inLeftTop=float2(i.centerPos.x  - _InPoint , i.centerPos.y + _InPoint);
    283             float2 inRightButtom=float2(i.centerPos.x  + _InPoint , i.centerPos.y -  _InPoint);
    284             float2 inLeftButtom=float2(i.centerPos.x  - _InPoint , i.centerPos.y -  _InPoint);
    285             
    286             if(((i.pos.x) > (inRightTop.x) & (i.pos.y) > (inRightTop.y)) | ((i.pos.x) < (inLeftTop.x) & (i.pos.y) > (inLeftTop.y)) | ((i.pos.x) > (inRightButtom.x) & (i.pos.y) < (inRightButtom.y)) | ((i.pos.x) < (inLeftButtom.x) & (i.pos.y) < (inLeftButtom.y)) | ((i.pos.x) < (i.centerPos.x - _R) | (i.pos.x) > (i.centerPos.x+ _R)) | ((i.pos.y) < (i.centerPos.y- _R) | (i.pos.y) > (i.centerPos.y+ _R)))
    287             { 
    288                 discard;
    289             }
    298         }
    299 
    300         v2g vert(appdata_full  v)
    301         {
    302             v2g o;
    303             o.vertex = v.vertex;
    304             o.nor=v.normal;
    305             o.color=v.color;
    306             return o;
    307         }
    308 
    309         [maxvertexcount(12)]
    310         void geom(triangle v2g IN[3], inout TriangleStream<g2f> tristream)
    311         {
    312            g2f o; 
    313            //固定只扩展4个点,且初始偏转为45
    314            //矢量点
    315            if(IsEqualPixelPoint==0.0)
    316            {
    317             //中心点   
    318             float3 centerPos=float3(0,0,0);
    319             o.centerPos=centerPos;
    320             o.color=IN[0].color;
    321 
    322             //计算本地坐标系
    323             float3 dir=normalize(mul(unity_WorldToObject,_WorldSpaceCameraPos)-IN[0].vertex);
    324             float3 worldUp=float3(0,1,0);
    325             float3 right=normalize(cross(worldUp, dir));
    326             float3 up=normalize(cross(dir,right));
    327 
    328             //正上方点
    329             float3 p=worldUp * _Radius * 1.414;
    330             float3 p1=centerPos;
    331             float3 p2=centerPos;
    332             float3 p3=centerPos;
    333             float3 p4=centerPos;
    334 
    335             //计算偏移角
    336             float angle= radians(360/4);
    337 
    338             //求正方形四顶点
    339             p1=float3((cos(radians(45)) * (p).x)-(sin(radians(45)) * (p).y),(sin(radians(45)) * (p).x)+(cos(radians(45)) * (p).y),(p).z);
    340             p2=float3((cos(angle) * (p1).x)-(sin(angle) * (p1).y),(sin(angle) * (p1).x)+(cos(angle) * (p1).y),(p1).z);
    341             p3=float3((cos(angle * 2) * (p1).x)-(sin(angle * 2) * (p1).y),(sin(angle * 2) * (p1).x)+(cos(angle * 2) * (p1).y),(p1).z);
    342             p4=float3((cos(angle * 3) * (p1).x)-(sin(angle * 3) * (p1).y),(sin(angle * 3) * (p1).x)+(cos(angle * 3) * (p1).y),(p1).z);
    343             p1=(p1.x * right + p1.y * up + p1.z * dir);
    344             p2=(p2.x * right + p2.y * up + p2.z * dir);
    345             p3=(p3.x * right + p3.y * up + p3.z * dir);
    346             p4=(p4.x * right + p4.y * up + p4.z * dir);
    347 
    348             //计算法线
    349             float3 edgeA = p2 - p1;
    350             float3 edgeB = p3 - p1;
    351             float3 normalFace = normalize(cross(edgeA, edgeB));
    352             o.norg=-normalFace;
    353 
    354             ADD_INFO(p1,p2,p3,o,tristream);
    355             ADD_INFO(p3,p4,p1,o,tristream);
    356           }
    357           else
    358           {
    359             //等像素点
    360             float4 centerPos1=float4(0,0,0,1);
    361             centerPos1= GetScreenPos(centerPos1);
    362             float2 up=float2(0,1);
    363             float2 pp=up * _Radius * 1.414;
    364             //第一个点
    365             float4 pp1=centerPos1;
    366             float4 pp2=centerPos1;
    367             float4 pp3=centerPos1;
    368             float4 pp4=centerPos1;
    369 
    370             //计算偏移角
    371             float angle= radians(360/4);
    372 
    373             //求正方形四顶点
    374             pp1.xy=float2((cos(radians(45)) * (pp).x)-(sin(radians(45)) * (pp).y),(sin(radians(45)) * (pp).x)+(cos(radians(45)) * (pp).y));
    375             pp2.xy=float2((cos(angle) * (pp1).x)-(sin(angle) * (pp1).y),(sin(angle) * (pp1).x)+(cos(angle) * (pp1).y));
    376             pp3.xy=float2((cos(2 * angle) * (pp1).x)-(sin(2 * angle) * (pp1).y),(sin(2 * angle) * (pp1).x)+(cos(2 * angle) * (pp1).y));
    377             pp4.xy=float2((cos(3 * angle) * (pp1).x)-(sin(3 * angle) * (pp1).y),(sin(3 * angle) * (pp1).x)+(cos(3 * angle) * (pp1).y));
    378             
    379             //计算偏移
    380             pp1=pp1+float4(centerPos1.xy,0,0);
    381             pp2=pp2+float4(centerPos1.xy,0,0);
    382             pp3=pp3+float4(centerPos1.xy,0,0);
    383             pp4=pp4+float4(centerPos1.xy,0,0);
    384 
    385             //计算法线
    386             float3 edgeA = pp2 - pp1;
    387             float3 edgeB = pp3 - pp1;
    388             float3 normalFace = normalize(cross(edgeA, edgeB));
    389             o.norg=-normalFace;
    390             
    391             o.centerPos=centerPos1;
    392             o.color=IN[0].color;
    393 
    394             ADD_INFO_Other(pp1,pp2,pp3,o,tristream);
    395             ADD_INFO_Other(pp3,pp4,pp1,o,tristream);
    396 
    397           }
    398         } 
    399             
    400        fixed4 frag (g2f i) : SV_Target
    401         {
    402                  
    403             //圆形点
    404             if (abs(_PointType)<=0.05)
    405             {    
    406                DrawCirclePoint(i,0.0);       
    407             }
    408              
    409             //正方形
    410             if(abs(_PointType-2)<=0.05)
    411             {
    412                DrawSquarePoint(i,0.0);
    413             }
    414 
    415             //三角形
    416             if(abs(_PointType-1)<=0.05)
    417             {
    418                DrawTrianglePoint(i,0.0);
    419             }
    420 
    421              //交叉十字
    422             if(abs(_PointType-3)<=0.05)
    423             {
    424                 DrawCrossPoint(i,0.0);
    425             }
    426 
    427              return _LineColor;
    428         }
    429 
    430 
    431         fixed4 fragOther (g2f i) : SV_Target
    432         {
    433             //圆形点
    434             if (abs(_PointType)<=0.05)
    435             {    
    436                DrawCirclePoint(i,1.0);   
    437             }
    438              
    439             //正方形
    440             if(abs(_PointType-2)<=0.05)
    441             {
    442                DrawSquarePoint(i,1.0);
    443             }
    444 
    445             //三角形
    446             if(abs(_PointType-1)<=0.05)
    447             {
    448                DrawTrianglePoint(i,1.0);
    449             }
    450 
    451              //交叉十字
    452             if(abs(_PointType-3)<=0.05)
    453             {
    454                 DrawCrossPoint(i,1.0);
    455             }
    456 
    457               return _Color;
    458         }
    459 
    460         ENDCG
    461 
    462         Pass 
    463         {
    464               NAME "InitShader"
    465 
    466               Tags { "RenderType"="Opaque" }
    467               LOD 100 
    468               Cull Off
    469 
    470               CGPROGRAM
    471               
    472               #pragma target 4.0
    473               #pragma vertex vert
    474               #pragma geometry geom        
    475               #pragma fragment frag
    476 
    477               ENDCG  
    478         }
    479 
    480         Pass 
    481         {
    482               NAME "LineShader"
    483             
    484               Tags { "RenderType"="Opaque" }
    485               LOD 100 
    486               Cull Off
    487 
    488               CGPROGRAM
    489               
    490               #pragma target 4.0
    491               #pragma vertex vert
    492               #pragma geometry geom        
    493               #pragma fragment fragOther
    494               
    495               ENDCG  
    496         }
    497     }
    498 
    499     FallBack "Diffuse"
    500 }

    代码分析:

    这个方案主要是为了边框处理,我在这里画了两次,也可以处理一次,通过条件去改变Color,但是我这里不想过多处理过渡问题,所以采取了两个Pass渲两遍。。

    这里附带一个判断点是否在三角形内算法:

    对于三角形ABC和一点P,可以有如下的向量表示:

    image

    p点在三角形内部的充分必要条件是:1 >= u >= 0,   1 >= v >= 0,   u+v <= 1。

    已知A,B,C,P四个点的坐标,可以求出u,v,把上面的式子分别点乘向量AC和向量AB

    image

    解方程得到:

    image

    解出u,v后只需要看他们是否满足“1 >= u >= 0, 1 >= v >= 0, u+v <= 1”,如满足,则,p 在三角形内。

    (u = 0时,p在AB上, v = 0时,p在AC上,两者均为0时,p和A重合)

    ps:是不是很熟悉,嘿嘿

    关于GS:

    1.属性语法在着色器定义之前设置最大顶点数:
    [maxvertexcount(N)]
    N是几何着色器为单个调用输出的顶点的最大数量
    GS可以在每次调用时输出的顶点数量是可变的,但不能超过定义的最大值。出于性能考虑,最大顶点数应尽可能小; [NVIDIA08]指出,当GS输出在1到20个标量之间时,可以实现GS的性能峰值,如果GS输出在27-40个标量之间,则性能下降50%。

    2.GS需要两个参数:输入参数和输出参数。 (实际上,它可能需要更多,但这是一个特殊的主题;请参见§11.2.4。)输入参数一般是一个定义了图元的顶点数组 — 一个顶点定义一个点,两个定义一条线,三个定义三角形,四个定义邻接线段,六个定义邻接三角形。 输入顶点的顶点类型是顶点着色器返回的顶点类型(例如,VertexOut)。 输入参数必须以原始类型为前缀,描述输入到几何着色器中的图元的类型。这可以是以下任何一种:

        1、point:输入图元是点。
        2、line:输入图元是线段(lists或strips)。
        3、triangle:输入图元是三角形(lists或strips)。
        4、lineadj:输入图元是具有邻接(lists或strips)的线段。
        5、triangleadj:输入图元是具有邻接(lists或strips)的三角形。

    3.几何着色器输出的顶点形成基元; 输出原语的类型由流类型(PointStream,LineStream,TriangleStream)指示。 对于线和三角形,输出原语总是strips。 然而,线和三角形列表可以使用内在的RestartStrip方法进行

    关于SubShader使用:

    subShaderc 中 选择执行哪个?可根据LOG设置,(从上往下 &从大到小)写)<=LOD值就执行相应的子着色器,它会在子着色器列表中找《=LOD的,但是会找第一个满足条件的,所以从小到大,会只跑第一个最小的了,所以从大到小写(LOD)



    最新:
    解决问题:
    1.面向相机问题(用的是世界下坐标)参考广告牌技术,任何物体的上方就是(0,1,0);无需先构建本地坐标系。
    2.解决锯齿问题,使用颜色过渡。
    最新代码:
      1 Shader "Vector/Point"
      2 {
      3     Properties
      4     {
      5         _Color("MianColor",color)=(1,1,1,1)
      6     }
      7     SubShader
      8     {
      9 
     10         Tags { "RenderType"="Transparent" "Queue"="Transparent+1"}
     11         LOD 100 
     12         Cull Off
     13 
     14         CGINCLUDE
     15     
     16         #include "UnityCG.cginc" 
     17 
     18         struct appdata
     19         {
     20             float4 vertex : POSITION;
     21             float2 uv : TEXCOORD0;
     22             float3 normal : NORMAL;
     23             fixed4 color : COLOR; //顶点自身的颜色
     24         }; 
     25 
     26         struct v2g
     27         {
     28             float4 vertex : POSITION;
     29             float3 nor:NORMAL;
     30             fixed4 color : COLOR; //顶点自身的颜色
     31         };
     32         
     33         struct g2f
     34         {
     35             float4 vertex : SV_POSITION;
     36             float3 pos: TEXCOORD0;
     37             float3 centerPos: TEXCOORD1;
     38             float3 norg:NORMAL;
     39             fixed4 color : COLOR; //顶点自身的颜色
     40         };
     41 
     42         //点的颜色
     43         fixed4 _Color;
     44         //边框的颜色
     45         fixed4 _LineColor;
     46         //点的半径大小(四边形内切圆)
     47         float _Radius;
     48         //点的线框宽度
     49         uniform float _LineWidth=5;
     50         //点类型
     51         float _PointType=-1;
     52         //是否是像素点
     53         float IsEqualPixelPoint=0.0;
     54         //交叉点宽度
     55         float _CrossPointWidth;
     56 
     57         //矢量点添加扩展点坐标转换      
     58         void ADD_VERT(float3 v,g2f o,inout TriangleStream<g2f> tristream)
     59         {
     60            o.vertex = UnityObjectToClipPos(v);
     61            o.pos = v;
     62            tristream.Append(o);
     63         }
     64 
     65         //矢量点添加扩展点面逻辑      
     66         void  ADD_TRI(float3 p0,float3 p1,float3 p2,g2f o,inout TriangleStream<g2f> tristream)
     67         {
     68             ADD_VERT(p0,o,tristream);
     69             ADD_VERT(p1,o,tristream);
     70             ADD_VERT(p2,o,tristream);
     71             tristream.RestartStrip();
     72         }
     73                   
     74        // (像素点)根据模型坐标获得屏幕坐标
     75        float4 GetScreenPos(float4 vertex)
     76         {
     77           float4 pos = UnityObjectToClipPos(vertex);
     78 
     79           pos = ComputeScreenPos(pos);
     80           pos.xy = pos.xy / pos.w;
     81           pos.xy = pos.xy * _ScreenParams.xy;
     82           return pos;
     83        }
     84 
     85         //(像素点)将旋转完的坐标转回剪裁空间下
     86         void ADD_VERT_Other(float4 v,g2f o,inout TriangleStream<g2f> tristream)
     87         {
     88             float4 pos=v;
     89             pos.xy=v.xy/_ScreenParams.xy;
     90             pos.xy=pos.xy * v.w;
     91 
     92             pos.y= (pos.y-(0.5*pos.w))/(_ProjectionParams.x * 0.5);
     93             pos.x=(pos.x-(0.5*pos.w))/0.5;
     94 
     95             o.vertex = pos; 
     96             o.pos=v;
     97             tristream.Append(o);
     98         }     
     99         
    100         //像素点添加点
    101         void  ADD_TRI_Other(float4 p0,float4 p1,float4 p2,g2f o,inout TriangleStream<g2f> tristream)
    102         {
    103             ADD_VERT_Other(p0,o,tristream);
    104             ADD_VERT_Other(p1,o,tristream);
    105             ADD_VERT_Other(p2,o,tristream);
    106             tristream.RestartStrip();
    107         }
    108 
    109         // 判断点是否在三角形内
    110         float PointinTriangle(float2 A, float2 B, float2 C, float2 P)
    111         {
    112             float2 ab=B-A;
    113             float2 ac=C-A;
    114             float2 ap=P-A;
    115              
    116             float u=(dot(ab,ab) *dot(ap,ac)-dot(ac,ab)* dot(ap,ab)) / (dot(ac,ac) * dot(ab,ab)-dot(ac,ab) * dot(ab,ac));
    117             float v=(dot(ac,ac) *dot(ap,ab)-dot(ac,ab)* dot(ap,ac)) / (dot(ac,ac) * dot(ab,ab)-dot(ac,ab) * dot(ab,ac));
    118 
    119                if (u < 0 || u > 1) // if u out of range, return directly
    120                {
    121                   return 2 ;
    122                }
    123 
    124                if (v < 0 || v > 1) // if v out of range, return directly
    125                 {
    126                     return 2 ;
    127                 }
    128                 return u+v;
    129         }
    130 
    131         //截圆点
    132         void DrawCirclePoint(g2f i,float type)
    133         {
    134 
    135             float _R = abs(type) < 0.05 ? _Radius +0.5 :  (_Radius - _LineWidth +0.5);
    136 
    137             float dis=distance(i.centerPos,i.pos);
    138               
    139             if(abs(type) <= 1.05 ){
    140                //剔除圆
    141                if(dis > _R)
    142                {
    143                  discard;
    144                }
    145             }
    146         }  
    147 
    148         //截正方形点
    149         void DrawSquarePoint(g2f i,float type)
    150         {
    151 
    152             float _R = abs(type) < 0.05 ? 0.92 * _Radius :  (0.92 *_Radius - _LineWidth);
    153 
    154              //计算边缘点
    155              float2 leftTop=float2(i.centerPos.x  - _R , i.centerPos.y +  _R);
    156              float2 leftButtom=float2(i.centerPos.x  - _R , i.centerPos.y -  _R);
    157              float2 rightTop=float2(i.centerPos.x  + _R , i.centerPos.y +  _R);
    158              float2 rightButtom=float2(i.centerPos.x  + _R , i.centerPos.y -  _R);
    159                
    160              //正方形剔除
    161              if(i.pos.x < leftTop.x | i.pos.x > rightTop.x | i.pos.y < leftButtom.y | i.pos.y > rightTop.y)
    162              {
    163                  discard;
    164              }
    165         }
    166 
    167         //截三角形点
    168         fixed4 DrawTrianglePoint(g2f i,float type)
    169         {
    170 
    171             float _R = abs(type) < 0.05 ? _Radius * 0.92 :  (_Radius * 0.92 );
    172              
    173             //计算边缘点
    174             float2 leftTop=float2(i.centerPos.x  - _R , i.centerPos.y +  _R);
    175             float2 leftButtom=float2(i.centerPos.x  - _R , i.centerPos.y -  _R);
    176             float2 rightTop=float2(i.centerPos.x  + _R , i.centerPos.y +  _R);
    177             float2 rightButtom=float2(i.centerPos.x  + _R , i.centerPos.y -  _R);
    178 
    179             //三角形顶点
    180             float2 topCenter=float2(i.centerPos.x , i.centerPos.y + (sin(radians(60))*2-1) * _R);
    181             float2 rightB = rightButtom;
    182             float2 leftB = leftButtom;
    183             if(abs(type-1) < 0.05)
    184             {  
    185                 float2 center=float2(0,0);
    186                 center=(topCenter+rightB+leftB) / 3;
    187                 topCenter=topCenter + normalize(center-topCenter) * 2 * _LineWidth ;
    188                 rightB = rightButtom + normalize(center-rightButtom) * 2 * _LineWidth ;
    189                 leftB = leftButtom + normalize(center-leftButtom) * 2 * _LineWidth ;
    190 
    191             }
    192 
    193             if(PointinTriangle(topCenter,rightB, leftB, i.pos.xy)>1)
    194             {
    195                 discard;
    196             }
    197 
    198             float2 right_center=(topCenter+rightB)/2;
    199             float2 buttom_center=(leftB+rightB)/2;
    200             float2 left_center=(topCenter+leftB)/2;
    201 
    202             //在右三角形内
    203             if(PointinTriangle(topCenter,i.centerPos, rightB, i.pos.xy)<=1)
    204             {
    205                float2 right_center_o=(right_center-i.centerPos);
    206                float2 P_o=(i.pos-i.centerPos);
    207                float l1= length(right_center_o-i.centerPos);
    208                float dis= dot(right_center_o,P_o)/l1;
    209 
    210                float delta =l1-0.5;
    211                float edge = smoothstep(delta, delta+0.5, dis);
    212                if(abs(type-1) < 0.05){
    213                   fixed3 col = lerp( _Color,_LineColor,  edge);
    214                   return fixed4(col, 1.0);
    215                    
    216                }
    217                else
    218                {
    219                    fixed4 target=fixed4(_LineColor.rbg,0);
    220                    fixed4 col = lerp(_LineColor, target ,edge);
    221                    return col;
    222                }
    223             }
    224             else if(PointinTriangle(topCenter,i.centerPos, leftB, i.pos.xy)<=1)
    225             {
    226                //左三角形内
    227                float2 left_center_o=(left_center-i.centerPos);
    228                float2 P_o=(i.pos-i.centerPos);
    229                float l1= length(left_center_o-i.centerPos);
    230                float dis= dot(left_center_o,P_o)/l1;
    231 
    232                float delta =l1-0.5;
    233                float edge = smoothstep(delta, delta+0.5, dis);
    234                 if(abs(type-1) < 0.05){
    235                   fixed3 col = lerp( _Color,_LineColor,  edge);
    236                   return fixed4(col, 1.0);
    237                    
    238                }
    239                else
    240                {
    241                    fixed4 target=fixed4(_LineColor.rbg,0);
    242                    fixed4 col = lerp(_LineColor, target ,edge);
    243                    return col;
    244                }
    245             }
    246             else
    247             {
    248                 //下三角型内
    249                float2 buttom_center_o=(buttom_center-i.centerPos);
    250                float2 P_o=(i.pos-i.centerPos);
    251                float l1= length(buttom_center_o-i.centerPos);
    252                float dis= dot(buttom_center_o,P_o)/l1;
    253 
    254                float delta =l1-0.5;
    255                float edge = smoothstep(delta, delta+0.5, dis);
    256                 if(abs(type-1) < 0.05){
    257                   fixed3 col = lerp( _Color,_LineColor,  edge);
    258                   return fixed4(col, 1.0);
    259                }
    260                else
    261                {
    262                    fixed4 target=fixed4(_LineColor.rbg,0);
    263                    fixed4 col = lerp(_LineColor, target ,edge);
    264                    return col;
    265                }
    266             }
    267         }
    268         
    269         //截交叉十字形点
    270         void DrawCrossPoint(g2f i,float type)
    271         {
    272 
    273             float _R = abs(type) < 0.05 ? 0.92 * _Radius :  (0.92 * _Radius - _LineWidth);
    274 
    275            //宽度 
    276            _CrossPointWidth=_R/3;
    277 
    278             float _InPoint = abs(type) < 0.05 ? _CrossPointWidth / 2 :  (_CrossPointWidth - _LineWidth) / 2;
    279 
    280             //计算边缘点
    281             float2 leftTop=float2(i.centerPos.x  - _R , i.centerPos.y +  _R);
    282             float2 leftButtom=float2(i.centerPos.x  - _R , i.centerPos.y -  _R);
    283             float2 rightTop=float2(i.centerPos.x  + _R , i.centerPos.y +  _R);
    284             float2 rightButtom=float2(i.centerPos.x  + _R , i.centerPos.y -  _R);
    285 
    286             //十字架内角点  
    287             float2 inRightTop=float2(i.centerPos.x  + _InPoint , i.centerPos.y +  _InPoint);
    288             float2 inLeftTop=float2(i.centerPos.x  - _InPoint , i.centerPos.y + _InPoint);
    289             float2 inRightButtom=float2(i.centerPos.x  + _InPoint , i.centerPos.y -  _InPoint);
    290             float2 inLeftButtom=float2(i.centerPos.x  - _InPoint , i.centerPos.y -  _InPoint);
    291 
    292             if(((i.pos.x) > (inRightTop.x) & (i.pos.y) > (inRightTop.y)) | ((i.pos.x) < (inLeftTop.x) & (i.pos.y) > (inLeftTop.y)) | ((i.pos.x) > (inRightButtom.x) & (i.pos.y) < (inRightButtom.y)) | ((i.pos.x) < (inLeftButtom.x) & (i.pos.y) < (inLeftButtom.y)) | ((i.pos.x) <= (i.centerPos.x - _R) | (i.pos.x) >= (i.centerPos.x+ _R)) | ((i.pos.y) <= (i.centerPos.y- _R) | (i.pos.y) >= (i.centerPos.y+ _R)))
    293             { 
    294                 discard;
    295             }
    296         }
    297 
    298         v2g vert(appdata_full  v)
    299         {
    300             v2g o;
    301             o.vertex = v.vertex;
    302             o.nor=v.normal;
    303             o.color=v.color;
    304             return o;
    305         }
    306 
    307         float3 _CenterOffset=float3(0,0,0);
    308         float3 GetTowardsCamera(float3 objectPos, float3 normal, float3 upDir, float3 rightDir)
    309         {
    310             objectPos -= _CenterOffset.xyz;
    311 
    312             float3 localPos = _CenterOffset.xyz + rightDir * objectPos.x + upDir * objectPos.y + normal * objectPos.z;
    313 
    314             return localPos;
    315         } 
    316 
    317         [maxvertexcount(12)]
    318         void geom(triangle v2g IN[3], inout TriangleStream<g2f> tristream)
    319         {
    320            g2f o; 
    321            //固定只扩展4个点,且初始偏转为45
    322            //矢量点
    323            if(IsEqualPixelPoint==0.0)
    324            {
    325                 //中心点   
    326                 //矢量点 
    327                 float3 centerPos=float3(0,0,0);
    328                 o.centerPos=centerPos;
    329                 o.color=IN[0].color;
    330 
    331                 //正上方点
    332                 float3 worldUp=float3(0,1,0);
    333                 float3 p=worldUp * _Radius * 1.414;
    334                 float3 p1=centerPos;
    335                 float3 p2=centerPos;
    336                 float3 p3=centerPos;
    337                 float3 p4=centerPos;
    338 
    339                 //计算偏移角
    340                 float angle= radians(360/4);
    341 
    342                 //求正方形四顶点
    343                 p1=float3((cos(radians(45)) * (p).x)-(sin(radians(45)) * (p).y),(sin(radians(45)) * (p).x)+(cos(radians(45)) * (p).y),(p).z);
    344                 p2=float3((cos(angle) * (p1).x)-(sin(angle) * (p1).y),(sin(angle) * (p1).x)+(cos(angle) * (p1).y),(p1).z);
    345                 p3=float3((cos(angle * 2) * (p1).x)-(sin(angle * 2) * (p1).y),(sin(angle * 2) * (p1).x)+(cos(angle * 2) * (p1).y),(p1).z);
    346                 p4=float3((cos(angle * 3) * (p1).x)-(sin(angle * 3) * (p1).y),(sin(angle * 3) * (p1).x)+(cos(angle * 3) * (p1).y),(p1).z);
    347 
    348                 float3 normal = mul((float3x3)UNITY_MATRIX_I_V, float3(0,0,-1));
    349                 float3 upDir =  abs(normal.y) > 0.999 ? float3(0,0,1) : float3(0,1,0);
    350                 float3 rightDir = normalize(cross(upDir, normal));
    351                 upDir = normalize(cross(normal, rightDir));
    352 
    353                 p1=GetTowardsCamera(p1, normal, upDir, rightDir);
    354                 p2=GetTowardsCamera(p2, normal, upDir, rightDir);
    355                 p3=GetTowardsCamera(p3, normal, upDir, rightDir);
    356                 p4=GetTowardsCamera(p4, normal, upDir, rightDir);
    357 
    358                 //计算法线
    359                 float3 edgeA = p2 - p1;
    360                 float3 edgeB = p3 - p1;
    361                 float3 normalFace = normalize(cross(edgeA, edgeB));
    362                 o.norg=-normalFace;
    363 
    364                 ADD_TRI(p1,p2,p3,o,tristream);
    365 
    366                 ADD_TRI(p3,p4,p1,o,tristream);
    367 
    368             }
    369             else
    370             {
    371                 //等像素点
    372                 float4 centerPos1=float4(0,0,0,1);
    373                 centerPos1= GetScreenPos(centerPos1);
    374                 float2 up=float2(0,1);
    375                 float2 pp=up * _Radius * 1.414;
    376                 //第一个点
    377                 float4 pp1=centerPos1;
    378                 float4 pp2=centerPos1;
    379                 float4 pp3=centerPos1;
    380                 float4 pp4=centerPos1;
    381 
    382                 //计算偏移角
    383                 float angle= radians(360/4);
    384 
    385                 //求正方形四顶点
    386                 pp1.xy=float2((cos(radians(45)) * (pp).x)-(sin(radians(45)) * (pp).y),(sin(radians(45)) * (pp).x)+(cos(radians(45)) * (pp).y));
    387                 pp2.xy=float2((cos(angle) * (pp1).x)-(sin(angle) * (pp1).y),(sin(angle) * (pp1).x)+(cos(angle) * (pp1).y));
    388                 pp3.xy=float2((cos(2 * angle) * (pp1).x)-(sin(2 * angle) * (pp1).y),(sin(2 * angle) * (pp1).x)+(cos(2 * angle) * (pp1).y));
    389                 pp4.xy=float2((cos(3 * angle) * (pp1).x)-(sin(3 * angle) * (pp1).y),(sin(3 * angle) * (pp1).x)+(cos(3 * angle) * (pp1).y));
    390                 
    391                 //计算偏移
    392                 pp1=pp1+float4(centerPos1.xy,0,0);
    393                 pp2=pp2+float4(centerPos1.xy,0,0);
    394                 pp3=pp3+float4(centerPos1.xy,0,0);
    395                 pp4=pp4+float4(centerPos1.xy,0,0);
    396 
    397                 //计算法线
    398                 float3 edgeA = pp2 - pp1;
    399                 float3 edgeB = pp3 - pp1;
    400                 float3 normalFace = normalize(cross(edgeA, edgeB));
    401                 o.norg=-normalFace;
    402                 
    403                 o.centerPos=centerPos1;
    404                 o.color=IN[0].color;
    405 
    406                 ADD_TRI_Other(pp1,pp2,pp3,o,tristream);
    407                 ADD_TRI_Other(pp3,pp4,pp1,o,tristream);
    408 
    409           }
    410         } 
    411             
    412        fixed4 frag (g2f i) : SV_Target
    413         {
    414                  
    415             //圆形点
    416             if (abs(_PointType)<=0.05)
    417             {    
    418                 DrawCirclePoint(i,0.0);       
    419                 float dis= distance(i.pos,i.centerPos);
    420                 float delta = _Radius-0.5;
    421                 float edge = smoothstep(delta, delta + 0.5, dis );
    422                 fixed4 target= fixed4(_LineColor.rbg,0);
    423                 fixed4 col = lerp( _LineColor, target, edge);
    424                 return col;
    425             }
    426              
    427             //正方形
    428             if(abs(_PointType-2)<=0.05)
    429             {
    430                 DrawSquarePoint(i,0.0);
    431                 float _distance=0.9*_Radius;
    432                 float2 centerTop_center=((float2(i.centerPos.x,i.centerPos.y+_distance))-i.centerPos);
    433                 float2 pos_center=(i.pos-i.centerPos);
    434                 float pos_center_dis= distance(i.pos,i.centerPos);
    435                 float dis= dot(pos_center,centerTop_center)/_distance;
    436 
    437                 float delta = _distance-0.5;
    438                 float edge = smoothstep(delta, delta + 0.5, dis );
    439                 fixed4 target= fixed4(_LineColor.rbg,0);
    440                 fixed4 col = lerp( _LineColor, target, edge);
    441                 return col;
    442 
    443 
    444             }
    445 
    446             //三角形
    447             if(abs(_PointType-1)<=0.05)
    448             {
    449                DrawTrianglePoint(i,0.0);
    450             }
    451 
    452              //交叉十字
    453             if(abs(_PointType-3)<=0.05)
    454             {
    455                 DrawCrossPoint(i,0.0);
    456             }
    457 
    458              return _LineColor;
    459         }
    460 
    461 
    462         fixed4 fragOther (g2f i) : SV_Target
    463         {
    464             //圆形点
    465             if (abs(_PointType)<=0.05)
    466             {    
    467                 DrawCirclePoint(i,1.0);   
    468                 float dis= distance(i.pos,i.centerPos);
    469                 float delta = _Radius-_LineWidth;
    470                 float edge = smoothstep(delta-0.5, delta + 0.5, dis );
    471                 fixed3 col = lerp( _Color, _LineColor, edge);
    472                 return fixed4(col, 1.0);
    473             }
    474              
    475             //正方形
    476             if(abs(_PointType-2)<=0.05)
    477             {
    478                 DrawSquarePoint(i,1.0);
    479                 float _distance=0.9*_Radius-_LineWidth;
    480                 float2 centerTop_center=((float2(i.centerPos.x,i.centerPos.y+_distance))-i.centerPos);
    481                 float2 pos_center=(i.pos-i.centerPos);
    482                 float pos_center_dis= distance(i.pos,i.centerPos);
    483                 float dis= (dot(pos_center,centerTop_center)/_distance);
    484 
    485                 float delta = _distance-0.5;
    486                 float edge = smoothstep(delta, delta + 0.5, dis );
    487                 fixed3 col = lerp( _Color, _LineColor, edge);
    488                 return fixed4(col, 1.0);
    489             }
    490 
    491             //三角形
    492             if(abs(_PointType-1)<=0.05)
    493             {
    494                DrawTrianglePoint(i,1.0);
    495             }
    496 
    497              //交叉十字
    498             if(abs(_PointType-3)<=0.05)
    499             {
    500                 DrawCrossPoint(i,1.0);
    501             }
    502 
    503               return _Color;
    504         }
    505 
    506         ENDCG
    507 
    508         Pass 
    509         {
    510               NAME "InitShader"
    511 
    512               Cull Off
    513               ZTest Off 
    514               Blend SrcAlpha OneMinusSrcAlpha
    515 
    516               CGPROGRAM
    517               
    518               #pragma target 4.0
    519               #pragma vertex vert
    520               #pragma geometry geom        
    521               #pragma fragment frag
    522 
    523               ENDCG  
    524         }
    525 
    526         Pass 
    527         {
    528               NAME "LineShader"
    529               ZTest Off
    530               Cull Off
    531 
    532               CGPROGRAM
    533               
    534               #pragma target 4.0
    535               #pragma vertex vert
    536               #pragma geometry geom        
    537               #pragma fragment fragOther
    538               
    539               ENDCG  
    540         }
    541 
    542     }
    543 
    544     FallBack "Diffuse"
    545 }



  • 相关阅读:
    Django之model补充:一对多、跨表操作
    Ajax
    Django之model详解
    Django补充之模板语言
    Django基础篇
    web框架
    linux下命令学习
    make: Warning: File `Makefile' has modification time 17 s in the future
    linux下复制文件报cp: omitting directory `XXX'
    关于控制台程序下使用mfc库中的函数时断言
  • 原文地址:https://www.cnblogs.com/answer-yj/p/12752019.html
Copyright © 2011-2022 走看看