HLSL vs GLSL vs cg的优缺点是什么?[关闭]


61

这三个的优点/缺点是什么?


2
在您决定使用哪种着色器语言之前,您似乎首先需要确定要使用的API(OGL或DX)和平台。
Tetrad

1
我认为这个问题很棒。社区维基怎么样?我不熟悉所有这些,关于着色器的区别的问题正是我需要知道的。
Mladen Mihajlovic

3
更正:“关闭不具有建设性”应该说“关闭是违反了机智的政策”,因为这是建设性的。
Lennart Rolland

Answers:


42

coderanger对针对DirectX的HLSL,针对OpenGL和CG的GLSL适用于两个接口都是正确的。

但是,还需要考虑其他事项(在OGRE论坛上了解):

  • CG不允许您使用GLSL的最新功能(我不确定HLSL)。这是中间立场,因此您将无法充分利用GLSL功能,只有Shader Model 3.0(AFAI可以理解)才能充分利用GLSL功能。
  • CG由NVidia制造,可以对其卡进行优化,但是似乎对ATI卡并没有做很多工作……有人报告说使用CG的ATI卡可能存在问题。
  • 在Windows平台上,OpenGL似乎比DirectX慢一些。这确实与您正在做的事情有关,并且这样做的原因是在驱动程序实现中找到它的来源,但是在选择API和关联的着色器语言之前先了解一下是很好的。但是,OpenGL是所有(win / mac / unix /某些控制台)平台上唯一可用的接口。因此知道,对于非以Microsft为中心的跨平台游戏,仅使用GLSL可能是更好的选择。
  • Linux上的NVidia驱动程序似乎比ATI驱动程序更稳定,如果您需要确保CG在Linux上能很好地工作,这会使CG更加有趣(这是所有报告的信息,您必须检查详细信息)

因此,如果您不使用最新的着色器功能,CG似乎是一个不错的选择。如果要使用完整的OpenGL,GLSL似乎是一个不错的选择。HLSL(如果您仅在Microsoft平台上使用)。

现在,首先在HLSL中为Windows开发以使用DirectX,然后再转换为GLSL以在Linux和Mac中使用,这可能是更好的解决方案,以确保性能并具有更多可用的着色器功能集。但是,这可能需要做很多工作(我自己没有做,所以我无法分辨)。OGRE图形引擎(和其他引擎)允许使用任何API(DirectX或OpenGL或其他),因此可以提供帮助,但是如果您采用这种方式,则仍存在要转换的着色器代码。

这就是我在选择着色器语言时收集的所有信息(我尚未做出决定)。


更新:Valve将他们的一种游戏转换为OpenGL,没有找到比OGL更快的DirectX版本的方法。因此请记住,驱动程序实现的状态,API质量等每年都会发生太多变化,以至于您完全依赖原始性能作为选择一个或另一个的参数。考虑到这一点,选择OpenGL / GLSL可以简化与Windows以外的其他平台一起工作(或有计划或希望进行工作)时的生活,如果您真的只想使用Microsoft平台并集中精力并且也许有一些好的经验,请使用DirectX / HLSL API比OpenGL更快(现在正在逆转,所以不要指望它);如果您想为用户提供两种可能性,请使用CG,但是如果您有劳动力(和工具)来做到这一点,则同时使用GLSL和HLSL也是可行的解决方案。


更新(2012):值得注意的是CG已停产,Nvidia不再对其提供支持或积极开展工作。Nvidia建议所有用户切换到GLSL和HLSL的组合,或更新的库,例如nvFX(在github上)。这是因为很难维护GLSL和HLSL之间的功能兼容性。


2
是的。NVIDIA似乎并不关心ATI卡的问题。
bobobobo

4
“ OpenGL在Windows平台上似乎比DirectX慢一些。” 在大多数情况下,这通常是由于供应商对OpenGL驱动程序的支持在Windows上不如DirectX上更好。
ChrisC 2011年

1
注意:由于最近的改进以及需要确保我的游戏可以在某些非MS平板电脑上运行,因此我最终选择了OpenGL / GLSL。
克莱姆

2
@社区:您是否有任何链接停止对Cg的支持?
Nicol Bolas


15

我只能谈论CG vs HLSL,因为这是我到目前为止使用的2。

CG是一样的HLSL。

在Cg中,NVIDIA在创建非常干净的着色器语法方面做得非常出色。它与HLSL非常相似。

但是,在HLSL上将D3D9 / D3D11(初始化代码,着色器编译代码)与Cg结合起来要干净得多。-1克 Cg有一些讨厌的启动代码,您甚至不需要D3D上的HLSL。

在Cg中,您必须为每个 uniform要设置/修改的着色器变量“ cgGetNamedParameter” 。而且您必须CGparameter在代码中维护该变量的引用

// C++ code to interact with Cg shader variable (shader language independent)
CGparameter mvp = cgGetNamedParameter( vs, "modelViewProj" ); 
CG::getLastError("Getting modelViewProj parameter");  // check for errors
cgSetMatrixParameterdr( mvp, &modelViewProj._11 ) ;   // setting the matrix values

在HLSL中,这最终变得更加简洁-只需一行,而您不必维护该CGparameter变量。

// D3D9 C++ code to interact with HLSL shader variable
DX_CHECK( id3dxEffect->SetMatrix("modelViewProj", &mvp._11 ), "Set matrix" ) ;

