UnityShader入门精要-3.3 UnityShader的结构

一个UnityShader的基础结构如下所示:

Shader "ShaderName"{
  Properties{
    //属性
 }      

  SubShader{
  //显卡A使用的子着色器
 }

  SubShader{
  //显卡B使用的子着色器
 }

 Fallback "VertexLit"

}

Unity在背后根据使用的平台来吧这些结构编译成真正的代码和Shader文件,开发者只需要和UnityShader打交道即可。(Unity编写Shader的语言是ShaderLab)

属性:在Shader中访问它们需要使用每个属性的名字,这些属性的名字通常由一个下划线开始,还需要为属性指定它的类型,还需要指定一个默认值,当第一次把该Shader赋给某个材质的时候,材质面板上显示的就是这些默认值。

属性类型:

标签类型 说明 例子
Queue
控制渲染顺序,指定该物体属于哪一个渲染队列,通

过这种方式可以保证所有的透明物体可以在所有不透

明物体后面被渲染(详见第8章),我们也可以自定义

使用的渲染队列来控制物体的渲染顺序

Tags{"Queue"="Transparent" }
RenderType
对着色器进行分类,例如这是一个不透明的着色器,

或是一个透明的着色器等。这可以被用于着色器替换

(ShaderReplacement)功能

Tags{"RenderType"="Qpaque"}
DisableBatching
一些SubShader在使用Unity的批处理功能时会出现问

题,例如使用了模型空间下的坐标进行定点动画。这时可

以通过该标签来直接指明是否对改SubShader使用批处

Tags{"DisableBatching"="True"}
ForceNoShadowCasting 控制使用该SubShader的物体是否会投射阴影 Tags{"ForceNoShadowCasting"="True"}
IgnoreProjector
如果该标签值为“True”,那么使用该SubShader的物

体将不会受Projectror的影响。通常用于半透明物体

Tags{"IgnoreProjector"="True"}
CanUseSpriteAtlas
当该SubShader是用于精灵(Sprite)时,将该标签设

为“False”

Tags{"CanUseSpriteAtlas"="False"}
PreviewType
指明材质面板将如何预览该材质。默认情况下,材质

将显示为一个球型,我们可以通过把该标签的值设为

“Plane” "SkyBox" 来改变预览类型

Tags{"PreviewType"="Plane"}

需要注意的是,上述的标签仅可以在SubShader中声明,而不可以在Pass块中声明。Pass块虽然也可以定义标签,但这些标签不同于SubShader的标签类型。这是我们下面要讲到的:

  • Pass语义块

Pass语义块包含的语义定义如下:

Pass{
  [Name]
  [Tags]
  [RenderSetup]
  //Other code
}

首先可以在Pass中定义该Pass的名称,例如:

Name "MyPassName"

通过这个名称可以使用ShaderLab的UsePass命令来直接使用其他的UnityShader中的Pass。例如:

UsePass "MyShader/MYPASSNAME"

这样可以提高代码的复用性。需要注意的是由于Unity内部会把素有的Pass的名称转换成大写字母表示,因此在使用UsePass命令时必须使用大写形式的名字。

其次,我们可以对Pass设置渲染状态。SubShader的状态设置同样适用于Pass.除了上面提到的状态设置外,在Pass中我们还可以使用固定管线的着色器命令。

Pass同样可以设置标签,但它的标签不同于SubShader的标签,这些标签也是用于告诉渲染引擎我们希望怎么样来渲染该物体。下表给出了Pass中使用的标签类型。

标签类型 说明 例子
LightMode 定义该Pass在Unity的渲染流水线中的角色 Tags{"LightMode"="ForwardBase"}
RequireOptions
用于指定当满足某些条件时才渲染该Pass,它的值是一个

由空格分隔的字符串。目前,Unity支持的选项有:

SoftVegetation.在后面的版本中可能会增加更多的选项

Tags{"RequireOptions"="SoftVegetation"}

除了上面普通的Pass定义外,UnityShader还支持一些特殊的Pass,以便进行代码服用或实现更复杂的效果。

  • UsePass : 如上文所说,可以使用该命令来服用其他UnityShader中的Pass;
  • GrabPass : 该Pass负责抓取屏幕并将结果存储在一张纹理中,以用于后续的Pass处理;

最后留一条路: Fallback

紧跟在各个SubShader语义块后面的,可以是一个Fallback命令。他用于告诉Unity,"如果上面所有的SubShader在这块显卡上都不能运行,那么就使用这个最低级的Shader吧!"

它的语义如下:

Fallback "name"
//或者
Falllback off

如上所述,我们可以通过一个字符串来告诉Unity这个“最低级的UnityShader”是谁。我们也可以任性的关闭Fallback功能,但一旦你这么做,你的意思大概就是:“如果一块显卡跑不了上面所有的Shader,那就不要管他了!”

下面给出一个使用Fallback的例子:

Fallback "VertexLit"

事实上,Fallback还会影响阴影的投射。在渲染阴影纹理时,Unity会在每个UnityShader中寻找一个阴影投射的Pass,通常情况下,我们不需要自己专门实现一个Pass, 这是因为Fallback使用 的内置Shader中包含了这样一个通用的Pass。因此,为每个UnityShaer正确的设置Fallback是非常重要的。

除了上述语义,还有一些不常用到的语义。例如,如果我们不满足于Unity内置的属性类型,想要自定义材质面板的编辑界面,就可以使用CustomEditor语义来扩展编辑界面。我们还可以使用Category语义来对UnityShader中的命令进行分组。

时间: 2024-10-22 18:46:46

