0x00 写在前面

之前一直在阅读 The Book of Shaders 一书,为什么会开始写 Unity Shader 呢?一方面,因为该书目前尚未完结,写下此文时已阅读到该书的最新章节;另一方面,也需要通过一些实践来检验以及巩固所学的知识。Unity 引擎提供的环境正好是一个不错的媒介。

本文没有完整可运行的 Shader 代码,只是简单梳理一下 Unity Shader 的基本结构,为之后学习做铺垫。

0x01 基本框架

一段 Unity Shader 的基本结构如下:

// 路径及名字
Shader "Path/ShaderName"
{
// 材质属性
Properties
{ } // 子着色器
SubShader
{
[Tags]
[RenderSetup]
Pass
{
Name "PassName"
[Tags]
[RenderSetup]
// ...
// 顶点/片元着色器
}
// 更多 Pass 可选
}
// 更多 SubShader 可选
Fallback "OtherShaderName" // 可选
}

0x02 名字

Path/ShaderName 决定该 Shader 在选择面板上所处的位置,很像文件的全路径。例如,Shader "Path0/Path1/CustomShader" 将位于 Path0 → Path1 → CustomShader:

0x03 属性

Properties 括号中定义的属性将在材质面板上展示,可以方便地进行调节。

Properties
{
Name("Display Name", Type) = DefaultValue
// Other Properties
}

定义一个属性,就像在 C 语言中定义一个变量一样,只是格式稍有不同。在上面的代码中,Name 是属性的名字,Display Name 是用于展示在材质面板上的名字,Type 是属性的类型,DefaultValue 是属性的默认值。ps:其中 Name 常常以下划线开头,例如 _PropertiesName。

下面列出一些常用的属性:

数字

_Number0("Number 0", Range(-2.0, 2.0)) = 0.0
_Number1("Number 1", Float) = 0.618
_Number2("Number 2", Int) = 3

其中,Range 将在面板上展示一个滑动条,它的两个参数依次表示可以滑动的最小值和最大值。Float 是浮点数,Int 是整数。

颜色和向量

_Color("Color", Color) = (1, 1, 1, 1)
_Vector("Vector", Vector) = (1, 1, 1, 1)

颜色 Color 的四个值分别表示 RGBA,在面板上将会展示修改按钮以及吸取按钮。向量 Vector 为四维向量,在面板上展示为 XYZW 四个格子。

纹理

_2DTexture("2D Texture", 2D) = "defaulttexture" {}
_Cube("Cube", Cube) = "defaulttexture" {}
_3DTexture("3D Texture", 3D) = "defaulttexture" {}

2D 表示 2D 纹理贴图,Cube 表示立方体贴图,3D 表示 3D 纹理贴图。它们都有 Tiling 和 Offset。

在 Properties 中定义的属性可以在 SubShader 的代码块中使用,只需要在相应的地方定义与这些属性名字相同、类型匹配的变量即可。SubShader 中的类型与 Properties 中的稍有不同,下面列出两者对应的匹配关系:

  • Color 和 Vector 可对应 float4、half4、fixed4
  • Range 和 Float 可对应 float、half、fixed
  • 2D 对应 sampler2D
  • Cube 对应 samplerCUBE
  • 3D 对应 sampler3D

SubShader 代码中,有的属性也可以不在 Properties 中定义,两者都可以在运行时通过 C# 脚本动态地进行修改(如,使用方法 Material.SetFloat 修改浮点属性)。两者的区别是,定义在 Properties 中的属性在修改后将会被保存,而不在 Properties 中的属性则不会。

0x04 SubShader

每个 Unity Shader 中都可以包含多个 SubShader,当 Unity 展示一个 Mesh 时,将会从这些 SubShader 中找到第一个可以运行的来运行。因为不同的硬件对 Shader 的支持不同,这里可以理解为

0x05 Tags

Tags 是 kv 结构,用来指定 Shader 怎样以及何时渲染对象。

