unity 3d shaderlab 开发实战详解_【引擎】造一个 ShaderLab 语言

ShaderLab[1] 是 Unity 的声明式着色器语言,用于实现“数据驱动”渲染。这里的数据驱动,意思是将 multi-pass,pass 内的 tags,render state setup 等信息写在 ShaderLab 中,渲染管线读取这些信息动态地执行渲染逻辑。

我自己也造了一门类 ShaderLab 语言,包含 ShaderLab 的核心功能。

这里贴一个语法展示代码,后文详述。

b0aa01b278fb4ad773f2160d2a43165d.png

0. ShaderLab 作用

渲染管线(如 URP,HDRP)决定了一个渲染能力,而 ShaderLab 则能以数据驱动的方式让我们能在渲染管线内自由发挥,而不再是将 shader 的配置硬写在引擎代码中,没有灵活性可言。

ShaderLab 本质就是在底层着色语言(主要是 HLSL)的基础上,提供各种的声明信息,这些信息用于驱动渲染管线。

1. 如何给引擎加上这个功能?

  • 在引擎中编写一个 Shader 类,用于记录声明信息
  • 渲染管线根据声明信息进行渲染
  • 写一个 ShaderLab 的编译器,用于读取文件并生成对应的 Shader 对象

2. 语言设计

首先,语言设计大致参考 ShaderLab,但有许多不同的地方。语言的设计上以当前引擎提供的功能而定,未来随时根据需求而修改。

  • HLSL:unity 将 hlsl 的代码分布在各个 pass 内,并支持 #include,因此整个 shader 的功能是由多文件决定了。我这里直接将 HLSL 用一个外部文件来实现,并在后边的 Pass 中指定 VSPS 的 entry point(函数名)。两者是基本等价的。我在示例中使用了 <meta>,了解 Unity 的 asset 机制的朋友应该不陌生,就是用于指定文件的。我引擎内部也包含类似 AssetDatabase 的功能。用 meta 而不直接用相对路径的好处是与路径解耦(当然,想通过 meta 直接找到对应代码就比较麻烦了,不过简单提供一下查询工具即可)。
  • RootSignature:DX12 需要明确 Root Signature,我这里将其也实现在 shader 中(日后可能会有改动,目前暂时先实现成这样),多个pass 是共用一个 Root Signature 的。
  • Properties:基本同于 Unity,不过纹理的默认值可以通过 meta 指定
  • Pass
    • entry point:将 entry point 直接放在了 Pass 的后边(函数对应的代码都在开头的 HLSL 里)
    • queue:将 Queue 作为 pass 内的一个语句而不是作为 tag
    • blend:对 Blend 的语法进行了优化([] 是用于多 RT 的,如不写则默认 RT 0)

3. 引擎中的 Shader 类

大致如下

4d8a8f8b786376945c68a76496d68f82.png

4. 渲染管线设计

在渲染管线的一个 pass 内,对所有物体(进行一定的裁剪过滤)进行渲染。根据 queue 分成两类(opaque 和 transparent),前者优先根据同 shader 同材质排序,后者根据视距排序。

渲染过程中,尽量减少 RootSignature 的切换(opaque 的排序方式就是为了这点)。利用 DX12 提供的反射功能自动更新 SRV,CBV 等。对一个子网格渲染时,会使用 shader 的所有 pass(会根据 pass 的 tags 进行一定的过滤,如 LightMode),每个 pass 对应一个 PSO。

5. 编译器实现

用 ANTLR4 编写着色器语法,详情请查阅:Shader.g4

接着利用 ANTLR4 C++ 运行时和生成的 lexer,parser,visitor,实现 compiler

6. 实例

46826fc10e4dda7dcb9649a351f9cef4.png

d70c30f5e9cd17b61b92e670118a9817.png

7. 总结

从全部硬编写的管线,到架构出 FrameGraph,再搞定根据 shader 类声明信息实现数据驱动渲染,最后再为 shader 类专门实现一个声明式语言。终于,渲染的架构设计上不再让我感觉 low 了。这是我第一次自己设计语言,第一次实现灵活的渲染架构。真的不容易,我每天都得为了框架设计不断思考,生怕写出一个毫无灵活性的差劲设计。

最后,有关注我的朋友应该知道,我最近一直都在写着一个新引擎,再进行一定的完善后,近期就会写一篇文章宣传一下,这里预先贴一下引擎链接。

Utopia Game Engine​github.com

参考

  1. ^ShaderLab https://docs.unity3d.com/Manual/SL-Shader.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Unity 3D ShaderLab开发实战详解》是一本介绍Unity 3DShaderLab开发实战教程的PDF电子书。ShaderLabUnity中用于创建和编辑着色器的工具,通过编写自定义着色器可以实现各种特效和材质效果,提升游戏的视觉效果。 这本书的目的是帮助读者掌握ShaderLab的基本概念和技巧,并通过实例演示来深入了解如何创建高质量的着色器。书中的内容涵盖了ShaderLab开发的各个方面,从基础的着色器语法开始讲解,逐步介绍如何创建材质、纹理、光照效果、透明效果、反射效果等。书中还详细讲解了Unity的着色器渲染管线和渲染流程,帮助读者理解着色器是如何与场景、摄像机、光源等组件进行交互和渲染的。 在书中,作者通过大量的示例代码和图文说明,帮助读者理解和掌握ShaderLab的使用方法和技巧。同时,书中还提供了一些实用的开发技巧和调试技巧,帮助读者解决在实际开发中可能遇到的问题。 《Unity 3D ShaderLab开发实战详解》适合有一定Unity开发经验的读者阅读,对于对着色器开发感兴趣的游戏开发者来说,这本书是一个很好的学习资源。通过学习这本书,读者可以深入了解Unity的着色器开发技术,掌握创建高质量视觉效果的方法,提升游戏的质量和表现力。 ### 回答2: 《Unity 3D ShaderLab开发实战详解》是一本介绍UnityShaderLab开发实战指南。Shader是用来描述渲染效果的程序,而ShaderLab则是Unity的内建语言,用于编写和调试Shader。 该书包含了ShaderLab开发的基础知识和高级技巧。首先,它涵盖了ShaderLab语言的基本语法和结构,包括材质和渲染管线的理解,以及Shader中常用的算法和函数。读者可以通过逐步学习这些内容来掌握ShaderLab的基本编写和调试技巧。 书中还介绍了一些常见的渲染效果,如水面、光照、阴影等。读者可以通过学习这些案例来了解如何在实际项目中应用ShaderLab开发出高质量的渲染效果,并通过对案例代码的分析和修改来加深对ShaderLab的理解。 此外,该书还介绍了一些高级的ShaderLab开发技术,如使用GPU编程语言HLSL优化Shader性能、通过贴图及纹理坐标实现特定效果等。这些技术可以帮助读者深入理解ShaderLab的内部原理,并运用到实际项目中。 总的来说,《Unity 3D ShaderLab开发实战详解》提供了一个系统和全面的学习ShaderLab开发的平台。通过阅读本书,读者可以逐步掌握ShaderLab语言的基础知识和技巧,并学会如何应用它来实现各种炫酷的渲染效果。无论是初学者还是有一定经验的开发者,都可以从中获得实践和提高的机会。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值