打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【风宇冲】Unity3D教程宝典之Shader篇:第二十七讲Geometry Shaders

原创文章如需转载请注明:转载自风宇冲Unity3D教程学院


                       Shader第二十七讲 GeometryShaders

本文
Geometry Shader简称为g
Vertex Shader简称为v
Fragment Shader简称为f

Geometry Shader是继Vertex Shader和Fragment Shader之后,由Shader Model4(第四代显卡着色架构)正式引入的第三个着色器。  性能差因为不像V和F那样高度并行.

 
Geometry Shader是vertex和pixel之间的一个optional的stage.
V的功能是处理顶点,G是处理图元,最后光栅化后传给F. 通俗理解:G是用来处理三角形的
V的输出 传给 G 作为输入,G 处理完成后,G的输出 传给 F作为输入
G输出的是最后的齐次裁剪空间,也就是经过mvp。


使用步骤
(1)  使用声明
#pragma geometry GS_Main

(2)
函数
【设置输出最大顶点数量】
函数前添加[maxvertexcount(4)]

【输入】的图元
必须添加以下前缀之一,例如添加Point就是指这个三角形被当作一个point读取第一个点。(注意如果处理一个quad,2个三角形,所以实际上只有2个点,而不是全部4个顶点)
point line triangle lineadj triangleadj
【输出】必须加inout前缀, triStream.Append(pIn);
PointStream
LineStream
TriangleStream


  1.                 [maxvertexcount(11)]
  2.                 void GS_Main(triangle GS_INPUT p[3], inout TriangleStream triStream)
  3.                 {
  4.                     for(int i=0;i<<font face="Consolas"> 3;i++)
  5.                     {
  6.                         FS_INPUT f;
  7.                         f.pos p[i].pos;
  8.                         f.tex0 p[i].tex0;
  9.                         triStream.Append(f);
  10.                     }
  11.                     triStream.RestartStrip();
  12.                 }
[例:不处理]