Tags { "TagName1" = "Value1" "TagName2" = "Value2" }

关于 Tags 的详细说明可以查看:ShaderLab: SubShader Tags

0X06 RenderSetup

RenderSetup 用来设置显卡的渲染状态。比如,设置剔除模式。

Cull Back | Front | Off

关于渲染状态的详细设置可以查看:ShaderLab: Pass

0x07 Pass

在 SubShader 中指定的 RenderSetup 将会应用到所有 Pass 中,我们也可以在 Pass 中单独指定。Pass 中的 Tags 与 SubShader 中的有所不同,主要用于控制该 Pass 中的环境光、顶点照明等,详见:ShaderLab: Pass Tags

Pass
{
Name "PassName" // 可选
[Tags]
[RenderSetup]
// ...
// 顶点/片元着色器
}

当用 Name 为 Pass 指定名字后,可以在其它地方复用这个 Pass。其中,Pass 名需要大写。用法如下:

UsePass "ShaderName/PASSNAME"

一个 SubShader 中可以有多个 Pass,这些 Pass 将会被依次执行。

0x08 Fallback

如果所有 SubShader 都无法使用时,将会尝试使用 Fallback 指定的着色器。如:

Fallback "Diffuse"

0X09 总结

本文简单梳理了一下 Unity Shader 的基本结构,因为了解不深,部分内容只能粗略带过。这些内容在以后有需要时会再深入研究。

最后,再回顾一下 Unity Shader 的基本结构吧:

  • 每个 Shader 都需要定义名字,格式为:Shader "Path/ShaderName" {}。
  • 在 Shader 的括号中,如果有需要,我们可以在 Properties 语义块中定义材质的属性。
  • 每个 Shader 都包含多个子着色器 SubShader。使用多个 SubShader 是因为不同的硬件对 Shader 的支持有所不同。当实例运行时,引擎会帮我们找到第一个可以运行的 SubShader 来运行。当所有的 SubShader 都不能运行时,则使用 Fallback 指定的 Shader。
  • 每个 SubShader 包含多个 Pass,每个 Pass 表示一个渲染流程。因为有的效果需要几个渲染才能表现出来,这时候就需要使用多个 Pass 了。
  • SubShader 和 Pass 都可以通过一些语义 (Tags 和 RenderType) 来设置渲染状态,Pass 还可以通过:Name "PassName" 来指定 Pass 的名字。

参考资料:

Unity Shader 00 - 梳理 Unity Shader 的基本结构的更多相关文章

  1. 【unity shaders】:Unity中的Shader及其基本框架

    shader和Material的基本关系 Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出.绘图单元可以依据这个输出来将图 ...

  2. 【Unity Shaders】初探Surface Shader背后的机制

    转载请注明出处:http://blog.csdn.net/candycat1992/article/details/39994049 写在前面 一直以来,Unity Surface Shader背后的 ...

  3. 【Unity Shaders】Vertex & Fragment Shader入门

    写在前面 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Shader中实现描边效果的弊端,也就是只对表面平缓的模型有效.这是因为我们是依赖法线和视角的点乘结果来进行描边判 ...

  4. Unity切换到安卓平台Shader丢失(opengl)

    Unity安卓平台shader平台丢失 Unity的工程切换到Android平台后,运行游戏出现shader丢失 解决办法:在Unity桌面图标的快捷方式后添加 -force-gles20 示例:&q ...

  5. [转]解读Unity中的CG编写Shader系列7——漫反射

    如果前面几个系列文章的内容过于冗长缺乏趣味着实见谅,由于时间原因前面的混合部分还没有写完,等以后再补充,现在开始关于反射的内容了.折射与反射在物理世界中,光的反射与折射往往是同时存在的,光源由真空或者 ...

  6. 今天写shader流光效果,shader代码少了个括号,unity shader compiler卡死且不提示原因

    今天写shader流光效果,shader代码少了个括号,unity shader compiler卡死且不提示原因 好在找到了原因,shader 代码如下,原理是提高经过的颜色亮度 void surf ...

  7. Unity中的ShaderToys——将大神们写的shader搬到unity中来吧

    http://lib.csdn.net/article/unity3d/38699 这篇文章翻译自国外的一篇文章(这里是原文链接),正在使用unity的你是否在shader toy上发现很多牛逼哄哄的 ...

  8. Physically Based Shader Development for Unity 2017 Develop Custom Lighting Systems (Claudia Doppioslash 著)

    http://www.doppioslash.com/ https://github.com/Apress/physically-based-shader-dev-for-unity-2017 Par ...

  9. unity给子物体添加Shader

    分享两个自制Shader:http://pan.baidu.com/s/1nuRcF2L Shader存放路径:\Assets\Resources\Shader\ 定义Shader类型: public ...

