前言

  最近打算恶补一下游戏引擎shader相关的模块。
  毕竟之前学three.js的时候就接触过GLSL语言,也知道有shadertoy之类神仙般的网站。
  但是因为实习各种原因,还是没能够进行深入学习。
  这次我在B站找了一部shader教程进行入门,没想到看完其实只是个开头而已,还没讲完,不过讲师讲得还可以吧。要吐槽的就是经常念PPT,另外shader开发不是很熟练,有些BUG犯的都是低级错误。不过视频下载来跳着看还算可以的。
教程地址

Shader概述

视频截图

  1. Shader是给GPU执行的程序,中文叫做着色器;
  2. 着色器是运行在图形处理单元上,可以让开发人员直接操作图形硬件渲染功能;
  3. shader能开发出很多好的效果,UV动画,水,雾等一些特效,这些用程序开发出来比较困难,性能还不好;
  4. 渲染流水线,模型投影,定点着色;
  5. shader一般主要有: 固定管线着色器,顶点片元着色器,表面着色器;
  • 固定管线着色器(慢慢会被淘汰);
  • 顶点shader:干预模型形态的shader;
  • 像素shader:干预像素着色的shader;
  1. 模型定点运算的时候,可以加入顶点shader来干预顶点的位置;顶点着色的时候,加入像素shader来干预像素的上色;

GPU编程语言

视频截图

  1. 什么是Direct3D和opengl;
  2. 目前面向GPU的编程语言主要有三种:
  • HLSL语言通过Direct3D编写的着色器程序,只能在Direct3D里面使用;
  • Cg语言NVIDIA和微软合作提供的语言,与c相似,Direct3D和opengl都支持;
  • GLSL语言支持OpenGL上编写Shader程序;
  1. Unity使用ShaderLab来进行着色程序的编写,对不同的平台进行编译,重点支持Cg语言;

OpenGL 是开源标准,适用于所有的平台
Directx 是微软开发的标准,只适用于Windows平台,windows也支持OpenGL

Shader Lab语法基础

视频截图

定义一个Shader,每一个着色程序都要有一个Shader

1
2
3
4
5
6
7
8
9
10

Shader "name"{//name shader名字
//定义的一些属性,定义在这里的会在属性查看器里面显示
[Propeties]
//子着色器列表,一个Shader必须至少有一个子着色器;
Subshaders{...}
/如果子着色器显卡不支持,就会降级,即Fallback操作;
[Fallback]
}

Properties定义

视频截图

  1. name(”display name”,type)=值;
  • name指的是属性的名字,Unity中用下划线开始_Name;
  • display name是在属性检查器的名字;
  • type:这个属性的类型值:只这个属性的默认值;
  1. 类型:
  • 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}
  1. Options:纹理属性选项
  • TexGen:纹理生成模式,纹理自动生成纹理坐标的模式;顶点shader将会忽略这个选项;
  • ObjectLinear,Eyelinear,SphereMap,CubeReflect CubeNormal
  • LightmapMod:光照贴图模式如果设置这个选项,纹理会被渲染器的光线贴图所影响。

视频截图

  1. _Range(“range value”,Range(0,1)=0.3;//定义一个范围
  2. _Color(”color”,Color)=(1,1,1,1);//定义一个颜色
  3. _FloatValue(”float value”,Float)=1;//定义一个浮点
  4. _MainTex(”Albedo”,Cube)=”skybox”{TexGen CubeReflect}//定义一个立方贴图纹理属性;

  Properties 定义必须是下划线开头

SubShader

视频截图

  1. SubShader{[Tags],[CommonState],Pass{}}
    子着色器由标签(Tags),通用状态,通道列表组成,它定义了一个渲染通道列表,并可选为所有通道初始化需要的通> 用状态;
  2. SubShader渲染的时候,将优先渲染一个被每个通道所定义的对象。
  3. 通道的类型:RegularPass,UsePass,GrabPass,
  4. 在通道中定义状态同时对整个子着色器可见,那么所有的通道可以共享状态;

视频截图

1
2
3
4
5
6
7
SubShader{
Tags{"Queue","Transparent"}
Pass{
Lighting Off//关闭光照
...
}
}

Tags

视频截图

  1. Tags{“标签1”=”value1””key2”=”value2”}
  2. 标签的类型:
  • Queue tag队列标签;
  • Render Type tag 渲染类型标签;
  • DisableBatching tag禁用批处理标签;
  • ForceNoShadowCasting Tag 强制不投阴影标签;
  • lgnoreProjecttor忽略投影标签;
  • TCanUseSpriteAtlas Tag,使用精灵图集标签;
  • PreviewType Tag预览类型标签;

Pass

视频截图

  1. subshader包装了一个渲染方案,这些方案由一个个通道(Pass)来执行的,SubShader可以包括很多通道块,每> 个Pass都能使几何体渲染一次;
  2. Pass基本语法:
    Pass{[Name and Tags][RenderSetup][Texture Setup]}
    Pass块的Name引用此Pass,可以在其它着色器的Pass块中引用它,减少重复操作,Name命令必须打大写;

RegularPass 渲染设置

视频截图

  1. Lighting光照:开启关闭定点光照On/off
  2. Material{材质块}:材质,定义一个使用定点光照管线的材质;
  3. ColorMaterial:颜色集计算定点光照的时使用> 顶点颜色;
  4. SeparateSpecular:开光状态开启或关闭顶点光照相关的镜面高光颜色,On/Off;
  5. Color 设置定点光照关闭时的所使用的颜色;
  6. Fog{雾块}:设置雾参数;
  7. AlphaTest:Alpha测试
  8. ZTest:深度测试模式;
  9. ZWrite:深度写模式;
  10. Blend:混合模式SourceBlendMode,DestBlendMode,AlphaSourcesBlendMode,AlphaDstBlendMode;
  11. ColorMask 颜色遮罩:设置颜色遮罩,颜色值可以由RGB或A或0或R,G,B,A的组合,设置为0关闭所有颜色通道> 渲染;
  12. Offset偏移因子:设置深度偏移;

特殊通道Pass

视频截图

  1. UsePass:插入所有来自其它着色器的给定名字的通道;UsePass”Shader/Nmae”,Name为着色器通道;UsePass”Specular/BASE”//插入Specular中为Bass的通道;
  2. GrabPass{}:一种特殊通道类型,他会捕获物体所在的位置的屏幕的内容,并写入一个纹理中,这个纹理能被用于后续通道中完成一些高级图像特效,后续通道可以使用GrabTexture进行访问;
  3. GrabPass{“纹理名称”}捕获屏幕内容到指定纹理中,后续通道可以通过纹理名称来访问;

Fallback

视频截图

  1. 降级:定义在所有子着色器之后,如果没有任何子着色器能运行,则尝试降级;
  2. Fallback “着色器名称”;
  3. Fallback Off;没有降级,并且不会打印任何警告;

Category分类

视频截图

分类是渲染命令的逻辑组。例如着色器可以有多个子着色器,他们都需要关闭雾效果

1
2
3
4
5
6
7
Shader"xxxx"{
Categroy{
Fog{Mode Off}
SubShader{...}
SubShader{...}
}
}