UnityShader学习3 vertx and fragment Shader 和 CG语言入门

1.大部分知识都可以从以下代码知道

Shader "ShaderLearn/vf1" {
    SubShader{
        pass{ 
            CGPROGRAM
            // Upgrade NOTE: excluded shader from DX11; has structs without semantics (struct v2f members pos,uv)
            #pragma exclude_renderers d3d11
            // Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices
            #pragma exclude_renderers gles

            #pragma vertex vert
            #pragma fragment frag
            //类型别名
            typedef float4 FL4;
            //宏定义
            #define MACROFL float4(fl4.rgba);

            //结构体
            struct v2f
            {
                float4 pos;
                float2 uv;
            }

            //#pragma target 2.0
            //像“ : POSITION”、“: COLOR”这样的均是语意
            void vert(in float2 objPos : POSITION, out float4 pos:POSITION, out float4 col : COLOR)
            {
                //这里的in的参数是由引擎输入的
                pos = float4(objPos, 0, 1);

                //顶点程序也能对颜色做处理,输出给下面的片段程序 col
                col = pos;
            }

            void frag(inout float4 col : COLOR)
            {
                //这里的inout是指在顶点程序中 col是从顶点程序中输入的,同时也会从片段程序输出
                //如果片段程序不做处理,那么最后会直接输出由顶点程序处理的颜色

                fixed r = 1;
                fixed g = 0;
                fixed b = 0;
                fixed a = 1;

                col = fixed4(r, g, b, a);
                
                //float ==> float2 ==> float3 ==> float4  32位精度浮点
                //half ==> half2 ==> half3 ==> half4      16位精度
                ////fixed ==> fixed2 ==>fixed3 ==> fixed4    8位 颜色的输出用fixed已经足够了
                //bool bl = true;
                //sampler
                bool bl = true;
                //col = bl? col:fixed4(0,1,0,1);// 如果bl为真,取col的值  如果为假,取fixe4...

                float2 fl2 = float2(1, 0);
                float3 fl3 = float3(1, 0, 1);
                float4 fl4 = float4 (1, 1, 0, 1);
                //swizzle
                float4 fl = float4 (fl2.xy, 0, 1);
                fl = float4 (fl2.yx, 0, 1);
                fl = float4(fl4);
                fl = float4(fl3.xyxx);
                //类型别名的使用
                fl = FL4(fl4.rgba);
                //fl= float4 (fl4.raxy);错误 要么rgba 要么xyzw
                //宏使用 ,定义的时候有了“;”,所以这里就不要分号了
                fl = MACROFL
                col = fl;
                
                //矩阵
                float2x2 M2x2 = { 1,0,1,1 };
                float2x4 M2x4 = { 1,0,1,1,0,1,0,1 }; //也可以用 {1,0,1,1},{0,1,0,1}    也可以用 {fL4,{0,1,0,1}}

                col = M2x4[0];

                //数组
                float arr[4] = { 1,0.5,0.5,1 };
                col = float4(arr[0], arr[1], arr[2], arr[3]);

                //结构体使用
                v2f o;
                o.pos = fl4;
                o.uv = fl2;
                
            }
            ENDCG
        }
    }
        /*
        SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed4 vertColor : COLOR0;
            };


            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.vertColor = fixed4(v.vertex.xy, 0.0, 1.0);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                return i.vertColor;
            }
            ENDCG
        }
    }
        */
    
}

2.CG语言的函数大致和c语言差不多,用之前要声明。以下代码为例:

//如果要调用A函数
void A();

void frag (inout float4 col : COLOR)
{
  A();          
}

void A()
{
  //函数实现  
}

//===========我是分割线===========
//或者再调用之前先实现函数
void A()
{
  //函数实现  
}

void frag (inout float4 col : COLOR)
{
  A();          
}

 

3.由于CG语言不支持引用(或者说指针),所以在传参数的时候要么就设定函数有返回值,要么就把参数修饰符写成“out”。

 

4.CG语言同样也有数组,函数里带数组作为参数的时候要明确确定数组长度,比如参数为float类型的数组arr,那参数就写成“float arr[长度(用户自己定)]”。

 

5.我们也可以include相关文件来复用代码,比如:

“#include "文件路径/文件名.cginc"”,然后函数该怎么调还是怎么调,比如“文件名.cginc”里面有A()函数,我们直接“A();”这样调用。顺带一提,文件放在与unity官方的cginc同级目录,win和ios两个系统路径为:

a.Windows:“unity安装目录/Editor/Data/CGIncludes/”

b.IOS:“unity安装目录/Editor/Applications/Unity/Unity.app/Contents/CGIncludes/”

 

6.CG语言有很多内置数学函数,建议用内置的,虽然也能手写,但是nvidia是专门对函数做了优化的,比我们手写的高到不知道哪里去了,顺便贴上函数一览地址:https://blog.csdn.net/jingmengshenaaa/article/details/52809879

 

posted on 2019-05-10 17:58  炼金师  阅读(619)  评论(0)    收藏  举报

导航