Shader笔记——初识
声明:本文仅供自己记录学习使用
Shader其实就是专门用来渲染图形的一种技术,通过shader,我们可以自定义显卡渲染画面的算法,使画面达到我们想要的效果。
GPU,CPU,显卡驱动,Directx,OpenGL,shader(无序排列)。这些都是图形渲染相关。
从unity的基础上来讲,一个模型,首先会在硬盘中加载到内存中,然后CPU读取,并且告诉GPU想要渲染成什么效果,而GPU收到CPU的指令进行渲染,而渲染的过程
上图中,在渲染时,我们可以对其中一些步骤进行编辑,按照自己的需求(改变顶点,改UV)等,cg语言编写控制,最终达到想要的效果。
而我们的主角shader并不是直接能被识别的,他在unity中编译成可识别的程序,我们可以称之为ShaderLab
Shader的两种类型
- 顶点shader,对三角形面片的顶点操作,计算每个三角面片上的顶点,并为最终像素渲染做准备
- 以像素为单位,计算光照、颜色的一系列算法。
- DirectX中
- 顶点shader叫做 Vertex Shader
- 像素Shader叫做 Pixel Shader
- OpenGL
- 顶点Shader也叫做 Vertex Shader
- 像素Shader叫做 Fragment Shader(片断Shader或者片元Shader);
- DirectX中
Shader的语言
- 基于DirectX的High Level Shading Language,简称HLSL。
- 基于OpenGL的OpenGL Shading Language,简称GLSL。
- 还有NVIDIA公司的C for Graphic,简称Cg语言。
在pc端,基本上使用的DirectX,而在android和ios,linux则使用的OpenGL
而unity作为跨平台的编辑器,无疑选择Cg语言
在unity中有三种shader:
- Surface Shaders 表面着色器
- Vertex/Fragment Shaders 顶点/片断着色器
- Fixed Function Shaders 固定管线着色器
下面是干货
ShaderLab语法基础
1.定义一个Shader,每一个着色程序都要有一个shader
Shader“name”
{
//name:shader的名字
//定义的一些属性,定义在这里会在属性查看器显示
[Propertes]
//子着色器列表,一个shader至少有一个子着色器
Subshaders{...}
//如果子着色器显卡不支持,就会降级处理,Fallback
[Fallback]
}
Propertes属性
2.Propertes定义
name("displayname",type)=值
name指属性的名字,Unity中使用下划线开始 _xxx
displayname,在属性检查器显示的名字
type这个属性的类型
值,默认值
3.类型
Float,
Int,
Color(r,g,b,a)(0~1),
Vector(4维向量),
Range(start,end),
2D:2D纹理
Rect:矩形纹理属性
Cube:立方体纹理属性
3D:3D纹理属性
例:name("displayname",2D)="name"{options}
4.Options:纹理属性选项
TexGen:纹理生成模式,纹理自动生成纹理坐标的模式,顶点shader自动忽略
ObjectLinear,EyeLinear,SphereMap,CubeReflect CubeNormal
LightmapMod:光照贴图模式如果设置,纹理会被渲染器的光线贴图影响
5.prepertes定义案例
_Range("range value",Range(0,1))=0.3;//定义一个范围值
_Color("color",Color(1,1,1,1))=(1,1,1,1);//定义一个颜色
_FloatValue("float value",Float)=1;定义一个浮点
_MainTex("Altobo",Cube)="skybox"{TexGen CubeReflect}//定义一个立方贴图纹理属性
SubShader
组成:SubShader{[Tags],[CommonState],Pass{}}
子着色器由 标签+通用状态+渲染通道并可选为所有通道初始化的通用状态
渲染的时候将优先渲染一个被每个通道所定义的对象
通道的类型:
- RegularPass
- UserPass
- GrabPass
在通道中定义状态同时对整个子着色器可见,所有通道可以共享状态
SubShader
{
Tags{"Queue","Transparent"}
Pass{
Lighting Off //关闭光照
...
}
}
Tags
Tags{"key1"="value1" "key2"="value2" "key3"="value3"}//空格隔开
Tags类型
- Queue tag队列标签
- RenderType tag渲染类型标签
- DisableBatching tag禁用批处理标签
- ForceNoShadowCasting tag强制不投影标签
- IngoreProjecttor忽略投影标签
- CanUseSpriteAtlas tag使用精灵图集标签
- PreviewType tag预览类型标签
Pass
SubShader包装了自定义的渲染方案,由一个个通道(Pass)执行,一个SubShader可以包含多个通道,每个通道都渲染一次
Pass基本写法 Pass{[Name and Tags][RenderSetup][TextureSetup]}
Pass块的Name引用此Pass,可以在其他着色器的Pass块中引用他,减少重复,Name命令必须大写
RegularPass设置
- Linghting:光照开启/关闭定点光照 On/Off
- Material:(材质)定义一个使用定点光照管线的材质
- ColorMaterial:颜色集:计算使用定点光照使用顶点颜色
- SeparateSpecular:开光状态:开启或关闭顶点光照相关的镜面高光颜色 On/Off
- Color:设置定点光照关闭时使用的颜色
- Fog:设置雾参数
- AlphaTest:Alpha测试
- ZTest:深度测试模式
- ZWrite:深度写模式
- Blend:混合模式SourceBlendMode,DestBlendMode,AlphaSourceBlendMode,AlphaDestBlendMode
- ColorMask:颜色遮罩,颜色值可以由RGB或A或0或R,G,B,A的组合,设置为0,关闭所有颜色通道渲染
- Offset:偏移因子,设置深度偏移
特殊通道Pass
UsePass:插入所有来自其他着色器的给定名字的通道
也叫通道的复用,简单地说,我有一个shader,要使用两个pass,其中一个pass已经在其他shader中使用过,那么,我们可以直接复用这个pass
UsePass"Shader/Name" Name为着色器通道
UsePass"Specular/BBB" 插入Specular中为BBB的通道
即 Pass{[Name and Tags][RenderSetup][TextureSetup]}
GrabPass:一种特殊的通道
获取物体所在位置的屏幕内容,写入一个纹理,后续可被使用
_GrabTexture访问
GrabPass{"纹理名"}获取屏幕内容到指定的纹理,后续通道可以使用纹理名访问
FallBack:对于一个shader中,所有的子着色器都无法被显卡使用,那么就会降级处理
FallBack"着色器名"
FallBack Off:没有降级,并且无任何警告
Categroy分类
分类是渲染命令的逻辑组,例如着色器可以有多个子着色器,如果他们都需要关闭雾效和和混合
Shader"xxx"{
Categroy{
Fog{Mode Off}
SubShader{...}
SubShader{...}
}
}

浙公网安备 33010602011771号