几何着色器

几何着色器用途
        添加几何体,删除几何体
        改变图元类型

 

Shader "may/Geometry Shader"
{
    Properties
    {

    }
    SubShader
    {
        Tags { "Queue" = "Geometry" "RenderType"="Opaque" }
        LOD 100
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            Cull  Off 
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag 
            #pragma geometry geometry
            #pragma multi_compile_fwdbase
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            struct VSIn
            {
                float4 vertex:POSITION;
                fixed3 normal:NORMAL;
            };
            struct VSOut
            {
                float4 pos:POSITION;
            };

            struct GSOut
            {
                float4 pos:SV_POSITION;
            };

            VSOut vert(VSIn v)
            {
                VSOut o;
                o.pos = v.vertex;
                return o;
            }
            
            
            GSOut MakeGSOut(float4 pos)
            {
                GSOut o;
                o.pos = pos ;
                return o;
            }
            [maxvertexcount(3)]                        //输出的最大顶点数, 此处对每个三角形图元,输出一个世界空间立起来的三角形
            void geometry(
                triangle VSOut i[3] : SV_POSITION,     //输入图元的类型,point line triangle,triangleadj等,对应[1] [2] [3] [6]
                inout TriangleStream<GSOut> o          //流输出对象,PointStream LineStream TriangleStream,其成员函数Append和RestartStrip
                )
            {
			    float4 pos = mul(unity_ObjectToWorld, i[0].pos);
                //float4 pos1 = mul(unity_ObjectToWorld, i[1].pos);
                //float4 pos2 = mul(unity_ObjectToWorld, i[2].pos);
				float4 pos1 = pos + float4(1, 0, 0, 0);
                float4 pos2 = pos + float4(0.5, 1, 0, 0);
                pos = UnityWorldToClipPos(pos);
                pos1 = UnityWorldToClipPos(pos1);
                pos2 = UnityWorldToClipPos(pos2);

                o.Append(MakeGSOut(pos ));
                o.Append(MakeGSOut(pos1));
                o.Append(MakeGSOut(pos2 ));
                /*o.Append(MakeGSOut(pos ));
                o.Append(MakeGSOut(pos1 ));
                o.Append(MakeGSOut(pos2 ));*/
			}

            fixed4 frag():SV_TARGET
            {
                return fixed4(1,1,1,1);
            }
            ENDCG
        }
    }
    Fallback "Diffuse"
}

TriangleStream 对象 函数Append RestartStrip
        如果直接 Append 四个点,则会形成两个三角形;若Append三个点,RestartStrip,在Append三个点,则是两个三角形而不是四个三角形。

