一个专注音视频领域问答的小圈子

Unity 中的 Shader 不同于 OpenGL 的 GLSL ,它是通过 ShaderLab 语言编写的。

ShaderLab 是 Unity 为开发者提供的高层级的渲染抽象层,它是一种说明性语言。

ShaderLab 使用了一些嵌套在花括号内部的语义来描述一个 Unity Shader 文件的结构,这些结构包含了许多渲染所需的数据。

$a_{1}$

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

Shader "shaderName" {
    Properties{
        // 属性
    }
    
    SubShader{
        // 显卡 A 使用的子着色器
    }
    
    SubShader{
        // 显卡 B 使用的子着色器
    }
    Fallback "VertexLit"
}

可以在 Properties 语句块中定义着色器所需的各种属性,这些属性将会出现在材质面板中。

UnityShader 中的属性

UnityShader 中共有 8 种属性类型,如下代码所示:

Shader "Basic/BasicPropertiesShader"
{
    Properties
    {
        _Int ("Int",Int) = 100
        _Float("Float",Float) = 10.0
        _Range("Range",Range(0.0,5.0)) = 3.0
        _Color("Color",Color) = (1,1,1,1)
        _Vector("Vector",Vector) = (2,3,6,1)
        _2D("2D",2D) = ""{}
        _Cube("Cube",Cube) = "while"{}
        _3D("3D",3D) = "black"{}
    }
    Fallback "Diffuse"
}

Int、Float、Range 类型对应单独的数字,Color、Vector 类型对应四维向量,2D、3D、Cube 对应纹理类型,默认值通过一个字符串和花括号来指定,字符串要么是空的,要么是内置的纹理名称,比如“while”、“black”、“gray”等。

定义这些属性之后就可以在参数面板里面去调节对应值。

要想真正使用这些值去调节 Shader 效果,还需要在 SubShader 中再定义一遍。

SubShader 的使用

每一个 UnityShader 可以包含多个 SubShader 语义块,但最少要有一个。

SubShader 语义块中包含的定义如下:

SubShader {
   // 可选
   [Tags] 
   
   // 可选
   [RenderSetup]
   
   Pass{
   
   }
   
   // Other Pass
}

SubShader 中定义了一系列 Pass 和可选的状态(RenderSetup)和标签(Tags),每个 Pass 定义了一次完整的渲染流程。

Pass 中也可以定义状态(RenderSetup)和标签(Tags)。

但是 SubShader 中的标签是特定的,和 Pass 中使用的标签是不一样的。

而状态设置的语法是相同的,但 SubShader 中设置了状态,会是全局生效作用于所有的 Pass ,不过 Pass 中不想用全局状态可以在 Pass 另外定义状态来修改。

状态设置

ShaderLab 中提供的状态设置主要就是渲染时是否开启深度测试、混合模式等。

如果有了解 OpenGL 渲染的,就应该对这些不陌生了,只是 OpenGL 通过 API 调用来设定,而 ShaderLab 通过在 Shader 中来指定了。

ShaderLab 中提供的渲染状态如下,直接摘抄自 《Unity Shader 入门精要》的附图了。

Tag 标签

SubShader 的标签是一个键值对,键和值都是字符串类型,这些键值对是 SubShader 和渲染引擎之间的沟通桥梁,它们用来告诉 Unity 的渲染引擎:SubShader 希望怎样以及何时渲染这个对象。

具体的标签类型如下,,直接摘抄自 《Unity Shader 入门精要》的附图了。

Pass 块

Pass 语义块的结构如下:

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

在 Pass 语义块进行渲染之前也有一些状态要设置,Name 就是该 Pass 的名字,渲染状态和 SubShader 中提到的渲染状态一致。

Pass 中的标签不同于 SubShader 中的标签,可用的如下:

Fallback

最后的 Fallback 块就是当前面的渲染都不行才会走到这里了,相当于是兜底了。

另外,当 UnityShader 有问题的话,物体的颜色会出现粉红色的异常。

Shader 分类

UnityShader 共有三种类型的 Shader ,分别是表面着色器、顶点/片元着色器、固定函数着色器。

表面着色器 Surface Shader

表面着色器是 Unity 自己创造的一种着色器代码类型,需要的代码量很少,但渲染的代价很大。

Unity 在表面着色器背后做了很多工作,将它们转换成对应的顶点/片元着色器。

顶点/片元着色器 Vertex/Fragment Shader

顶点/片元着色器就是 OpenGL 中常用的着色器了,只不过这里统一在一个文件中描述,而且渲染流程和 OpenGL 的流程也大同小异,代码上会有些区别,原理都是一样的。

固定函数着色器

固定函数着色器用的就比较少了,也渐渐淘汰了,实际上它最后也被 Unity 转换成了顶点/片元着色器。

小结

以上就是关于 UnityShader 的基本概念,也算是 《UntiyShader入门精要》的读书笔记了。

看完一遍书,再来博客总结一遍内容,用输出促进输入,从而学的更牢固一点,接下来就要进入正式的 UnityShader 编写了。

知识星球

一个专注音视频领域问答的小圈子

公众号音视频开发进阶对应的知识星球,一个编程开发领域的专业圈子,贩卖知识和技巧!

※ 入群须知:了解该星球能提供的价值和帮助,在提问时务必阐述好背景,附带相关的信息。

iOS 用户可以加我微信 ezglumes 邀请你进星球,有疑问也可以加我微信咨询。

※ 星球内容:

基础教程:

在知识星球连载的干货教程,可以在专栏中找到,随着时间的推移,教程也会越来越多:

- 音视频基础概念
- WebRTC 入门教程及源码实践
- 播放器教程及源码实践
- OpenGL 和特效开发教程
- Vulkan 入门教程

部分内容可以在博客 https://glumes.com 中检索到,后面会在星球里持续更新.

干货分享:

涵盖了移动开发和音视频工程领域的绝大部分,从项目实战角度出发,提升能力,包括但不限于以下领域:

- Android/iOS 移动开发
- Camera 开发
- 短视频编辑 SDK 项目实践
- 在线直播和推流
- WebRTC 开发
- 播放器基础和提高
- OpenGL 图像渲染及特效开发
- C++ 基础和提高
- FFmpeg 使用和分析
- 干货资源和书籍分享

不止于技术方面的,各种 IT 新闻、茶余饭后、生活趣事也欢迎大家分享!!!

技术答疑解惑:

针对上述基础教程和干货分享的答疑,另外还有音视频和 IT 开发中的各种交流讨论。

- 基础知识点答疑
- 工业项目实践答疑
- 问题排查思路分析

一个 BUG 排查很久,不如来星球里提个问题,效率提升百倍。

求职和面试辅导:

一站式职场服务,每份工作都值得用心对待!!!

- 面试题和面试经验分享
- 简历修改和模拟面试
- 大厂内推和信息同步
- 职场经验分享
- 职业规划和发展分析

※ 星主和合伙人介绍

星主是公众号音视频开发进阶的作者,也是网站 https://glumes.com 的作者,曾参与过抖音、剪映等头部音视频 APP 底层 SDK 的开发。

合伙人也是在头条、快手从事音视频架构师的职位,具有多年的音视频开发经验,能力圈覆盖了音视频的绝大多数领域,资深音视频从业人员为你保驾护航。

微信公众号

扫描下面的二维码关注我的微信公众号《音视频开发进阶》,推送更多精彩内容!

添加我的微信 ezglumes 拉你入音视频与图形图像技术群一起交流学习~

wechat-account-qrcode

原创文章,转载请注明来源:    UnityShader 的基本概念