[ZT]GLSL/HLSL易犯错误和注意点

GLSL/HLSL易犯错误和注意点

我的blog里有许多此类笔记,主要是记录写程序时犯下的错误.有相当多的错误,我都是一犯再犯,而且每次都因这种小错耽误时间而骂自己是猪,所以很有必要记录下来,以备查找.作程序的要懂得积累经验,并书面化,抽象化.
渲染API容易出错,根源于其本质是个状态机,作一个渲染时,几十上百个状态都必须设置正确,才能得到正确的图像,这就很容易出点小差错.
1.GLSL的vec4有3种分量形式xyzw/rgba/stpq, 注意到的r分量是指颜色r分量, 习惯上的纹理坐标分量strq的r由于和颜色r冲突,改作p.
2.Global Amibient也要乘以材质Material.
3.HLSL没有shadow2DProj函数, GLSL的shadow2DProj返回的是深度比较的结果1.0或0.0的4元组,不是深度值!且要记住,shadow2DProj受到固定流水中纹理GL_TEXTURE_COMPARE_MODE/GL_TEXTURE_COMPARE_FUNC的影响,要使用shadow2DProj必须打开深度纹理比较模式.
4.HLSL允许如vec4向下强转为vec3这种隐式转换. GLSL语法上不允许,但实践上N卡出warning仍可以编译运行,A卡直接报错无法运行.
5.DirectX的shader调试状态和硬件实际运行状态的结果有很大区别,不能全信.
6.设置   glEnable(GL_COLOR_MATERIAL);
              glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
在shader中, A卡的glFrontMaterial.diffuse不会跟踪设置为当前顶点色,而N卡正确.
7.GLSL: N卡可以使用vec3 temp = { 1.0, 0.0, 1.0}; 这种形式的构造, A卡报错. 
   HLSL: 都可以使用float3 temp = { 1.0, 0.0, 1.0};形式.
8.HLSL的mul接受mul(vec, matrix)或mul(matrix, vec),要注意通常HLSL要依DirectX计算(V * M)使用mul(vec, matrix)的形式.
特别需要小心的是,vec如果是float3,前后行列不等,违反HLSL规范,但shader编译也不报错,直接当成float4(vec, 0)处理,而不是当成float4(vec, 1).即mul(float3, matrix)中的float3被当成向量,而不是顶点.
9.不要在一行中写过于复杂的表达式, N卡没问题, A卡很烂,通常都编译不过.例如:
http://www.ozone3d.net/blogs/lab/?p=38

10.GLSL可以只有PixelShader, 没有Vertex Shader, HLSL不支持.
vs_3_0 shader executed in hardware vertex processing mode can only be paired with at least a ps_3_0 shader.
11.GLSL的1.2版本开始支持mat4x3这种non-square矩阵,要注意4x3是4列3行,而不是4行3列.

HLSL小技巧

研究HLSL也有些日子了,其中犯了很多错误,现将沿途所遇略作纪录,以次时刻提醒自己不要重蹈覆辙。

1. Effect文件(.fx)是标准格式,要妥善利用其接口与应用程序通讯,理解语意(Semantic)和注释(Annoation)是关键。
clip_image001

2. HLSL指令集要倒背如流,切不可做出重写标准库的蠢事,当初我就写了一个distance函数来求距离,熟不知标准库里早有这个函数,仔细一研究,标准库里不仅支持三维向量,其它的诸如二维也以考虑在内,汗^_^,完整的指令集可以参见DX帮助文件,路径为DirectX Graphics->HLSL->Reference->Intrinsic Functions。

3. 不仅指令既要倒背如流,还要注意指令的限制,尤其是Shader Model(SM),像ddx,ddy这样的指令是不能用在Shader Model 1 中的,这个我感觉是比较令人沮丧的事情,程序员的代码和逻辑都正确,却限制于硬件配置的问题,还好现在硬件发展迅速,SM3.0甚至SM4.0的显卡都已经进入主流市场,这些限制会逐渐消失的。具体的限制可以查看DirectX Graphics->HLSL->Reference-> Shader Models。

4. 编译Effect的时候能用低配置的Profile就用低的,举例来说能用vs_1_1的就不要用vs_2_0,ps也是一样的道理,Profile选的越低,你的Effect兼容性就越好,如果不分清楚直接就用最高Profile,到了客户那因为显卡配置不够报错的概率就大了,至少我现在还没听说某款PC游戏只能在SM4.0下才能用,游戏机,测试程序自然不算了,以后没准等SM5.0都普及的时候,我这话也自然过时了^_^。

5. 在VS中计算屏幕坐标时要把坐标先转换成齐次坐标

a) 这样写是有问题的,mul(input.Position, WorldViewTransform);

b) 要改成mul(float4(input.Position,1), WorldViewTransform);

6. 文件最后一行要在最后加一个空格或一个空行,要不有时会有error X3000: syntax error: unexpected end of file,这样的错误信息,这种错误信息有时莫明其妙发生,例如在加了一条注释后,总之是在编写Effect的时候要格外小心谨慎。

7. 前几天还遇到了这样的错误,在ps中写了个if语句返回某种颜色,不料产生错误,错误信息如下error X3500: asymetric returns from if statements not yet implemented。现在把Effect文件内容张帖出来,为了搞清楚问题本质,我把不相关代码全部删除了,只留下必要地解释性代码。一开始没注意看错误信息,以为是那里写错了,就几十行代码折腾半天不见好转,后来仔细看错误信息后才恍然大悟,原来是Effect编译器不支持这种if用法,虽然HLSL支持以c的语法来写shader,但毕竟和c还是有区别的,编译下面的代码就会得到上述错误信息,只要在第二个return前加else,使其成为一个if-else结构,编译自然通过。由此可见,写shader时c的观念在某些情况下要转变过来,如果一味以c的直观印象去评测,极有可能出现问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和用性,特别注意了以下几:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值