ShaderLab中的CG语言
CG语句写在哪
CG需要写在Pass中,在CGPROGRAM和ENDCG之间
pragma申明编译指令
定义实现 顶点/片元着色器 代码的函数名称
pragma vertex 名字(实现顶点着色器的函数名)
pragma fragment 名字(实现片元着色器的函数名)
作用:将顶点/片元着色器实现 定位到这两个函数名中
因此只要在这两个函数中书写shader逻辑
数据类型
基础数据类型

区别:half(16位浮点数)、fixed(12位浮点数)、sampler(纹理对象句柄)
复合数据类型
一维数组
申明:int a[4] = {1,2,3,4}
长度:a.length
二维数组
int b[2][3] = {{1,2,3},{4,5,6}}
行:b.length
列:b[0].length
结构体
区别:结构体申明结束后加分号,一般在函数外申明


特殊数据类型
向量

                //二维向量
                fixed f2 = fixed2(1.2,2.5);
                //三维向量
                float3 f3 = float3(2,3,4);
                //四维向量
                int4 i4 = int4(1,2,3,4);
矩阵

                //矩阵
                int2x3 mInt2x3 = int2x3(1,2,3,
                                        4,5,6);
                float3x3 mFloat3x3 = float3x3(1,2,3,
                                              4,5,6,
                                              7,8,9);
                fixed4x4 mFloat4x4 = fixed4x4(1,2,3,4,
                                              5,6,7,8,
                                              9,10,11,12,
                                              13,14,15,16);
bool类型的特殊使用

                //bool的特殊使用
                float3 a = float3(1,2,3);
                float3 b = float3(4,5,6);
                bool3 c = a > b;
                //运行后的结果为bool3(false,false,false)
总结:

Swizzle操作符
用.的形式使用,后面跟着所需的分量顺序
对于四维向量,可以用:向量.xyzw / 向量.rgba
前者表示坐标,后者表示颜色通道
                fixed4 f4 = fixed4(1,2,3,4);
提取分量:
                //提取分量:
                //xyzw,rgba
                //第一个分量
                fixed f = f4.x;
                f = f4.r;
                //第二个分量
                f = f4.y;
                f = f4.g;
重新排列分量:
                //重新排列:
                f4 = f4.yzxw;
                f4 = f4.abgr;
创建新向量:
                //创建新的向量
                fixed3 f3 = f4.xyz;
                fixed2 f2 = f4.xz;
                fixed4 f4_2 = fixed4(f2,f2);//升维需要补齐
                f4_2 = fixed4(f3,f);//升维需要补齐
向量和矩阵的更多用法
把矩阵当作二维数组来用
用向量申明矩阵:
                fixed4x4 f4x4 = {fixed4(1,2,3,4),
                                fixed4(5,6,7,8),
                                fixed4(9,10,11,12),
                                fixed4(13,14,15,16)};
                f4x4 = {f4,
                        f4,
                        f4,
                        f4};
获取矩阵中的元素:
和获取二维数组的元素一样
                f = f4x4[0][0];
利用向量获取矩阵中的某一行:
                f4_2 = f4x4[0];
高维转低维:
直接赋值,自动在高维矩阵(向量)中截取低维矩阵(向量)部分
                fixed3 f3_2 = f4;
                f2 = f4;
                fixed2x2 f2x2 = f4x4;
运算符相关
三目运算符:和C#一样
逻辑运算符: || && ! ,不存在短路,所以不管逻辑运算符满不满足都会执行完所有条件
数学运算符:CG中的取余%只能对整数取余,这和C语言一样
流程控制语句
和C#一样
注意:CG需要更多的考虑性能消耗
- 尽量少使用循环语句,并减少次数和复杂度
- 利用GPU并行性来替代循环
- 尽量避免复杂的条件分支
函数
in和out可以有多个
无返回值:
参数有in,out之分

输入参数不改,输出参数必须初始化/修改,可以在外部调用
in和out关键字可以省略,但最好不要这么做
有返回值:
参数只有in

