GPU编程标准
Direct和OpenGL两种编程标准,前者是微软提供的,一般用于Windows平台,而后者是Linux、Android、ios等都共同支持的标准。
由这两种标准就衍生出来了集中GPU编程语言,诸如HLSL、Cg、GLSL等,在Unity里面,并不直接使用者三种语言去编写,而是用自己自定义的ShaderLab去编写Shader,之后再根据平台去编译成某种语言,一般现在Unity重点支持的是Cg语言。
UnityShader基本语法
Shader “name”{
//定义一些要用到的属性,这些属性会在检视面板里面显示
[Properties]
//子着色器,一个shader里面可以不只一个Shader起作用
SubShader:{}
//如果子着色器显卡都不支持,就会自动降级到Fallback定义的版本
[Fallback]
}
Properties定义
name{“display name”, type} = 值;
- name指属性名,Unity中用下划线开始;
- display name是在属性检查器的名字;
- type:这个属性的类型
- 值:指这个属性的默认值
1. type类型
Float,int,Color(r,g,b,a)(取值范围都是0~1),Vector(4维向量),Range(start,end),2D:2D纹理属性,Cube:立方体纹理属性,3D:3D纹理属性;
纹理类型变量声明:name{“display name”, 2D} = “name”{options};
Options:纹理属性选项
- TexGen:纹理生成模式,纹理自动生成纹理坐标的模式,顶点shader将会忽略这个选项;(ObjectLinear,EyeLinear,SphereMap,CubeReflect,CubeNormal,LightmapMod:光照贴图模式如果设置这个选项,纹理会被渲染器的光线贴图所影响)
2. type定义
- Range:_Range(“range”,Range(0,1))=0.3;
- Color:_Color(“color”,Color)=(1,1,1,1);
- Float:_FloatValue(“float value”,Float)=1;
- Cube:_MainTex(“Albedo”,Cube)=“skybox”{TexGen CubeReflect};
SubShader
SubShader{[Tags],[CommonState],Pass{}}
- 子着色器由标签,通用状态,通道列表组成(渲染流水线)它定义了一个渲染通道列表,并可选为所有通道初始化需要的通用状态
- SubShader渲染时优先渲染被每一个通道所定义的对象
- 通道类型:RegularPass,UsePass,GrabPass
- 在通道中定义状态同时对整个子着色器可见,那么所有的通道可以共享状态
SubShader{
Tags{“Queue”,“Transparent”}
Pass{
Lighting Off
}
}
1. Tags
Tags{“标签1”=“value1” “key2”=“value2”}
标签类型有:
- Queue tag 队列标签
- Render Type tag 渲染类型标签
- DisableBatching tag 禁用批处理标签
- ForceNoShadowCastring tag 强制不投阴影标签
- IgnoreProjecttor tag 忽略投影标签
- CanUseSpriteAtlas tag 使用精灵图集标签
- PreviewType tag 预览类型标签
2. Pass
- SubShader 包装了一个渲染方案,这些方案由一个个Pass通道执行,SubShader可以包括很多通道快,每个pass都能使几何体渲染一次;
- Pass基本语法:
Pass{[Name and Tags][RenderSetUp][Texture Setup]}
- Name(必须大写)便于其他SubShader通过名字查找到通道
Catagory 分类
统一处理一类着色器效果,比如说有子Shader都要关闭雾等效果
Shader “xxx”{
Category{
For{Mode Off}
SubShader{…}
SubShader{…}
}
}
GPU管道流水线
我们一般干预的就是顶点shader以及片元着色shader
顶点片元着色器
1:控制灵活,但不能参与光照。
2:着色器中插入cg代码段,编写在CGPROGRAM和ENDCG之间
3:编译指令:由于我们能操作两个不同的shader,所以我们写shader的时候必须表明出入口,比如顶点着色器就是#pragma vertex name将name的函数编译为顶点着色器,而#pragma fragment name则编译为片元着色器
4:参数和返回值都有语义修饰(语义修饰:POSITION 位置、TANEGENT 切线等)
CG的数据类型
浮点数:float、half、double
定点数:相当于把表示整数的32位(比方说)前16位表示整数,后16为表示小数,这样就用一个很大的整数去表示了小数,这里的COLOR就是这样定义的。
逻辑:bool
纹理对象:sampler
可以定义结构体:与C#一致(尽量不要在结构体里面定义函数)
语义
语义:一个阶段处理数据,然后传输给下一个阶段(顶点着色器渲染流水线),那么每个阶段之间的接口,例如:顶点着色器的输入数据是出于模型空间的顶点数据,输出的是投影坐标和光照颜色;片段处理器要将光照颜色作为输入
输入语义:绑定接收参数
输出语义:绑定输出参数
语义只在特定的入口函数才有作用,其他地方无用。