【省流总结】为什么游戏总要编译着色器?
原视频:为什么游戏总要编译着色器?BV1zi421h7tJ
省流:从图形接口讲起
我记得红警2要想调用D3D需要打ddraw补丁的,而且也不一定要调用direct3D也可能是GDI或者OGL
这个市场结构导致了GPU赛道上存在比较复杂的壁垒,手机平板的移动端GPU不借助VULKAN的情况下很难兼容Windows生态下的DitectX,但是反过来却可以,因为OpenGL是容易兼容的。所以NVIDIA也好ATI(后期的高通Adreno)也好甚至包括S3 IMG想要从桌面端进入移动端都是相对简单的,反过来却很难。
比如之前咱说的国潮显卡摩尔线程它的GPU就基于IMG的BXT架构,这种架构是IMG在退出桌面端之后出的GPU架构,主要还是提供给移动设备的。所以摩尔线程的显卡再堆GPU规模它由于原生不支持DX11只能靠驱动转译所以不仅对CPU的要求较高而且实际3D性能永远达不到理论性能,甚至目前来看支持不到DX12后面也会讲原因。
但是对于Linux下的OGL相对支持就会好一些毕竟这是个和POWERVR一样原定用于手机平板的架构,所以如果配合ARM主机跑Linux+APS[甚至直接运行Android的话那么理论上摩尔线程的卡就和POWERVR的GPU一样用起来基本没啥问题。
这个标准我想想不会是基于ARM的苹果自研GPU吧,IOS限定?难怪MAC OS X的游戏少甚至很多人到手就做Windows,毕竟当时的Mac都是基于X86,GPU也都是支持DX的通用型号,所以像XBOX或者PS4一样刷个Windows也不是不能用。
最后就算支持事先编译好着色器很多时候游戏厂家为了省钱也会选择让用户编译
下期估计会讲DXVK或者DXCPL之类的技术了。 AI字幕提取:不知道大家有没有注意到 近些年出品的游戏 在第一次载入游戏的时候 常常会出现一个正在编译着色器 这个过程通常要等很久 那么这个着色器到底是啥 为啥要编译呢 今天我就带你来了解一下GPU接口的发展史 为您解释一下这个问题 也顺带给你解释一下open gl d direct 3d mental vocal 这些东西是什么 有什么用 它们之间有什么关系 话不多说 我们开始 假如你是一个游戏开发者 你开发的游戏要运行在显卡上面 现在市面上有五款显卡 那么你的游戏就必须兼容这五款显卡 你就要写五份兼容代码 太愚蠢了 那应该怎么办呢 我们可以制定一个标准 制定一套接口 让所有的显卡生产厂商都实现这套接口 让所有的软件开发者都调用这套接口 这样软件开发者不必一款显卡 一款显卡的去兼容 只需要调用这套接口 那么实现这套接口的显卡就都能运行 显卡生产厂商也不用担心 有软件无法运行在自家的显卡上 只需要实现这套接口 这些软件就都能运行 而第一个受到行业广泛认可的标准就是open gl 上世纪90年代早期有一家名叫SGI的公司 这家公司在3D图形领域堪称number one 不过SGI面临的竞争同样激烈 Ibm sun 惠普等巨头都对3D图形领域垂涎三尺 面对激烈的竞争 SGI最终做出了一个违背祖宗的决定 他们把自家公司的3D技术标准 IRISJL给开放了出来 做成了开放标准 这就是open gl 1992年 open gl1.0发布计算机 3D图形领域进入open gl时代 GPU的结构和CPU有很大的区别 CPU拥有数量较少 但是每个都很强大的运算核心 相反在GPU里边 每个核心都相对弱小 但其数量却有很多 这就意味着GPU天生具有强大的并行运算能力 那么什么是并行运算呢 举个例子 我这里有一张图片 图片太暗了 我想给这张图片提亮 用CPU应该怎么做呢 其实就是写个循环 把图像里面所有的像素循环一遍 一个一个的处理 那么用GPU呢 因为GPU有数量众多的运算核心 我可以给每一个核心都分配一个像素 然后让他们一起运算 这样这幅图像一下子就处理好了 在最初的GPU里边 每个核心上面要运行的程序 你是不能够进行干预的 GPU会给你提供一些预设 你可以选择这些预设来达到你想要的效果 这种设计被称之为固定管线 open gl1.0标准就是固定管线 那么大家也一定能看出来 固定管线的灵活度是很差的 于是在不久之后就出现了可编程管线 所谓可编程管线就是你可以写一小段程序 然后把这段程序拿到GPU的核心上面去跑 从而实现对GPU的可编程 这段小程序被称之为SHADER 中文里边我们管它叫做着色器 所以编译着色器就是把人写的着色器程序 编译成GPU可以执行的机器码 这么一说 好像这个正在编译着色器就能说得通了 不过好像也说不太通 还是有一些问题的 例如第一为什么只在第一次进入的时候 需要编译之后再进入就不需要了呢 第二为什么游戏开发者不能把SHADER预先编译好 然后放到游戏包里边 这不比我们开游戏的时候再编也会更好吗 别急 我们来慢慢讲 open gl出现之后 很快就成为了业界唯一的3D接口标准 大家都很快乐 除了一个人 微软 好微软对open gl不满意的原因有很多 有的人说open gl是为了那种超贵的图形工作站 所涉及到并不适合微软所在意的游戏场景 所以微软不满意 但是我觉得另外一种说法可能更有说服力 虽然当时open gl1统江湖 但是有一些硬件厂商 为了让自己的产品更有优势 他们会利用open gl的扩展功能 来设计一些别人没有的非标准的硬件特性 然后他们会找到游戏厂商 对游戏厂商说 我这儿有块新显卡 里边有一个很特别的功能 能让你游戏中的水面看起来更加真实 别的显卡都没有 你要是在你们的游戏里面接入的话 我就给你一笔赞助费 这样当消费者为自己喜欢的游戏 采购硬件的时候 就会优先考虑购买这块显卡 因为open gl是开放标准 为open gl添加扩展 不需要任何人审查批准 微软只能在一边干 看着插不进去手 终于忍无可忍的 微软 在1996年 推出了自家不支持扩展的3D接口标准 Direct3 d 并且顶着行业的压力 靠着在操作系统领域绝对的话语权 强行推广以后 你们俩人做生意必须带上我 从此江湖上出现了open gl direct3D两大3D接口标准 DIEX3D靠着微软的强力支持 很快在游戏领域成为了唯一的选择 我们小时候玩的红色警戒 就是首批使用迪direct3D开发的游戏 赶快投降 当然这里的红警其实是红警一 不是零八玩的红警二 而open gl因为早年的积累和开放的特点 在专业图形工作站领域则更加受欢迎 其实我觉得是因为史山代码太多 实在不太可能迁移到d direct3D上面 这种布局持续了一些年 在这期间微软是越来越强势 而open gl的母公司SGI则是老太太 过年一年不如一年 终于SGI连open gl标准委员会都供不起了 在2006年 SGI把open g奥托付给了非营利组织CORNGROUP 而自己则走向破产 退出了历史舞台 SGI最终走向了失败 但是这家公司对整个行业 乃至整个世界都产生了很大的影响 我们今天看到的很多八九十年代的电影 都是SGI工作站所渲染出来的 3D软件 MAYA也是由SGI开发的 后来SGI死掉之后才辗转卖给了AUTODESK 更别说open gl 这个影响了几乎所有人30年之久的标准 所以请允许我在这里对SGI表示最真诚的称赞 S gi 美国硅土公司牛逼SGI倒下了 open gl的日子也并不好过 在2000年左右 随着PC个人电脑的崛起 一座小型机工作站为代表的第一代电脑巨头 纷纷歇菜 比如SGI 比如sun 就是发明了java的那个公司 还有什么IBM 惠普都歇菜了 人们发现以前巨贵的图形工作站能做的事情 现在一台廉价的PC也能做 运行open gl的那些专业图形工作站都已经入土了 大家都在使用着运行着direct3D的PC机 还在使用open gl的 也只有尚未成气候的开源LINUX系统 不过当时的显卡生产厂商 对LINUX的驱动支持一直不怎么好 我说的对吧 Nvidia so nvidia Fuck you 至于同样在使用open gl的苹果公司 当时的状况也不太好 And i haven't have a special guest with me today Uh via satellite down link And if we could get him up on the stage Right now 照着这个趋势发展下去 open gl完蛋也只是时间问题了 不过岂能事事都随了微软的愿 2007年 苹果发布了IPHONE 世界很快就进入了移动互联网时代 大量手机上的游戏影音需求被挖掘了出来 大家发现 原来移动设备上的图形 渲染能力也是至关重要的 对于当时的IOS和安卓来说 搭载open gl是唯一的选择 于是在大约2010年前后 IOS和安卓都搭载了经过精简的open gl es s标准 同时期的windows phone则是搭载了自家的DERRX3D 不过很快就暴毙了 于是open gl es开始在移动设备上大放异彩 Make open gl great game 于是图形接口标准的布局又发生了新的变化 direct3D统治桌面PC open gl统治移动设备 外带Mac linux等一些小众市场 康纳group也十分给力 在2012年推出了open gl es3.0标准 而在open gl es3.0中出现了一个新的特性 SHADER缓存机制 在open gl较早的版本中 SHADER是以源代码的形式存放在程序里面的 在程序运行的时候就需要拿出来进行编译 但是早期的open gl在SHADER编译之后 会直接扔给显卡去进行执行 并不允许将编译后的产物给缓存起来 这就导致程序每次运行的时候 都要对SHADER进行重新编译 这也就是为什么大部分老游戏不会专门显示 正在编译着色器的进度条 笑死每次进来都得编译 当然由于老游戏的SHADER都较为简单 所以在最初的时候每次都编译一下 也并没有造成什么太大的问题 世界是个草台班子对吧 但是随的SHADER越来越复杂 SHADER的数量也越来越多 这种用到的时候才进行编译的策略就不够用了 于是open gl es3.0里边加入了SHADER的缓存机制 你可以在编译SHADER之后 把编译得到的产物直接获取到 然后存到磁盘里面去 下次再进来的时候 直接从磁盘里边读取编译产物 直接扔给GPU去执行 前面的这部分就不需要跑了 这也就是很多近几年出的游戏 会在第一次载入游戏的时候 把所有的SHADER都编译一遍 因为第一次编译了 后面每次进入游戏加载速度就会大大加快 那有的同学就要问了 既然在open gl es3.0里边 SHADER只需要编译一次就可以了 那么游戏开发者为什么不直接在游戏开发阶段 就把SHADER编译好 直接把编译好的SHADER放到游戏安装包里边 这样即使是第一次进入游戏的时候 也可以直接进行加载 就不需要经历这个漫长的着色器编译阶段了 这其实是一个很好的问题 非常有深度回答 这个问题需要从多个方面来说 先说结论 在open jor里边这样做是不可以的 SHADER源代码经过编译会变成GPU 可以直接运行的机器指令 open gl的标准里边只规定了SHADER源代码的格式 但是并没有规定编译之后的机器指令的格式 所以这些机器指令的格式 在不同品牌的GPU上面运行的时候 其格式也是不同的 这就意味着你用A机器编译出来的指令 放到B机器上面是跑不起来的 随意使用open gl的游戏里边 只能包含SHADDER的源代码 在第一次运行的时候 编译 编译出来的产物也只能在同一台机器上面使用 但是大家发现了没有 如果可以统一所有GPU的机器码格式 这将会是一个非常好的特性 不过说实话有点难 让所有的硬件厂商 按照统一的机器码指令去制造硬件 实在是有点强人所难 但是我们可以退一步 我们可以在SHADER源代码到机器码之间 增加一种新的中间格式 人类写好的SHADER源代码 可以先编译成这种中间格式 这种中间格式有点像是汇编代码 它不能直接送给硬件去执行 但是这是一种机器友好型的格式 GPU只要一行一行的将指令进行翻译 就可以快速得到机器码 这比编译人写的SHADER要快得多得多 而且这种中间格式仍然具备跨机器运行的能力 编译一份你就可以拿到所有的机器上面去运行 这很美好 但是open gl es3.0里边不支持不支持怎么办 open gl需要革新 其实也不只是open gl 还包括迪direct3D这两个老家伙 从上世纪90年代一直坚挺到2010年代 虽然他们自己也做过很多革新 但是技术变了 市场变了 连消费者都有可能变了 open gl和direct3D 这两个老家伙逐渐开始力不从心 2014年 微软提出了新一代的direct3D标准 Derdirect3 d 12 虽然这仍然是DRX3D 但是DRX3D12已经相较之前的版本 有了翻天覆地的变化 说是一个新的标准也不为过 同年苹果也发布了自家的标准 闷头你微软做的的事情 我苹果也做的 扣壳网5亿可网 2015年维护open gl的康纳group van这个单词你要是不会念 你就记住福尔康vocal 富尔康VOC 一时间整个3D图形领域乱成了一锅粥 那种勃勃生机 万物竞发的境界犹在眼前 Direct3 d 12 Vocal mental 在设计的时候都考虑到了 我们刚才说的SHADER的中间格式 direct3D12提出了DXL格式 vocal提出了spire5中间格式 这种格式是一种开放的标准 在此后的发展中 这种格式将大放异彩 mental则提出了mental i r的中间格式 所以如果你的游戏是使用新的direct3D12 vocal或者mental来开发的 那么你就可以把你的SHADER 预先编译成这种中间格式 放到安装包里边 这样用户就不需要经过漫长等待 直接进入游戏了 不过可以这样做 并不代表一定要这样做 这是一个SHADDER的源代码 大小是110一个字节 将这份源代码编译成vocal的中间格式 大小是368个字节 体积大了将近三倍 所以当你的SHADER特别多的时候 选择在用户的机器上面进行编译 可以减小安装包的体积 可以节省流量 很多的开发者仍然会选择这样做 2022年 V社发布了自家的掌机steam deck steam deck运行的是一个LINUX系统 但是它却能高性能的运行为windows开发的游戏 他是怎么做到的呢 和我们今天介绍的这些东西有关系吗 我们下期再继续介绍好了 这就是本期视频的全部内容了 我是肖红 我们下期再见
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~