在上面,DX_CHECK只是一个简单的函数,用于检查从SetMatrix调用返回的HRESULT 。 上面的代码是d3d9。D3D10和11当然要痛苦得多(因为没有ID3DX11Effect对象)。

在开始使用HLSL之前,我曾经看过这段代码,但实际上很嫉妒

虽然NVIDIA尽最大努力,确保为/ D3D OpenGL的CG之间的通用接口,实际而言它不是这样,你有cgGL*cgD3D9cgD3D10cgD3D11功能组与之抗衡。这样就可以在OpenGL D3D上使用!!声称只走了这么远。您仍然必须将所有内容包装到OpenGL / D3D #ifdef类型组中,以使其在不同平台上工作。-2 Cg。

此外,我最近在使用Cg / ATI卡方面经历了一段糟糕的经历,我敢肯定这还不错。(其他人可以尝试一下吗?)。我认为NVIDIA不会像Klaim所说的那样完全测试ATI卡是真的。或者说ATI不对Cg进行测试。一种或另一种方式是存在不匹配和某种利益冲突。-3 Cg。

总之,我更喜欢Cg。它的着色器代码语法和命名干净,整洁。太糟糕了,还遇到了其他问题。


10

我的基本理解是HLSL仅用于DirectX,而GLSL仅用于OpenGL。Cg与HLSL基本是同一语言,但是可以与DirectX或OpenGL一起使用(尽管通过不同的运行时代码)。


+1这也是我的理解,就我个人而言,我尽可能地使用cg,但是它确实在渲染系统本身之外增加了额外的依赖性;我似乎还记得OpenGL,cg和ATI驱动程序存在一些奇怪的问题,它们的效果更加复杂...
Riley Adams 2010年

我正在使用Ogre,因此可以同时使用这三个组件,但是如果我想同时拥有DirectX和OpenGL,则必须在HLSL和GLSL中都编写着色器,或者只使用cg?那正确吗?
Z_guy 2010年

14
-1。这是一个非常基本的答案,希望能在此站点上找到更多的信息。
bobobobo

2
-1:我同意bobobobo。
Nicol Bolas

1
不幸的是,出于与bobobobo相同的原因,我必须设为-1。
乔纳森·迪金森

8

HLSL和GLSL之间的另一个关键区别(我不知道CG,所以我不能说它)是,Microsoft使用HLSL将着色器编译器作为D3D运行时的一部分提供,而使用GLSL,您的硬件供应商将其作为其一部分提供司机。

这在双方都有优点和缺点。

使用GLSL方法,供应商可以将编译器调整到其硬件功能。他们最了解自己的硬件,知道该做什么和不该做什么。另一方面,缺点是-在存在多个硬件供应商的世界中,您会遇到着色器编译器之间可能存在不一致的情况,并且供应商也有完全的统治权。

Microsoft使用HLSL方法控制编译器。每个人都具有一致的技术基础,如果着色器可以在一个地方成功编译,则可以合理地认为它可以在任何地方进行编译。相同的着色器将产生相同的编译输出,而与供应商无关(当然所有其他条件都相同)。另一方面,HLSL编译器必须是“始终如一地工作”的东西,因此它无法提取任何特定于供应商的特殊技巧来从罐中取出最后几滴果汁。

如果遇到这种情况,好像我更喜欢HLSL的世界观,那是因为我愿意。之前,我在不同平台上的行为异常不一致,这使我很受痛苦,在一种情况下,甚至不得不将GLSL的负载回滚到ARB ASM只是为了获得有效的基准。NVIDIA的GLSL编译器在这里可以被认为是特别臭名昭著的-它甚至可以接受HLSL语法和关键字,这意味着如果您不小心,最终可能会产生仅在NVIDIA上可以使用的着色器。那是一个丛林。


1
公平地讲,自那时以来,NVIDIA的GLSL编译器对其功能和不可接受的功能已变得更加严格。但是即使到了今天,我仍然称之为“ NVIDIA陷阱”,可以轻松地执行您认为应该起作用的操作,但是却不符合实际的规格和AMD驱动程序。
Nicol Bolas

我什至可以说,绝对需要在ATI / AMD上进行开发,或者至少定期与ATI / AMD进行交叉核对。您将以其中一个的价格杀死两个,因为您也将在其OpenGL驱动程序中捕获错误。
Maximus Minimus

当针对支持SPIR-V的Vulkan或OpenGL实现时,可以将GLSL着色器预编译为SPIR-V。
安德里亚(Andrea)

@Andrea-是的,没错;显然,在提出问题时(写了答案),Vulkan和SPIR-V都不存在。
Maximus Minimus

1

我一直在使用这两种方法,我从glsl开始,然后才转到hlsl,只是因为项目需要它。有了选择,它就一路走来。glsl感觉非常光滑,hlsl感觉像是从工程师的爱好长凳上出来的。


1

您可能还想研究Ogre随附的RTSS(运行时着色器系统)。它是相当新的东西,但是您基本上是在代码中而不是外部文件中编写着色器。我还没有实现它,但是绝对打算在时机成熟时使用它。

这是Ogre Wiki上的大量教程,以及编写着色器的教程。 http://www.ogre3d.org/tikiwiki/JaJDoo+Shader+Guide

至于您最初提出的问题,就像Praetor所说的,这实际上不是利弊问题,而是要使用哪种渲染系统的问题。由于将DX / OpenGL与Ogre一起使用仅是加载插件的问题,因此您很可能希望使用.cg格式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.