它们之间是否存在明显的差异,它们在某些情况下会使一个或另一个变得更好?知道这两者或满足大多数需求是否有用?
我不想模糊的答案表明个人喜好。我正在寻找可测量的特定差异,以便自己决定最适合自己的差异。我没有特定的任务在想-我希望发现是否有一个我可以学习的东西,然后再应用于将来的任何任务,而不必为每个新任务学习一种新的语言。
如果还有其他我没有提到的着色器语言,我也很想听听它们之间的比较,只要它们不依赖于任何特定的GPU制造商即可。我希望我的代码可以在不同的图形卡之间移植。
#1 楼
着色器语言绑定到支持它的API /引擎(glsl到openGL和WebGL,hlsl到D3D)。有一些工具可以相互转换,但并不完美。这意味着选择一个工具的主要原因是要使用哪个平台。
但是,到今年年底,将会出现一种新的二进制着色器表示形式,称为Spir-V,它是为Vulkan设计的,并且有望很快推出OpenGL扩展。只要存在Spir-V的翻译工具(包括Python和Haskell工具在内的几种工具),这将允许您用多种语言编写着色器。
#2 楼
HLSL着色器语言用于DirectX系列API,而GLSL用于OpenGL系列API。这意味着图形API的选择也将限制着色器语言,因此,如果考虑跨平台,则选择GLSL。但是,这也会带来一些警告。一个区别是,在OpenGL中,着色语言是在驱动程序级别上编译的,这意味着二进制表示形式不稳定,并且可以随驱动程序更新而改变。在HLSL中,它被编译为独立于硬件的表示形式,可以在多个GPU上使用。这确实是编写着色器的问题,但有时它意味着某些操作与其他驱动程序(尤其是操作系统)不同。
要注意的另一件事是OpenGL功能扩展,可以启用这些功能GLSL内部以利用额外的功能。对于较新的OpenGL版本,其中某些扩展名可能会添加到核心配置文件中。然后,供应商必须实施这些扩展以使其合规,这有时会导致工作方式有所不同。 HLSL着色语言语法仅随着DirectX API的新引入而发生变化。
语法上的一些差异是HLSL可以使用#include,在GLSL中这不是默认设置。在搜索GLSL教程时,您可能会发现不同的语法,因为与OpenGL 3和4相比,它已经发生了很大变化。GLSL着色器具有一个无效的main()作为着色器入口点。在HLSL中,可以命名此入口点,并具有输入(顶点数据)和输出(像素着色器输入)。
学习这两种方法中的任何一种都会使您了解一些共同点,这将使学习变得容易另外一个。 HLSL更加标准化,但也只能在单个操作系统上运行。还有其他尝试将着色器语言编译为OpenGL和DirectX的尝试,例如Cg,现在已弃用。许多游戏引擎(Unity,虚幻引擎)也有自己的风格,但其语法类似于HLSL或GLSL。
如前所述,Vulkan将引入一种称为Spir-V的开放式中间语言表示形式。这意味着,如果可以将一种语言编译成这种表示形式,则可以用来编写着色器。
评论
$ \ begingroup $
GLSL函数不能返回值吗?哼?您是从哪里得到这个想法的?
$ \ endgroup $
–glampert
15年8月20日在17:41
$ \ begingroup $
我一直习惯于opengl.org/wiki/Core_Language_%28GLSL%29#Functions中所述的值返回调用约定。如果可以定义返回类型并使用“返回变量”;语法,我将对其进行更改。编辑:nvm,你是对的。 OpenGL 4.5规范说应该有可能(但是我不知道什么时候引入的)
$ \ endgroup $
–莫里斯·拉沃(Maurice Laveaux)
15年8月20日在18:14
$ \ begingroup $
始终支持返回值,即AFAIK。如果查看1.2规范的6.1节,则可以看到函数声明语法:returnType functionName(type0 arg0,type1 arg1,...,typen argn);。另外,许多内置函数都返回一个值...也许in / out参数的存在使您误以为它不支持返回值,但是两者都是正交的概念。除此之外,您的答案还不错,顺便说一句;)
$ \ endgroup $
–glampert
15年8月20日在18:26
$ \ begingroup $
是的,我可能只是看了Wiki而不是规范本身。尽管确实内置函数确实使用了这两种方法,但我从未想到这两种方法都是可行的。
$ \ endgroup $
–莫里斯·拉沃(Maurice Laveaux)
15年8月20日在18:42
评论
$ \ begingroup $
您的速度比我快了几秒钟,甚至有关于Spir-V的信息,我什至不知道。
$ \ endgroup $
– Nero
15年8月20日在11:07