本例实现的效果和普通的Vertex/Fragment Shader效果一样。
  1. Shader "Custom/0same" 
  2. {
  3.     Properties 
  4.     {
  5.           _MainTex ("Particle Texture"2D"white" {}
  6.     }
  7.     SubShader 
  8.     {
  9.         Pass
  10.         {
  11.             Tags "RenderType"="Opaque" }
  12.         
  13.             CGPROGRAM
  14.                 #pragma target 5.0
  15.                 #pragma vertex VS_Main
  16.                 #pragma fragment FS_Main
  17.                 #pragma geometry GS_Main
  18.                 #include "UnityCG.cginc" 
  19.                 sampler2D   _MainTex;              
  20.                 float4      _MainTex_ST;   
  21.                 struct GS_INPUT
  22.                 {
  23.                     float4    pos        POSITION;
  24.                     float3    normal    NORMAL;
  25.                     float2  tex0    TEXCOORD0;
  26.                 };
  27.                 struct FS_INPUT
  28.                 {
  29.                     float4    pos        SV_POSITION;
  30.                     float2  tex0    TEXCOORD0;
  31.                 };
  32.                 //step1
  33.                 GS_INPUT VS_Main(appdata_base v)
  34.                 {
  35.                     GS_INPUT output (GS_INPUT)0;
  36.                     output.pos  mul(UNITY_MATRIX_MVP,v.vertex);
  37.                     output.tex0 TRANSFORM_TEX(v.texcoord,_MainTex);
  38.                     output.normal v.normal;
  39.                     return output;
  40.                 }
  41.                 //step2
  42.                 [maxvertexcount(11)]
  43.                 void GS_Main(triangle GS_INPUT p[3], inout TriangleStream triStream)
  44.                 {
  45.                     for(int i=0;i <<font face="Consolas"> 3;i++)
  46.                     {
  47.                         FS_INPUT f;
  48.                         f.pos p[i].pos;
  49.                         f.tex0 p[i].tex0;
  50.                         triStream.Append(f);
  51.                     }
  52.                     triStream.RestartStrip();
  53.                 }
  54.                 //step3
  55.                 float4 FS_Main(FS_INPUT i) COLOR
  56.                 {
  57.                     fixed4 col tex2D(_MainTex, i.tex0);   
  58.                     return col;
  59.                 }
  60.             ENDCG
  61.         }
  62.     
  63. }

[例一:显示模型顶点]

  1. Shader "Custom/ShowDots" 
  2. {
  3.     Properties 
  4.     {
  5.     }
  6.     SubShader 
  7.     {
  8.         Pass
  9.         {
  10.             Tags "RenderType"="Opaque" }
  11.             LOD 200
  12.         
  13.             CGPROGRAM
  14.                 #pragma target 5.0
  15.                 #pragma vertex VS_Main
  16.                 #pragma fragment FS_Main
  17.                 #pragma geometry GS_Main
  18.                 #include "UnityCG.cginc" 
  19.                 struct GS_INPUT
  20.                 {
  21.                     float4    pos        POSITION;
  22.                     float3    normal    NORMAL;
  23.                     float2  tex0    TEXCOORD0;
  24.                 };
  25.                 struct FS_INPUT
  26.                 {
  27.                     float4    pos        POSITION;
  28.                     float2  tex0    TEXCOORD0;
  29.                 };
  30.                 //step1
  31.                 GS_INPUT VS_Main(appdata_base v)
  32.                 {
  33.                     GS_INPUT output (GS_INPUT)0;
  34.                     output.pos  mul(_Object2Worldv.vertex);
  35.                     output.normal v.normal;
  36.                     output.tex0 float2(00);
  37.                     return output;
  38.                 }
  39.                 //step2
  40.                 [maxvertexcount(4)]
  41.                 void GS_Main(point GS_INPUT p[1], inout PointStream triStream)
  42.                 {
  43.                     float4 float4(p[0].pos.x,p[0].pos.y,p[0].pos.z,1.0f);
  44.                     //can move up a little bit
  45.                     //    v = v + float4(0,1,0,0);
  46.                     float4x4 vp mul(UNITY_MATRIX_MVP, _World2Object);
  47.                     FS_INPUT pIn;
  48.                     pIn.pos mul(vp, v);
  49.                     pIn.tex0 float2(0.0f0.0f);
  50.                     triStream.Append(pIn);
  51.                 }
  52.                 //step3
  53.                 float4 FS_Main(FS_INPUT input) COLOR
  54.                 {
  55.                     return float4(1,1,1,1);
  56.                 }
  57.             ENDCG
  58.         }
  59.     
  60. }


因为每个三角形只读一个点,如果改成如下,就每个点都显示了。


Shader "Custom/1ShowPoints2" 
{
    Properties 
    {
    }

    SubShader 
    {
        Pass
        {
            Tags "RenderType"="Opaque" }
        
            CGPROGRAM
                #pragma target 5.0
                #pragma vertex VS_Main
                #pragma fragment FS_Main
                #pragma geometry GS_Main
                #include "UnityCG.cginc" 

                struct GS_INPUT
                {
                    float4    pos        POSITION;
                    float3    normal    NORMAL;
                    float2  tex0    TEXCOORD0;
                };

                struct FS_INPUT
                {
                    float4    pos        POSITION;
                    float2  tex0    TEXCOORD0;
                };


                //step1
                GS_INPUT VS_Main(appdata_base v)
                {
                    GS_INPUT output (GS_INPUT)0;

                    output.pos  v.vertex;
                    output.normal v.normal;
                    output.tex0 float2(00);
                    return output;
                }

                //step2
                [maxvertexcount(11)]
                void GS_Main(triangle GS_INPUT p[3], inout PointStream triStream)
                {
                    for(int i=0;i<<fontface="Consolas"> 3;i++)
                    {
                        float4 float4(p[i].pos.x,p[i].pos.y,p[i].pos.z,1.0f);
                        float4x4 vp mul(UNITY_MATRIX_MVP, _World2Object);
                        FS_INPUT pIn;
                        pIn.pos mul(UNITY_MATRIX_MVP, v);
                        pIn.tex0 float2(0.0f0.0f);
                        triStream.Append(pIn);
                    }
                }

                //step3
                float4 FS_Main(FS_INPUT input) COLOR
                {
                    return float4(1,1,1,1);
                }
            ENDCG
        }
    
}

[例二:模型每个顶点显示一个公告板]


Shader "Custom/2Billboard" 
{
    Properties 
    {
        _SpriteTex ("Base (RGB)"2D"white" {}
        _Size ("Size"Range(03)) 0.5
    }

    SubShader 
    {
        Pass
        {
            Tags "RenderType"="Opaque" }
            LOD 200
        
            CGPROGRAM
                #pragma target 5.0
                #pragma vertex VS_Main
                #pragma fragment FS_Main
                #pragma geometry GS_Main
                #include "UnityCG.cginc" 

                struct GS_INPUT
                {
                    float4    pos        POSITION;
                    float3    normal    NORMAL;
                    float2  tex0    TEXCOORD0;
                };

                struct FS_INPUT
                {
                    float4    pos        POSITION;
                    float2  tex0    TEXCOORD0;
                };

                float _Size;
                float4x4 _VP;
                Texture2D _SpriteTex;
                SamplerState sampler_SpriteTex;

                GS_INPUT VS_Main(appdata_base v)
                {
                    GS_INPUT output (GS_INPUT)0;

                    output.pos  mul(_Object2Worldv.vertex);
                    output.normal v.normal;
                    output.tex0 float2(00);

                    return output;
                }

                [maxvertexcount(4)]
                void GS_Main(point GS_INPUT p[1], inout TriangleStream triStream)
                {
                    float3 up float3(010);
                    float3 look _WorldSpaceCameraPos p[0].pos;
                    look.y 0;
                    look normalize(look);
                    float3 right cross(up, look);
                    
                    float halfS 0.5f _Size;
                            
                    float4 v[4];
                    v[0float4(p[0].pos halfS right halfS up, 1.0f);
                    v[1float4(p[0].pos halfS right halfS up, 1.0f);
                    v[2float4(p[0].pos halfS right halfS up, 1.0f);
                    v[3float4(p[0].pos halfS right halfS up, 1.0f);

                    float4x4 vp mul(UNITY_MATRIX_MVP, _World2Object);
                    FS_INPUT pIn;
                    pIn.pos mul(vp, v[0]);
                    pIn.tex0 float2(1.0f0.0f);
                    triStream.Append(pIn);

                    pIn.pos  mul(vp, v[1]);
                    pIn.tex0 float2(1.0f1.0f);
                    triStream.Append(pIn);

                    pIn.pos  mul(vp, v[2]);
                    pIn.tex0 float2(0.0f0.0f);
                    triStream.Append(pIn);

                    pIn.pos  mul(vp, v[3]);
                    pIn.tex0 float2(0.0f1.0f);
                    triStream.Append(pIn);
                }

                float4 FS_Main(FS_INPUT input) COLOR
                {
                    return _SpriteTex.Sample(sampler_SpriteTex, input.tex0);
                }

            ENDCG
        }
    
}

[例三:输出金字塔]


  1. Shader "Custom/3Pyramid" 
  2. {
  3.     Properties
  4.     {
  5.         _MainTex ("Particle Texture"2D"white" {}
  6.         _Explode ("Explode factor"Range(0.04.0)) 1.0
  7.     }
  8.    
  9.     SubShader
  10.     {
  11.         Pass
  12.                  
  13.             CGPROGRAM
  14.                 #pragma target 5.0
  15.            
  16.                 #pragma vertex vert
  17.                 #pragma geometry geom
  18.                 #pragma fragment frag
  19.            
  20.                 #include "UnityCG.cginc"
  21.                    
  22.                 sampler2D   _MainTex;              
  23.                 float4      _MainTex_ST;           
  24.                 float       _Explode;
  25.                 float4x4    _ViewMatrix;
  26.                                
  27.                 struct VS_INPUT
  28.                 {
  29.                     float4 Pos  POSITION;        
  30.                     float3 Norm NORMAL         
  31.                     float2 Tex  TEXCOORD0       
  32.                 };
  33.  
  34.                 // GEOMETRY
  35.                 struct GSPS_INPUT
  36.                                          
  37.                     float4 Pos  SV_POSITION;
  38.                     float3 Norm TEXCOORD0;
  39.                     float2 Tex  TEXCOORD1;
  40.                 };
  41.                                
  42.                 // Vertex Shader
  43.                 GSPS_INPUT vert( VS_INPUT input )
  44.                 {
  45.                     GSPS_INPUT output (GSPS_INPUT)0;
  46.                    
  47.                     output.Pos  input.Pos;  // mul( float4(input.Pos,1), _Object2World);  // mul( float4(input.Pos,1), World );
  48.                     output.Norm input.Norm; // mul(input.Norm, (float3x3)_Object2World ); // mul( input.Norm, (float3x3)World );
  49.                     output.Tex  TRANSFORM_TEX(input.Tex, _MainTex);  // input.Tex;
  50.                                    
  51.                     return output;
  52.                 }
  53.  
  54.                 // Geometry Shader
  55.                 [maxvertexcount(12)]
  56.                 void geom( triangle GSPS_INPUT input[3], inout TriangleStream outStream )
  57.                 {
  58.                     GSPS_INPUT output;
  59.  
  60.                     // Calculate the face normal
  61.                     float3 faceEdgeA input[1].Pos input[0].Pos;
  62.                     float3 faceEdgeB input[2].Pos input[0].Pos;
  63.                     float3 faceNormal normalizecross(faceEdgeA, faceEdgeB) );
  64.                     float3 ExplodeAmt faceNormal*_Explode;
  65.                    
  66.                     // Calculate the face center                 
  67.                     float3 centerPos (input[0].Pos.xyz input[1].Pos.xyz input[2].Pos.xyz)/3.0;
  68.                     float2 centerTex (input[0].Tex input[1].Tex input[2].Tex)/3.0;
  69.                     centerPos += faceNormal*_Explode;                  
  70.                
  71.                     // Output the pyramid          
  72.                     forint i=0i<<fontface="Consolas"> 3i++ )
  73.                     {
  74.                         output.Pos input[i].Pos float4(ExplodeAmt,0);                                                  
  75.                         output.Pos mul(UNITY_MATRIX_MVP, output.Pos);
  76.                         output.Norm input[i].Norm;
  77.                         output.Tex input[i].Tex;
  78.                         outStream.Append( output );
  79.                        
  80.                         int iNext (i+1)%3;
  81.                         output.Pos input[iNext].Pos float4(ExplodeAmt,0);
  82.                         output.Pos mul(UNITY_MATRIX_MVP, output.Pos);
  83.                         output.Norm input[iNext].Norm;
  84.                         output.Tex input[iNext].Tex;
  85.                         outStream.Append( output );
  86.                        
  87.                         output.Pos float4(centerPos,1float4(ExplodeAmt,0);
  88.                         output.Pos mul(UNITY_MATRIX_MVP, output.Pos);                  
  89.                         output.Norm faceNormal;
  90.                         output.Tex centerTex;
  91.                         outStream.Append( output );
  92.                        
  93.                         outStream.RestartStrip();
  94.                     }
  95.                    
  96.                     forint i=2i>=0i-- )
  97.                     {
  98.                         output.Pos input[i].Pos float4(ExplodeAmt,0);
  99.                         output.Pos mul(UNITY_MATRIX_MVP, output.Pos);
  100.                         output.Norm -input[i].Norm;
  101.                         output.Tex input[i].Tex;
  102.                         outStream.Append( output );
  103.                     }
  104.                     outStream.RestartStrip();
  105.                 }
  106.                
  107.                
  108.                 // FRAG
  109.                 fixed4 frag (GSPS_INPUT COLOR0
  110.                                  
  111.                     fixed4 col tex2D(_MainTex, i.Tex);   
  112.                     return col;
  113.                      
  114.             ENDCG          
  115.         }
  116.     }
  117.     Fallback Off
  118. }

参考:

http://forum.unity3d.com/threads/geometry-shaders.156553/

http://forum.unity3d.com/threads/is-it-possible-to-use-geometry-shader-with-surface-shaders.164905/

http://msdn.microsoft.com/en-us/library/windows/desktop/bb205122(v=vs.85).aspx

http://blog.csdn.net/pizi0475/article/details/7795429

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Unity着色器常用关键字及属性
体积雾(dx9)
webgl-lessons
unity 使用噪音图实现简单水材质
A trip through the Graphics Pipeline 2011_03
边缘高光(附上代码)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服