随机推荐

  1. Htmlcss学习笔记1——html基础

    Hyper text markup language 超文本标签语言.不是一种编程语言,而是一种标记语言标记语言是一套标记标签 开发工具 chrome subline vscode photoshop ...

  2. Apache Pulsar 2.6.1 版本正式发布:2.6.0 功能增强版,新增 OAuth2 支持

    在 Apache Pulsar 2.6.0 版本发布后的 2 个月,2020 年 8 月 21 日,Apache Pulsar 2.6.1 版本正式发布! Apache Pulsar 2.6.1 修复 ...

  3. 推荐一款强大的前端CLI命令行工具

    背景 命令行界面交互开源工具 CloudBase CLI 自发布以来,受到了大量开发者的欢迎.近期,我们发布了新鲜打磨的 CloudBase CLI 1.0 Beta,引入了许多利于开发者的新特性,下 ...

  4. Hexo-butterfly-magicv3.0.1(持续更新中....)

    介绍 Hexo-butterfly魔改v3.0.1 软件架构 本项目是基于Hexo静态博客的个性主题---蝴蝶主题魔改版 安装教程 克隆 安装依赖 hexo命令生成public文件夹 启动hexo-s ...

  5. Python pymsql模块

    pymsql pymysql这款第三方库可以帮助我们利用python语言与mysql进行链接 基本使用 首先要下载pymysql pip install pymsql 以下是pymysql的基本使用 ...

  6. Vue 3.0 中令人激动的新功能:Composition API

    正如你所期望的那样,Vue 3带来了很多令人兴奋的新功能.值得庆幸的是,Vue团队主要是在当前API的基础上引入了一些补充和改进,而不是进行重大更改,所以已经了解Vue 2的人应该很快就会对新的语法感 ...

  7. Activiti7 使用监听器分配任务人员

    视屏中老师说,一般没有人用但是我还是想试试 但是当我画图的时候,发现IDEA的那个listener监听器点不开,不知道是不是我下载的插件不对还是什么原因,所以就亲自写了,看看到时候不行就下载一个Ecl ...

  8. 用笛卡尔积来创建一千六百万大表 整体19分钟 大表建成两分钟 设置id13分钟

    昨天拙文中讲述了用自增方式创建一千六百万大表的方案,这回讨论的是用笛卡儿积,实践证明这种方案更快. 2020年3月15日08点58分实验开始 创建仅有四千数据的tb_4thousand1表: SQL& ...

  9. Ubuntu修改默认Python版本,你了解多少~

    目录 1 查看Python版本 1.1 查看装有哪些版本 1.2 查看默认版本 2 修改Python默认版本 2.1 基于文件修改 2.2 基于软链接修改 1 查看Python版本 1.1 查看装有哪 ...

  10. [LeetCode]69. x 的平方根(数学,二分)

    题目 https://leetcode-cn.com/problems/sqrtx 题解 方法一:牛顿迭代法 按点斜式求出直线方程(即过点Xn,f(Xn)),然后求出直线与x轴交点,即为Xn+1: 求 ...