散爆社招面经

技术面

技术面基本上就是对着我的项目经历一条条问的。

1. Lua 配置表优化

项目前期使用的是哈希表形式存储的表格数据,导致内存占用较大。优化的思路就是将数据以数组的形式存储,然后重写 index 元方法将传入 key 转换为索引来访问数据。具体可以看我的笔记:


2. 人物渲染

人物采用的是 Unity URP 的 PBR 渲染,根据项目需求做了一些参数和效果的扩展。头发部分采用的是双层 Kajiya-Kay 高光。皮肤部分会预先烘焙一张曲率贴图(主要是脸部),然后用曲率和 NdotL 采样预积分 LUT 得到皮肤颜色并叠加在 PBR 的漫反射色上。衣服部分主要是丝绸会特殊一点,需要用各向异性计算两层高光,一层横向一层纵向,类似于天刀那样的效果。

3. PBR 的理解

这个就没什么好说的了,各类文章和教程都有详细介绍 PBR 的内容。

4. 雨天潮湿效果

雨天潮湿主要是涉及到光滑度、法线强度、漫反射这三个部分。由于材质表面有雨水附着,因此适当提高光滑度、降低法线强度、降低漫反射就能够实现出湿润效果。如果想更进一步实现出积水效果,那么可以额外添加一张高度图(或者直接用粗糙度贴图代替,将有水坑的地方涂黑),并结合一个全局的潮湿度参数(区间最好是 0-1)来控制积水程度。具体的实现细节可以参考这篇文章:


5. 草地渲染

项目中用到的渲染方案是 GPU Instance,利用DrawMeshInstanced和 CullingGroup 做实例化草地的渲染以及剔除。之前我有尝试过 Indirect Draw,也就是用DrawMeshInstancedIndirect来绘制草地,在 Compute Shader 中执行剔除算法。不过由于我们的场景并不是很大,所以最终还是没采用这种做法。

由于是中小型场景,所以草地的位置直接是用自己写的草刷工具刷出来的,并没有用密度来实时生成草的位置。其实关于草地的渲染还有很多能讲的,比如草地区块的粗粒度划分、利用四叉树动态加载周围的草数据、Over Draw 问题等等,不过面试的时候只讲了这么多。

6. URP

URP 部分主要是问了一些扩展相关的问题,比如有没有修改 IBL 部分(因为 Unity 的 PBR 公式是拟合优化过的,不是像 UE4 那样去采样一张预积分的 LUT)。Shadowmask 的问题还着重问了我一下,但事实上 URP 10 已经官方支持了 Shadowmask,就算是用的低版本也只需要编写少量代码就能支持 Shadowmask。

7. GPU 粒子优化

粒子的优化其实是参考了 UWA 2020 上战双帕弥什的分享,主要的优化思路就是将粒子运动轨迹按照时间帧进行切分,将每一帧中所有的粒子数据保存成 Mesh 数据并用 Shader 进行还原。用 Mesh 存储数据的优点如下:

  • Mesh 支持 Bounding Box,可以做视锥剔除。
  • 可以直接挂在 Mesh Renderer 组件上进行渲染,播放一段粒子效果只需要按照顺序切换对应的 Mesh 即可。
  • 这种做法对于低端设备的支持较好。
  • 已经运动完的粒子并不会被烘焙到 Mesh 中。
  • 渲染效率很高,且支持 SRP Batcher,相同的粒子数据只占一份。

之前和组内人员讨论时,他们觉得这种做法不如实时粒子模拟,理由是粒子数一旦提高就会占用大量内存。我个人觉得有许多优化本质上都是空间和时间的互换,具体采用哪种做法取决于游戏实际的需求。对于战双这种游戏类型来说,它需要在维持高帧率、适配低端机型的情况下渲染大量类似于火花的粒子,那么这套方案无疑就是更好的选择。如果游戏需要那种大型的粒子特效(比如粒子传送门),那么自然就可以考虑用 Compute Shader 或者多张 RT 做实时模拟。至于像是雨天这种重复度很高的粒子效果完全可以只烘焙一段 1s 的粒子轨迹,然后在场景中重复地进行摆放即可在保证效果的前提下完成高效渲染。总的来说,对于一套方案好不好需要结合实际应用场景来评价,而不是单方面做一些测试就下结论说不好用。

当然,这种做法也是会有透明排序问题的,只不过战双做的粒子效果都是类似于火花这种重复度很高的,基本上看不出来排序问题。

8. Unity 的 GC

Unity 的 GC 可以看看这个分享,讲的很详细:


9. C# 基础

C# 只问了几个很基本的问题:

  • class 和 struct 区别
  • Dictionary 的实现
  • 虚函数实现

HR面

问了一些基本情况,比如为什么要离职之类的。

说起来我最开始投的是客户端岗位,但是可能是因为我简历上写了很多渲染有关的东西,因此面试的时候基本没怎么问客户端的内容,最后也是给的技术美术岗(我本来也是想做TA岗XD)。
#面经##社招##散爆网络#
全部评论
楼主你好,对于Lua配置表优化笔记我有个问题不大理解,文中给的优化方案在访问时元方法里面实际上还是进行了一次key-value的哈希吧,好像还是牺牲了时间来换空间,并不是文中说的优化了访问时间,我测了下在访问时间上应该是比优化前更耗时的,以下是我测试的代码和结果 local loopTimes = 100000 local _key2index = { id = 1, name = 2, number = 3 } local _o = {     __index = function(data, key)         local index = _key2index[key]         if index == nil then             return nil         end         return data[index]     end,     __newindex = function(data, key, value)         error("Can't modify a readonly table!")     end } local _M = {     [1] = setmetatable({1,"test1",100}, _o),     [2] = setmetatable({2,"test2",200}, _o) } local _X = {     [1] = { id = 1,name = "test1",number = 100 },     [2] = { id = 2,name = "test2",number = 200 } } local a print(os.clock()) for i = 1,loopTimes do     a = _M[1].id end print(os.clock()) for i = 1,loopTimes do     a = _M[1].id end print(os.clock()) for i = 1,loopTimes do     a = _X[1].id end print(os.clock())
点赞 回复
分享
发布于 2021-06-17 11:28
  请问楼主第一份工作是什么岗位呀,是游戏客户端开发吗?工作中有这么多机会接触渲染知识吗?   本届校招生对渲染/引擎方向热情比较高,但是因为目前知识储备问题还是打算以客户端为主,想请教一下楼主游戏客户端岗位有机会向渲染方向深入吗?   感谢解惑!
点赞 回复
分享
发布于 2021-06-26 11:25
博乐游戏
校招火热招聘中
官网直投
只有一面技术面嘛?
点赞 回复
分享
发布于 2023-04-19 15:42 浙江
21年啊。。今年简直地狱难度了
点赞 回复
分享
发布于 2023-09-21 23:39 安徽

相关推荐

10 49 评论
分享
牛客网
牛客企业服务