前言
最近打算恶补一下游戏引擎shader相关的模块。
毕竟之前学three.js的时候就接触过GLSL语言,也知道有shadertoy之类神仙般的网站。
但是因为实习各种原因,还是没能够进行深入学习。
这次我在B站找了一部shader教程进行入门,没想到看完其实只是个开头而已,还没讲完,不过讲师讲得还可以吧。要吐槽的就是经常念PPT,另外shader开发不是很熟练,有些BUG犯的都是低级错误。不过视频下载来跳着看还算可以的。
教程地址
Shader概述
- Shader是给GPU执行的程序,中文叫做着色器;
- 着色器是运行在图形处理单元上,可以让开发人员直接操作图形硬件渲染功能;
- shader能开发出很多好的效果,UV动画,水,雾等一些特效,这些用程序开发出来比较困难,性能还不好;
- 渲染流水线,模型投影,定点着色;
- shader一般主要有: 固定管线着色器,顶点片元着色器,表面着色器;
- 固定管线着色器(慢慢会被淘汰);
- 顶点shader:干预模型形态的shader;
- 像素shader:干预像素着色的shader;
- 模型定点运算的时候,可以加入顶点shader来干预顶点的位置;顶点着色的时候,加入像素shader来干预像素的上色;
GPU编程语言
- 什么是Direct3D和opengl;
- 目前面向GPU的编程语言主要有三种:
- HLSL语言通过Direct3D编写的着色器程序,只能在Direct3D里面使用;
- Cg语言NVIDIA和微软合作提供的语言,与c相似,Direct3D和opengl都支持;
- GLSL语言支持OpenGL上编写Shader程序;
- Unity使用ShaderLab来进行着色程序的编写,对不同的平台进行编译,重点支持Cg语言;
OpenGL 是开源标准,适用于所有的平台
Directx 是微软开发的标准,只适用于Windows平台,windows也支持OpenGL
Shader Lab语法基础
定义一个Shader,每一个着色程序都要有一个Shader
1 |
|
Properties定义
- name(”display name”,type)=值;
- name指的是属性的名字,Unity中用下划线开始_Name;
- display name是在属性检查器的名字;
- type:这个属性的类型值:只这个属性的默认值;
- 类型:
- Float,Int,Color(num,num,num,num)(0~1)Vector(4维向量),Range(start,end)
- 2D:2D纹理属性;Rect:矩形纹理属性;Cube:立方体纹理属性;
- 3D:30纹理属性I name(”displayname””,2D)=”name”(options}
- Options:纹理属性选项
- TexGen:纹理生成模式,纹理自动生成纹理坐标的模式;顶点shader将会忽略这个选项;
- ObjectLinear,Eyelinear,SphereMap,CubeReflect CubeNormal
- LightmapMod:光照贴图模式如果设置这个选项,纹理会被渲染器的光线贴图所影响。
- _Range(“range value”,Range(0,1)=0.3;//定义一个范围
- _Color(”color”,Color)=(1,1,1,1);//定义一个颜色
- _FloatValue(”float value”,Float)=1;//定义一个浮点
- _MainTex(”Albedo”,Cube)=”skybox”{TexGen CubeReflect}//定义一个立方贴图纹理属性;
Properties 定义必须是下划线开头
SubShader
- SubShader{[Tags],[CommonState],Pass{}}
子着色器由标签(Tags),通用状态,通道列表组成,它定义了一个渲染通道列表,并可选为所有通道初始化需要的通> 用状态;- SubShader渲染的时候,将优先渲染一个被每个通道所定义的对象。
- 通道的类型:RegularPass,UsePass,GrabPass,
- 在通道中定义状态同时对整个子着色器可见,那么所有的通道可以共享状态;
1 | SubShader{ |
Tags
- Tags{“标签1”=”value1””key2”=”value2”}
- 标签的类型:
- Queue tag队列标签;
- Render Type tag 渲染类型标签;
- DisableBatching tag禁用批处理标签;
- ForceNoShadowCasting Tag 强制不投阴影标签;
- lgnoreProjecttor忽略投影标签;
- TCanUseSpriteAtlas Tag,使用精灵图集标签;
- PreviewType Tag预览类型标签;
Pass
- subshader包装了一个渲染方案,这些方案由一个个通道(Pass)来执行的,SubShader可以包括很多通道块,每> 个Pass都能使几何体渲染一次;
- Pass基本语法:
Pass{[Name and Tags][RenderSetup][Texture Setup]}
Pass块的Name引用此Pass,可以在其它着色器的Pass块中引用它,减少重复操作,Name命令必须打大写;
RegularPass 渲染设置
- Lighting光照:开启关闭定点光照On/off
- Material{材质块}:材质,定义一个使用定点光照管线的材质;
- ColorMaterial:颜色集计算定点光照的时使用> 顶点颜色;
- SeparateSpecular:开光状态开启或关闭顶点光照相关的镜面高光颜色,On/Off;
- Color 设置定点光照关闭时的所使用的颜色;
- Fog{雾块}:设置雾参数;
- AlphaTest:Alpha测试
- ZTest:深度测试模式;
- ZWrite:深度写模式;
- Blend:混合模式SourceBlendMode,DestBlendMode,AlphaSourcesBlendMode,AlphaDstBlendMode;
- ColorMask 颜色遮罩:设置颜色遮罩,颜色值可以由RGB或A或0或R,G,B,A的组合,设置为0关闭所有颜色通道> 渲染;
- Offset偏移因子:设置深度偏移;
特殊通道Pass
- UsePass:插入所有来自其它着色器的给定名字的通道;UsePass”Shader/Nmae”,Name为着色器通道;UsePass”Specular/BASE”//插入Specular中为Bass的通道;
- GrabPass{}:一种特殊通道类型,他会捕获物体所在的位置的屏幕的内容,并写入一个纹理中,这个纹理能被用于后续通道中完成一些高级图像特效,后续通道可以使用GrabTexture进行访问;
- GrabPass{“纹理名称”}捕获屏幕内容到指定纹理中,后续通道可以通过纹理名称来访问;
Fallback
- 降级:定义在所有子着色器之后,如果没有任何子着色器能运行,则尝试降级;
- Fallback “着色器名称”;
- Fallback Off;没有降级,并且不会打印任何警告;
Category分类
分类是渲染命令的逻辑组。例如着色器可以有多个子着色器,他们都需要关闭雾效果
1 | Shader"xxxx"{ |