Shader "may/Geometry Grasses"
{
    Properties
    {
        [Header(Grass Color)]
        _GrassBottomColor("Grass Bottom Color",     Color) = (1, 1, 1, 1)
        _GrassTopColor("Grass Top Color",           Color) = (1, 1, 1, 1)
        [Header(Grass Shape)]
        _GrassHight("Grass Hight",                  Range(0.00001, 0.05)) = 0.001
        _GrassWidth("Grass Width",                  Range(0.0005, 0.005)) = 0.005
        _GrassBend("Grass Bend",                    Range(0.0,0.01)) = 0.01
        [Header(Wind)]
        _WindFlowMap("Wind FlowMap",                2D) = "black"{}
        _WindStrength("wind Strength",              2D) = "white"{}
    }
    SubShader
    {
        Tags { "Queue" = "Geometry" "RenderType"="Opaque" }
        LOD 100
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            Cull  Off 
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag 
            #pragma geometry geometry
            #pragma multi_compile_fwdbase
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            fixed4 _GrassBottomColor;
            fixed4 _GrassTopColor;
            half _GrassHight;
            half _GrassWidth;
            half _GrassBend;
            //extern half PI = 3.1415927;
            sampler2D _WindFlowMap;
            float4 _WindFlowMap_ST;
            sampler2D _WindStrength;

            struct VSIn
            {
                float4 vertex:POSITION;
                fixed3 normalMS:NORMAL;
                fixed4 tangentMS:TANGENT;
                float2 uv:TEXCOORD;
            };
            struct VSOut
            {
                float4 pos:SV_POSITION;
                fixed3 normalMS:TEXCOORD;
                fixed4 tangentMS:TEXCOORD1;
                float2 uv:TEXCOORD2;
            };

            struct GSOut
            {
                float4 pos:SV_POSITION;
                float4 posWS:TEXCOORD;
                float hight :TEXCOORD1;
                float2 uv:TEXCOORD2;
            };



            //vertex shader
            VSOut vert(VSIn v)
            {
                VSOut o;
                o.pos = v.vertex;
                o.normalMS = v.normalMS;
                o.tangentMS = v.tangentMS;
                o.uv = v.uv;
                return o;
            }
            
            //geometry shader
            float rand_1_05(in float2 uv)       // 产生随机数 0 - 1
            {
                float2 noise = frac(sin(dot(uv ,float2(12.9898,78.233)*2.0)) * 43758.5453);
                return abs(noise.x + noise.y) * 0.5;
            }
            [maxvertexcount(7)]
            void geometry(triangle VSOut i[3] : SV_POSITION, inout TriangleStream<GSOut> triStream)
            {
                fixed3 Binormal0 = cross(i[0].normalMS , i[0].tangentMS.xyz ) * i[0].tangentMS.w;
                float3x3 MStoTS = {
                    i[0].tangentMS.xyz, 
                    Binormal0, 
                    i[0].normalMS
                };
                float3x3 TStoMS = transpose(MStoTS);    
                
                //规定草的形状 和 TS 下的位置偏移
                float randomGrassBend  =_GrassBend * (rand_1_05(i[0].uv) * 0.7 + 0.3);
                float randomGrassWidth = _GrassWidth * (rand_1_05(i[0].uv) * 0.4 + 0.6);
                float randomGrassHight = _GrassHight * (rand_1_05(i[0].uv) * 0.8 + 0.2);
                float angle = rand_1_05(i[0].uv) * 2 * 3.14;                                //无法使用 全局变量 PI
                float4x4 ramdomTransform =          //绕草的顶点法线 旋转
                {
                    cos(angle), -sin(angle),0,          0/* rand_1_05(i[1].uv)-0.5*/,
                    sin(angle), cos(angle), 0,          0/* rand_1_05(i[2].uv)-0.5*/,
                    0,          0,          1,          0,
                    0,          0,          0,          1
                };
                float2 windDirWS= tex2Dlod(_WindFlowMap, float4(i[0].uv, 0, 0)).xy * 2.0 -float2(1,1)  ;
                float3 windDirTS = mul(MStoTS , mul(unity_WorldToObject, (float3(windDirWS, 0))) );       //将世界风向 转到 模型 再转到 切线空间 便于草的旋转
                float3 windSpaceXAxis = normalize(float3(windDirTS.xy, 0));         //去掉 风对地吹的分量
                float3 windSpaceZAxis = float3(0, 0, 1), windSpaceYAxis = cross(windSpaceXAxis, windSpaceZAxis);
                float3x3 TangentToWindSpace = { windSpaceXAxis, windSpaceYAxis, windSpaceZAxis};
                float3x3 WindSpaceToTangent = transpose(TangentToWindSpace);

                float3 newPoint[7] = {  //tangent space
                    float3(-randomGrassWidth/2.0 ,   0,              0),
                    float3(randomGrassWidth/2.0,     0,              0),
                    float3(-randomGrassWidth/3.0,    randomGrassBend/6,      _GrassHight/3),
                    float3(randomGrassWidth/3.0,     randomGrassBend/6,      _GrassHight/3),
                    float3(-randomGrassWidth / 6,    randomGrassBend/2,      _GrassHight * 2 / 3),
                    float3(randomGrassWidth / 6,     randomGrassBend/2,      _GrassHight * 2 / 3),
                    float3(0,                   randomGrassBend,         _GrassHight)
                };
                
                
                for(int k = 0;k < 7;k++)
                {
                    GSOut o;
                    o.hight = newPoint[k].y/_GrassHight;    // grass Hight Percentage
                    o.uv = i[0].uv;

                    float3 randomGrassPosTS = mul(ramdomTransform, float4(newPoint[k],1)).xyz;   //切线空间下随机旋转朝向

                    float angle = 3.14 / 6.0 *  tex2Dlod(_WindStrength, float4(o.uv,0,1)).x *(sin(_Time.y)/2+0.5) * o.hight; //最大偏转30度,越矮的地方旋转角度小
                    float3x3 windRotateY =  //wind space 下绕Y轴旋转
                    {
                        cos(angle),     0,      sin(angle),
                        0,              1,      0,
                        -sin(angle),    0,      cos(angle)
                    };
                    randomGrassPosTS = mul(WindSpaceToTangent, mul(windRotateY, mul(TangentToWindSpace, randomGrassPosTS)));
                    
                    float3 posMS = mul(TStoMS, randomGrassPosTS) + i[0].pos;                     //切线转模型空间
                    o.posWS= mul(unity_ObjectToWorld, float4(posMS, 1));   //转到世界空间
                    o.pos = UnityWorldToClipPos(o.posWS);

                    triStream.Append(o);
                }
			}

            fixed4 frag(GSOut i):SV_TARGET
            {
                //diffuse
                fixed3 diffuseColor = lerp(_GrassBottomColor,_GrassTopColor, i.hight);
                return fixed4(diffuseColor,1);
            }
            ENDCG
        }
    }
    Fallback "Diffuse"
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值