对于顶点vert / 片元着色器frag函数只会用单返回值进行处理
顶点/片元着色器的基本结构
            #pragma vertex myVert
            #pragma fragment myFrag
            //顶点着色器 回调函数
            //POSITION 和 SV_POSITION 是CG语言的语义
            //POSITION 模型的顶点坐标,填充到输入参数v中
            //SV_POSITION 裁剪空间中的顶点坐标,填充到输出参数SV_POSITION中
            //语义是用来限定输入输出参数,让渲染器知道用户的输入输出是什么
            float4 myVert(float4 v:POSITION):SV_POSITION{
                //mul():矩阵/向量的相乘
                //UNITY_MATRIX_MVP:Unity内置的变换矩阵,是Unity内置模型、观察、投影矩阵的集合
                //v:顶点坐标
                return mul(UNITY_MATRIX_MVP, v);
                //新版本把这个封装成了UnityObjectToClipPos(v)
            }
            //片元着色器 回调函数
            //SV_Target 告诉渲染器,输出参数是SV_Target,
            // 渲染器会把用户输出颜色储存到一个渲染目标中,输出到默认的帧缓存中
            fixed4 myFrag(): SV_Target
            {
                return fixed4(1, 0, 0, 1);
            }
效果:


语义——特殊关键字
修饰 函数的传入参数和返回值
作用:让Shader知道从哪里读取数据,并输出到哪里去
unity只支持CG的部分语义
常用语义
应用阶段->顶点着色器

顶点着色器->片元着色器

片元着色器的输出

其他语义
HLSL语义,CG语义
顶点/片元着色器获取更多数据信息
顶点着色器获取更多数据信息
使用结构体对数据封装,通过对结构体中的成员变量+语义的方式来定义想要获取的信息
            struct a2v{
                //顶点坐标
                float4 vertex : POSITION;
                //顶点法线
                float3 normal : NORMAL;
                //纹理坐标
                float2 uv : TEXCOORD0;
            };
            float4 myVert(a2v data):SV_POSITION
            {
                return UnityObjectToClipPos(data.vertex);
            }
片元着色器获取更多数据信息
片元着色器输入的数据基本都是由顶点着色器传递的
封装的结构体还需要顶点着色器的返回类型
            v2f myVert(a2v data)
            {
                //传给片元着色器的数据结构体
                v2f v2fData;
                v2fData.pos = UnityObjectToClipPos(data.vertex);
                v2fData.normal = data.normal;
                v2fData.uv = data.uv;
                return v2fData;
            }
            
            fixed4 myFrag(v2f data): SV_Target
            {
                return fixed4(0,1,0,1);
            }
ShaderLab属性类型和CG变量类型的匹配关系
Shader三大属性:数值、颜色和向量,纹理贴图




    Properties
    {
        //整形
        _MyInt("My Int", Int) = 10
        //浮点型
        _MyFloat("My Float", Range(0,1)) = 0.5
        //范围型
        _MyRage("My Range", Range(0,10)) = 5
      
        //颜色
        _MyColor("My Color", Color) = (1,1,1,1)
        //向量
        _MyVector("My Vector", Vector) = (1,1,1,1)
        //2D纹理
        _My2D("My2D", 2D) = "white" {}
        //2D数组纹理
        _My2DArray("My2DArray", 2DArray) = "white" {}
        //Cube map 纹理
        _MyCube("MyCube", Cube) = "white" {}
        //3D纹理
        _My3D("My3D", 3D) = "white" {}
    }

CG中变量类型对应的ShaderLab属性类型

如何在CG语句块中使用ShaderLab中申明的属性
直接在CG语句块中申明和属性对应类型的同名变量
            CGPROGRAM
            #pragma vertex myVert
            #pragma fragment myFrag
            float _MyInt;
            float _MyFloat;
            float _MyRage;
            fixed4 _MyColor;
            float4 _MyVector;
            sampler2D _My2D;
            samplerCUBE _MyCube;
            sampler3D _My3D;
CG内置函数
1.数学函数
三角函数

向量、矩阵

数值相关


其他

2.几何函数

3.纹理函数
二维纹理

举例:


立方体纹理

其他纹理


 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号