前言

Unity有自己的一套Shader系统,叫ShaderLab,今天主要说一下ShaderLab的语法和Unity中的几种不同种类的Shader的区别及使用场景,并分别做一些例子说明。

什么是ShaderLab

ShaderLab 是Unity3d自己封装的一个调用CG/HLSL/GLSL的接口,如果熟悉CG/HLSL/GLSL中的一种,理解起来会比较容易一些。

ShaderLab语法

首先,看一下ShaderLab的基本结构如下:

Shader "MyShader"{Properties{_MyTexture("My Texture",2D) = "white"{}//other properties like colors or vectors go here as well}SubShader{//here goes the 'meat' of your//- sureface shader or//- vertex and program shader or//- fixed function shader}SubShader{//here goes a simpler version of the SubShader//above than can run on older graphics cards}
}

上面代码可以看到,ShaderLab主要由Shader名字,属性和SubShader组成。

抽象语法可以表示成:

Shader "name" {[Properties] Subshaders [Fallback] [CustomEditor]}

Shader “name”{}:

Shader关键字加Shader名称,类似声明类class name{},Shader的名字一般是”xx/xx”,类似命名空间,这样可以避免重名。

Properties

ShaderLab的属性并不是必须的,属性主要用于暴露一些参数显示到材质(Material)球上,可以方便的调整效果,而不必每次都改代码。

属性的格式及支持的类型如下:
- 数字和范围滑条

name(“display name”,Range(min,max))=number

name(“display name”,Float) = number

name(“display name”,Int) = number
- 颜色和向量

name(“display name”,Color) = (number,number,number,number)

name(“display name”,Vector) = (number,number,number,number)
- 贴图

name(“display name”,2D) = “defaulttexture”{}

name(“display name”,Cube)= “defaulttexture”{}

name(“display name”,3D) = “defaulttexture”{}

其中name是属性的名字,在SubShader中会用到,display name是显示在material的inspector中,后面的类型定义,即是类型的修饰,又会在inspector中显示不同的控件(如Range显示滑条,Color显示颜色选择框等),赋值语句之后是默认值。

SubShader

在Unity中每个Shader都由一个或多个subshader组成。语法格式如下:

Subshader{[Tags][CommonState]Passdef[Passdef ..]}
- Tags:主要作用是告诉渲染引擎什么时候渲染和怎么样渲染

具体语法为:Tags{"TagName1" = "Value1" "TabName2"="Value2"}
1. Queue tag: Queue标签决定对象的渲染顺序。有Background(1000),Geometry(2000),AlphaTest(2450),Transparent(3000),Overlay(4000)等预定义的渲染顺序,也可以自己定义(其实就是数值,数值越大,渲染越靠后)
2. RenderType tag:RenderType tag将shader分类到几个预先定义的组,如不透明shader,alpha test shader等,一般用于Shader替换或产生相机深度纹理.稍后再详细解释。
3. DisableBatching Tag:这个标签主要用于禁用Batching,因为当Draw Call Batching后,所有对象都变换到了世界空间,而失去了模型空间信息,有”True”(禁用),”False”(不禁用,默认是这个),”LODFading”(当LOD fading激活,禁用,主要用于树)
4. ForceNoShadowCasting tag:如果为”True”,则使用此subshader渲染将不接收阴影,当在透明对象上使用shader replacement时可以避免从其它的subshader继承阴影。
5. IgnoreProjector Tag:如果为”True”,则物体不受投影影响,主要用于半透明的物体。
6. CanUseSpriteAtlasTag:如果为”False”,则sprite atlas不能使用。
7. PreviewType tag:主要影响material在inspector的显示,默认为球形,可以设置成”Plane”或”Skybox”
- CommonState:主要是设置硬件开关的各种状态。根据渲染管线,设置硬件状态,对渲染的各阶段进行控制。
1. Color,Material,Lighting:

Color color

Material {Material Block}

Lighting On|Off

SeparateSpecular On|Off

ColorMaterial AmbientAndDiffuse|Emission
2. Culling&Depth Testing:

Cull Back|Front|Off

ZWrite On|Off

ZTest Less|Greater|LEqual|GEqual|Equal|NotEqual|Always
3. Texture Combiners:

SetTexture[TextureName]{Texture Block}

SetTexture[_MainTex]{Combine
previous*texture,previous+texture}
4. Fog:

Fog {Fog Commands}

Mode Off|Global|Linear|Exp|Exp2

Color ColorValue

Density FloatValue

Range FloatValue,FloatValue
5. Alpha testing:

AlphaTest Off

AlphaTest comparison AlphaValue
6. Blending:

Blend SrcAlpha OneMinusSrcAlpha //Alpha blending

Blend One One //Additive

Blend OneMinusDstColor One//Soft Additive

Blend DstColor Zero//Multiplicative

Blend DstColor SrcColor//2x Multiplicative


- Passdef:定义渲染通道,一个subShader可以有多个pass,由于pass会产生drawcall, 一般都会用一个pass,但有一些效果可能需要多个pass配合实现。分为regular Pass,Use Pass,和Grab Pass
1. Regular Pass:语法
Pass{[Name and Tags][RenderSetup]}
Name就是指定Pass的名字 Tags和SubShader的Tags

RenderSetup是设置显卡状态
2. UsePass:引用其它Shader中的Pass名字
UsePass "Shader/Name"
3. GrabPass:抓取当前屏幕内容绘制到texture中,用于其它的pass,GrabPass{}GrabPass{"TextureName"}

Fallback

如果没有subShader可以在当前显卡运行,则尝试调用其它shader

Fallback "name"Fallback Off

CustomEditor

CustomEditor "name"
定义CustomEditor后,Unity会去找类名是CustomeEditor指定的,并继承ShaderGUI的类。如Unity自带的 Standard.shader 就是用了CustomEditor

Shader的三种写法

Unity中Shader分为surface shaders,vertex and fragment shaders或fxied function shaders
- Surface Shader:表面着色器,Unity中推荐使用的一种写法,Unity默认创建的就是Surface Shader,Surface Shader自身会编译为多个通道,不能添加Pass通道。如果需要受到光线和阴影影响,Surface Shader是最好的选择。如果不需对光线处理,不要用这个,因为会生成更多的代码。有点大材小用的感觉。
例子:

Shader "Example/Diffuse Texture"{Properties{_MainTex("Texture",2D) = "white"{}}SubShader{Tags{"RenderType" = "Opaque"}CGPROGRAM#pragma surface surf Lambertstruct Input{float2 uv_MainTex;};sampler2D _MainTex;void surf(Input IN,inout SurfaceOutput o){o.Albedo = tex2D(_MainTex,IN.uv_MainTex).rgb;}ENDCG}
}
  • vertex and fragment shader:顶点和片段着色器,功能最强大,最自由的形态,自己编写的代码会多,在Pass里放CGPROGRAM和ENDCG块。
    例子:
Shader "Custom/Simple"{Properties{_Color("BaseColor",Color) = (1,1,1,1)_MainTex("Base(RGB)",2D) = "white"{}}SubShader{tags{"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True"}Blend SrcAlpha OneMinusSrcAlphaPass{Name "Simple"Cull offCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"float4 _Color;sampler2D _MainTex;struct v2f{float4 post:POSITION;float4 uv:TEXCOORD0;};v2f vert(appdata_base v){v2f o;o.pos = mul(UNITY_MATRIX_MVP,v.vertex);o.uv = v.texcoord;return o;}half4 frag(v2f i):COLOR{float2 uv = i.uv.xy;half4 = tex2D(_MainTex.uv)*_Color;return c;}ENDCG}}
}
  • fixed function shader:固定功能着色器,写法简单,功能少,Unity官方不建议用这个写法。除非是用于比较古老的硬件,其它Shader功能不支持时才考虑用fixed function.例子:
Shader "ShaderLab/TestShader"{Properties{_Color("My Color",Color)= (.34,.85,.92,1)}SubShader{Pass{Material{Diffuse[_Color]Ambient[_Color]}Lighting On}}
}

Shader相关文件(扩展名):

  • shader: 着色器的主要文件
  • cg/cginc: 着色器的公用文件,可以在cg/shader/cginc文件中被”include”(包含),一般用来写全局方法和全局变量,方便多个shader文件调用。

ShaderLab的一些疑问补充

  • 多个Subshader的情况下,会按顺序优先选择当前第一个可用的Shader.如果都不能用就执行FallBack(如果指定的话)
  • Subshader中的pass是按顺序依次执行的。多个pass会导致多次drawcall.
  • CG块中包含的是CG语言,是编写逻辑和效果的地方,CG块可以在SubShader内,也可以在Pass内。当多个Pass的CG块相同则可以提到Subshader中,或surface Shader中CG块也是在SubShader中。
  • Category:Category解决了当多个SubShader中Tags或Common State相同时,可以提取这些到Category中,例子:

    Shader "Custom/Test"{Properties{_Color("Main Color",Color) = (1,1,1,1)}Category{Tags{"Queue" = "Transparent"}ZWrite OffBlend SrcAlpha OneMinusSrcAlphaSubShader{...}SubShader{...}}
    }

    总结

    本文主要大概总结了一下Unity中的ShaderLab语法,ShaderLab其实主要是提供了一个统一的框架,具体实现主要是用CG语言来写,关于CG语言,以后会写一篇专门针对CG语言的文章

Koo叔说Shader-Unity中的Shader相关推荐

  1. 2.在unity中创建shader模板

    知识提要: Mesh Filter : 存储一个Mesh(网格,模型的网格,就是模型的由哪些三角面组成,组成一个什么样子的模型,三角面的一些顶点信息) Mesh Renderer:用来渲染一个模型的外 ...

  2. Unity中利用shader将贴图变为黑白色

    使用Shader直接将贴图变为黑白色 Unity游戏开发中,有时候需要将贴图变为黑白色,以标记为两种状态,大部分时候都是美术做出两张图,一张彩色的一张黑白的,然后来回替换,最近为了省贴图资源,于是在网 ...

  3. [转]解读Unity中的CG编写Shader系列3——表面剔除与剪裁模式

    在上一个例子中,我们得到了由mesh组件传递的信息经过数学转换至合适的颜色区间以颜色的形式着色到物体上.这篇文章将要在此基础上研究片段的擦除(discarding fragments)和前面剪裁.后面 ...

  4. 【Unity3D Shader编程】之五 圣诞夜篇 Unity中Shader的三种形态对比 混合操作合辑

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...

  5. Unity学习之Shader

    Shader 是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序.其中Vertex Shader(顶点着色器)主要负责顶点的几何关系等的运算,Pixel Shader(像素着色器)主要负责片元颜色 ...

  6. 学习Shader Unity Shader 基础

    1.如何充分利用 Unity Shader 来为我们的游戏增光添彩? 材质和 Unity Shader: 在Unity中,我们需要配合使用材质(Material)和 Unity Shader 才能达到 ...

  7. Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法颜色、光照与材质

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨) ...

  8. Unity Shader - Making multiple shader program variants 制作shader程序多变体

    目录:Unity Shader - 知识点目录(先占位,后续持续更新) 原文:Making multiple shader program variants 版本:2019.1 Making mult ...

  9. unity中使用自定义shader进行光照贴图烘培无法出现透明度的坑爹问题

    最近开发中在对场景进行光照贴图烘焙时发现一个坑爹问题,在使用自定义shader的时候,shader命名中必须包含Transparent路径,否则烘焙的时候不对alpha通道进行计算,烘焙出来都是狗皮膏 ...

  10. 关于unity 中使用AssetBundle加载资源,shader偶尔会丢失的问题解决办法

    问题描述: 因为项目中要进行热更新设计,所以用unity官方推荐的打包方式assetbundle进行打包,打包好了以后再电脑上运行正常,但是当发布到android上后发现偶尔场景背景会出现空白,多方查 ...

最新文章

  1. Java动态代理的应用
  2. Hystrix Health Indicator及Metrics Stream支持
  3. Vue项目实战07:引入Normalize.css样式初始化
  4. jboss eap 7.0_创建委托登录模块(用于JBoss EAP 6.1)
  5. element upload预览_vue2.0 使用element-ui里的upload组件实现图片预览效果方法
  6. 内窥镜冲洗装置行业调研报告 - 市场现状分析与发展前景预测
  7. 拼多多前端岗位笔试试题 问答题部分 2017/8/1
  8. mysql 收藏表如何建立_代码收藏系列--mysql创建数据库、数据表、函数、存储过程命令...
  9. mysql免安装版的下载与安装
  10. Docker日志自动化: ElasticSearch、Logstash、Kibana以及Logspout
  11. python汉化包放哪_python环境搭建和pycharm的安装配置及汉化(零基础小白版)
  12. 笔记本通过网线给台式机分享网络
  13. Git 的暂存区(staging area)理解
  14. 列出所有的电影ID,名字和销售总额(以百万美元为单位计算)
  15. keil(MDK)中出现error: #513:
  16. 华为P20 Pro对比iPhone X:谁更能拍出人像高级美?
  17. 概率论与数理统计-ch2-随机变量及其分布
  18. 成就一亿技术人,我和CSDN的九年记忆
  19. GROUP BY小插曲
  20. 安装Properties Editor

热门文章

  1. 什么是CI/CD,以及我所熟知的CI/CD工具都是有哪些?
  2. 北航计算机学院王静远,北京航空航天大学计算机学院导师教师师资介绍简介-李帅...
  3. 【渝粤教育】电大中专建设工程法规_1作业 题库
  4. Java虚拟机及运行时数据区
  5. php追加append,PHP ArrayObject append()用法及代码示例
  6. 亚当斯分区曝光法俗解之一
  7. Google assisant 2018谷歌IO大会 谷歌助理背后的系统设计
  8. 2017 Google IO 开发者大会直播入口
  9. 乱弹集锦:火柴棍艺术大神
  10. HTB-Apocalyst