UnityShader3:ShaderLab
一、UnityShader 的语言:ShaderLab
ShaderLab:专门为 UnityShader 服务的语言,在 Unity 中所有的 UnityShader 都是使用 ShaderLab 来编写的
对于之前 OpenGL 的学习需要考虑很多事情,包括但不限于模型和资源的加载、着色器的选择与输入、渲染状态的设置等,现在对于 Unity3D 还再多一个跨平台。这样要考虑的事情实在是太多了,而有了 UnityShader 这一抽象层后,开发者只需要使用 ShaderLab 来编写 UnityShader 文件就可以完成所有的工作
ShaderLab 使用了一些嵌套在花括号内部的语义 (syntax) 来描述一个 UnityShader 文件的结构,这些结构包含了许多渲染所需的数据
UnityShader 的基础结构如下所示:
Shader "Test/TestShaderA" //Shader的名字/路径
{Properties{//属性,会显示在材质面板中}SubShader{//显卡A使用的子着色器}SubShader{//显卡B使用的子着色器}Fallback "Test/TestShaderB"
}
只要新建了 .Shader 文件,都可以在这里找到:
二、Properties 语义块
属性(property)定义,这些属性会出现在材质面板中
- 每条属性的定义格式:名字 {"显示在面板上的名称", 属性类型} = 默认值
一个例子如下:
Properties
{_MainTex("Texture", 2D) = "white" {}_DepthFade("颜色深度渐变", range(0,30)) = 0.4_Distance("距离", Float) = 50[Space]_WaveScale("波纹参数", Vector) = (0.063,0.25,0.5,1)_ReflectionTex("倒影", CUBE) = "" {}_SpecularColor("高光色", color) = (1,1,1,1)
}
对应到的材质面板:
其中 [Space] 可以让面板上对应的两个属性中间空上一个间距
很好理解,其中 Properties 语义块支持的属性类型如下:
属性类型 | 默认值的定义语法 | 例子 |
Int | number | _Int ("Int, Int) = 2 |
Float | number | _Float ("Float", Float) = 1.5 |
Range(min, max) | number | _Range ("Range", Range(0.0, 5.0)) = 3.0 |
Color | (num, num, num, num) |
_Color("Color", Color) = (1,1,1,1) |
Vector | (num, num, num, num) | _Vector("Vector", Vector) = (2,3,6,1) |
2D | "defaulttexture" {} | _2D("2D", 2D) = "" {} |
Cube | "defaulttexture" {} |
_Cube("Cube", Cube) = "white" {} |
3D | "defaulttexture" {} | _3D("3D", 3D) = "black" {} |
后面三个属性的默认值是通过一个字符串后跟一个花括号来指定的,其中字符串可以留空,也可以是一些基本的内置纹理颜色,而花括号原本是用于指定纹理属性的,在5.0后的Unity版本中被废弃,留空即可
需要注意的是:Properties 语义块只是为了让属性可以出现在材质面板中,当然也可以在着色器语言(CG代码片)中直接定义属性,并通过脚本向 Shader 中传递这些属性
三、SubShader 语义块
每一个 UnityShader 文件可以包含多个 SubShader 语义块,但至少要有一个。当 Unity 需要加载这个 UnityShader 时,Unity 会扫描所有的 SubShader 语义块,然后选择第一个能够在目标平台/显卡上运行的 SubShader,如果都不支持的话,Unity 就会使用 Fallback 语义指定的 UnityShader,当然 Fallback 并不是单纯的尝试用另一个子着色器,而是将对应的子着色器的代码全部插入到这个位置
SubShader 包含的内容大致如下:
SubShader
{[Tags] //标签,可以没有[RenderSetup] //状态,可以没有Pass{[Name] //当前Pass的名称[Tags] //标签,可以没有,只对当前Pass块有效[RenderSetup] //状态,可以没有,只对当前Pass块有效//…… //核心代码}
}
Fallback "候补着色器的名字" //如果没有候补,填 Off
其中 Pass 数目过多可能导致渲染性能下降
常用标签:
标签类型 | 说明 | 例子 | 是否可在Pass块中声明 |
Queue | 控制渲染顺序,指定该物体属于哪—个渲染队列,通过这种方式可以保证所有的透明物体可以在所有不透明物体后面被渲染,也可以自定义使用的渲染队列来控制物体的渲染顺序 | Tags { "Queue"= "Transparent-10" } | X |
RenderType | 对看色器进行分类,例如是否为透明/不透明(Opaque)着色器。可以被用于着色器替换功能 | Tags { "RenderType" = "Opaque" } | X |
DisableBatching | 一些 SubShader 在使用 Unity 的批处理功能时会出现问题,这时可以通过该标签来指明是否对该 SubShader 使用批处理 | Tags { "DisableBatching" = "True" } | X |
ForceNoShadowCasting | 控制使用该 SubShader 的物体是否会投射阴影 | Tags { "ForceNoShdowCasting" = "True" } | X |
lgnoreProjector | 如果该标签值为 "True", 那么使用该 SubShader 的物体将不会受 Projector 的影响,通常用于半透明物体 | Tags { "lgnoreProjector" = "True" } | X |
CanUseSpriteAtlas | 当该 SubShader 是用于 sprites 时,需要将该标签设置为 False | Tags { "CanUseSpriteAtlas" = "False" } | X |
PreviewType | 指明材质面板将如何预览该材质,默认情况下材质 PreviewType 将显示为一个球形,可以通过将该标签的值设为 "Plane"、"SkyBox" 等以改变预览类型 | Tags { "PreviewType" = "Plane" } | X |
LightMode | 定义该 Pass 在 Unity 渲染流水线中的角色 | Tags { "LightMode" = "ForwardBase" } | ✔ |
RequireOptions | 用于指定当满足某些条件时才渲染该 Pass,它的值是一个由空格分隔的字符串 | Tags { "RequireOptions" = "SoftVegetation" } | ✔ |
状态设置:
这些应该就比较熟悉了,例如是否开启深度/模板测试等(都可在 Pass 内部声明)
状态名称 | 设置指令 | 说明 |
Cull | Cull Back I Front I Off | 设置剔除模式:剔除背面 / 正面 / 关闭剔除 |
ZTest | ZTest Less Greater I LEqual I GEqual I Equal I NotEqual I Always | 设置深度测试时使用的函数 |
ZWrite | ZWrite On I Off | 开启 / 关闭深度写入 |
Blend | Blend Srcfactor Dstfactor | 开启并设置混合模式 |
一个 SubShader 的例子:
Subshader
{Tags { "RenderType"="Opaque" "IgnoreProjector" = "True" "Queue" = "Transparent-10" }LOD 100Pass {Tags{ "LightMode" = "ForwardBase" }ZTest LEqual ZWrite Off Cull BackCGPROGRAM#pragma vertex vert#pragma fragment fragENDCG}
}
Extra:
- 在定义 Pass 名称时,可以直接通过 UsePass 来复用其他 UnityShader 中的 Pass,当然在 UsePass 时需要将对应的名字转成全大写,这是因为 Unity 内部会把所有 Pass 的名称转换成大写字母的表示
- Fallback 还会影响到阴影的投射,这个在后面再说了
UnityShader3:ShaderLab相关推荐
- UnityShader6:最简单的顶点/片元着色器
一.顶点/片元着色器基本结构 直接上代码: 这个着色器可以得到蓝色的纯色输出,如果顶点着色器得出了错误的裁剪空间坐标,那么会出现很明显表现错误 Shader "Jaihk662/NewSur ...
- UnityShader4:UnityShader的形式
前置:UnityShader2:Shader与材质 一.Standard Surface Shader 代码解析 在前置中已经了解了什么是表面着色器,下面这是 Standard Surface Sha ...
- 【浅墨Unity3D Shader编程】之一 夏威夷篇:游戏场景的创建 第一个Shader的书写
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨) ...
- 【Unity3D Shader编程】之一 夏威夷篇:游戏场景的创建 第一个Shader的书写
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨) ...
- U3D_Shader编程(第二篇:基础夯实篇)
<U3D_Shader编程> ##<U3D_Shader编程>发布说明: ++++Shader一个高大上的领域,不管怎么样,我来了. ++++立钻哥哥从2018年开始正式对Sh ...
- 【浅墨Unity3D Shader编程】之中的一个 夏威夷篇:游戏场景的创建 amp; 第一个Shader的书写...
本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨) ...
- 【浅墨Unity3D Shader编程】之一 夏威夷篇:游戏场景的创建 第一个Shader的书写...
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨) ...
- Unity Shader - ShaderLab: Culling Depth Testing 剔除与深度测试
目录:Unity Shader - 知识点目录(先占位,后续持续更新) 原文:ShaderLab: Culling & Depth Testing 版本:2019.1 ShaderLab: C ...
- shader 编程入门(一)
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅 ...
最新文章
- python 继承和多态
- ListFragment的使用
- android oppo调试模式,OPPO A59 开启USB调试模式
- pl/sql链接64位oracle数据库报错Could not initialize oci.dll
- Linux内核调试技术——kprobe使用与实现
- 只需12 个步骤,就能在AWS中创建自定义VPC,用过都惊了!
- HALCON学习之旅(六)
- 物联网进入规模化应用时代 万物互联时代到来
- RabbitMQ----源码安装
- 归并排序java版_归并排序Java实现
- 各大浏览器兼容性报告
- 操作系统——实时操作系统和分时操作系统
- 有联系的标识变量的变化一定要同步
- mapbox中文地图_使用 Mapbox 地图
- 俞敏洪的一分钟励志演讲
- 为降低普及门槛,鑫洋泉将全景环视做成“算法引擎”
- 如何进行SYN攻击防范
- linux mips 时钟中断,Linux内核中地时钟中断.pdf
- 如何复现论文?什么是论文复现?
- 75寸的电视机长和宽是多少 75寸电视长宽多少厘米
热门文章
- python的第三方库是干什么用的-python一些工作用到的第三方库
- python怎么读发音百度翻译-用python实现百度翻译
- python计算工资编程-免费直播 | 编程小白如何通过学习Python获得超高工资
- python画三维图-Python使用matplotlib绘制三维图形示例
- python零基础入门视频免费-阿里云免费推出Python零基础入门在线教程视频
- python函数定义及调用-Python:函数定义和调用时都加*,有什么作用?
- python能干什么-Python这么火,学完到底能干什么
- python安装-在Python中安装包的三种方法
- 5岁自学python编程-枣庄适合小学生学的少儿编程课程在哪里
- python基础教程廖雪峰云-Python 基础教程