UnityShader入门精要-3.3 UnityShader的结构的相关文章

UnityShader入门精要-3.5 UnityShader的形式

UnityShader可以做的事情非常多(例如设置渲染状态等),但是其最重要的任务还是指定各种着色器所需的代码.这些着色器代码可以写在SubShader语义块中(表面着色器的做法),也可以写在Pass语义块中(定点/片元着色器和固定函数着色器的做法). 在Unity中,我们可以使用下面3中形式来编写UnityShader.而不管使用哪种形式,真正意义上的Shader代码都需要包含在ShaderLab语义块中,如下所示: Shader "MyShader"{ Properties{ //

「UnityShader入门精要」第二章 渲染流水线

2.3 GPU流水线 2.3.2 顶点着色器 输入来自于CPU,处理顶点数据.输入的每个顶点都会调用一次顶点着色器,所以每次都是对单个顶点进行运算. 主要任务:坐标变换.逐顶点光照. 坐标变换:修改顶点的位置,例如模拟水面波纹效果.果冻效果等. 必须完成的工作,把顶点坐标从模型空间转换到齐次裁剪空间. 常见的如:o.pos = mul(UNITY_MVP, v.position); 2.3.3 裁剪 摄像机视野有限,视野外的物体不需要被处理,可以直接裁剪掉. 2.3.4 屏幕映射 将单位立方体内

UnityShader入门精要-第二章 渲染流水线笔记

渲染流程包括:应用阶段.几何阶段和光栅化阶段. 1.应用阶段 应用阶段是由我们的应用主导的,通常由CPU负责. 在这一阶段开发者有三个主要任务 首先 需要准备好场景的数据. 其次  为了提高渲染的性能,我们往往要做一个粗粒度剔除,把那些看不见的物体剔除出去,这样就不需要交给几何阶段去处理. 最后需要设置好每个模型的渲染状态.这些渲染状态包括但不仅限于它使用的材质(漫反射的颜色.高光反射的颜色).使用的纹理.使用的shader等.这一阶段最重要的是输出渲染所需要的几何信息,即渲染图元.渲染图元可以

Unity Shader入门精要读书笔记(一)序章

本系列的博文是笔者读<Unity Shader入门精要>的读书笔记,这本书的章节框架是: 第一章:着手准备. 第二章:GPU流水线. 第三章:Shader基本语法. 第四章:Shader数学基础. 第五章:利用简单的顶点/片元着色器来实现辅助技巧. 第六章:基本光照模型. 第七章:法线纹理.遮罩纹理等基础纹理. 第八章:透明度测试和透明度混合. 第九章:复杂光照实现. 第十章:高级纹理(立方体纹理等). 第十一章:纹理动画.顶点动画. 第十二章:屏幕特效. 第十三章:深度纹理. 第十四章:非真

Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础

摘录自 冯乐乐的<Unity Shader入门精要> 笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置.距离.角度等变量.而这些计算大部分都是在笛卡尔坐标系下进行的. 一个二维的笛卡尔坐标系包含了两个部分的信息: 一个特殊的位置,即原点,它是整个坐标系的中心. 两条过原点的互相垂直的矢量,即X轴和Y轴.这些坐标轴也被称为是该坐标的矢量. OpenGL 和 DirectX 使用了不同的二维笛卡尔坐标系.如下图所示: 2)三维笛卡尔坐标系 在三维笛卡尔坐标系中,

Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照

转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交:一些光线被物体吸收了,而另一些光线被散射到其他方向. 最后,摄像机吸收了一些光,产生了一张图像. 在光学中,我们使用辐照度来量化光.对于平行光来说,它的辐照度可通过计算在垂直于l的单位面积上单位时间内穿过的能量来得到.在计算光照模型时,我们需要知道一个物体表面的辐照度,而物体表面往往是和l不垂直的,我们可以

Lucene入门精讲视频教程

课程目录:1.Lucene-全文检索是什么?2.Lucene-流程之原生文档3.Lucene-流程之创建文档对象4.Lucene-流程之分析文档5.Lucene-流程之创建索引6.Lucene-入门创建索引7.Lucene-全文检索搜索8.Lucene-入门查询索引9.Lucene-中文第3方插件分析器(IK分析器)10.Lucene-索引库删除11.Lucene-索引库修改12.Lucene-索引库查询(Query子类查询)13.Lucene-索引库查询(解析语法查询)14.Lucene-索引

【Android的从零单排开发日记】之入门篇(三)——Android目录结构

本来的话,这一章想要介绍的是Android的系统架构,毕竟有了这些知识的储备,再去看实际的项目时才会更清楚地理解为什么要这样设计,同时在开发中遇到难题,也可以凭借着对Android的了解,尽快找出哪些模块和设计能够帮助解决该问题.但想了一下,这毕竟是入门篇,若没有实际项目开发经验的人看了之后肯定是一头雾水,所以就决定将其搁浅到大家熟悉Android之后再为大家介绍. 那么今天的主题是Android的目录结构,将系统架构比作人的骨骼架构的话,目录结构就像是人的各个器官,彼此功能各不相同,却能有序地

Hibernate入门精讲

学习Hibernate ,我们首先要知道为什么要学习它?它有什么好处?也就是我们为什么要学习框架技术? 还要知道    什么是Hibernate?    为什么要使用Hibernate?    Hibernate的配置文件的作用是什么?          Hibernate映射文件的作用是什么?     Hibernate持久化对象的状态有哪些? 现在我先上面的问题解决了. 一.我们为什么要学习框架技术? 1.框架技术有哪些? 在Java开发中,我们经常使用Struts.Hibernate和Sp