理智的人没有品位?

我小时候想成为任何人,除了我自己。现在我爱上了你,然而你心里却只有上帝。-《兰陵王的骑士》


不可否认,OpenGL是一个只有成绩好的学生才学的明白的课程。这也就注定了这是个小众知识的原因。但我们程序员本身这个职业又何尝不是呢。其实仔细思考一下,确实如此,比如我们经常讨论的问题如下:


多目标渲染

老丝~~,为什么我运行同一个程序,在Win10上和Win7上的显示结果不一样啊,是不是有什么BUG呀?

实际上Win10上出问题,多半是因为集成显卡的缘故,特别是笔记本,为了省电,在有双显卡的情况下,默认会用集成显卡。集成显卡我们知道是会出各种问题的,但是我们依旧可以通过一些手段去规避这些问题。比如当我们无法使用多目标渲染的时候,可以按照我们的课程中多通道渲染的方式解决,也就是渲染多次。

实际上你可以通过一些查询API去获取当前你运行的显卡可以渲染到多少个ColorBuffer。查询办法请参考我们给大家准备的QuickReferenceCard,你不妨把那个卡片通读一遍,自然会发现很多有用的东西,我们给大家准备的课后资料不是随便乱准备的。没有权威性的资料肯定不会给。


主题

理智的人没有品位?

实际上这是个错误的命题,艺术界不存在高低贵贱,谁能说什么样的品位算是高的,什么样的品位算是低的?实际上没几个人真正能说得清楚。智力水平和见识不一样,自然品位不一样,又何必去在乎大部分臭味相投的人的眼光。


程序员的品位

世界上最强大的语言是PHP,其他的都是垃圾。Python都是些外行学的,他们不懂什么是真正的爱情。


OpenGL程序员的品位

写程序根本不在于你用什么语言,真正的乐趣在于你可以把你学到的数学、物理甚至是柏拉图式的爱情都用在程序中。你没学懂OpenGL程序的时候觉得他巨繁琐,当你学懂了它的时候,你甚至连思考普通程序的架构都变得不一样的,你总会让所有可并行的东西并行。

实际上,学懂一门手艺,才能真正体会设计者的思想,这样会反过来强化你本身的所有编程技能。实际上这些图形API的设计者的编程思想是学完OpenGL后最大的收获,而不仅仅是那几行C++代码。


Compute Shader

一切都是可并行的!!!!!

与其他的Shader有明显的不一样,Compute Shader是个疯子,其他种类的Shader都是为了完成渲染管线中特定的部分而存在。而Compute Shader完全没有什么特定的任务,所以比较符合我们中国人不按规矩办事的风格。

Compute Shader中既没有什么标准的输入,也没有必须规定的输出。它的输入可以是一对顶点,也可以是来自一张图片。所以完全可以按照设计师的想法来。

如果你是学过Cuda程序设计的,那么你会明白,Compute Shader中,你设置的那些执行用的参数并不一定可以让你的算法更快更高效,你必须设计一个合适的值,这个值取决于你的程序在什么样的GPU上运行。

那么刚才设置的这些值是指什么呢?是下面这些参数

  1. 总数据块的大小

  2. 每个Group的大小

  3. 每次运行的数据块的大小

总数据块的大小,这个也有讲究的吗?答案是肯定的。做过Cuda程序设计的人肯定知道,并不是说你调用的时候说请每次处理5亿的数据,那么Cuda程序就真的每次处理5亿个的。你需要让你的GPU满负荷运转,这才能让你的程序最快运行。

那么为什么参数的设置可以让GPU变得不是满负荷运转呢?这就要考虑我们的GPU中的浮点数运算单元了。学完进阶课的学员肯定是知道,我们的GPU是一个并行运算的芯片。我们假设,我现在有一个GPU,总共有256x256个核心,我假设每个核心每个GPU时钟周期只能做一次浮点运算。那么我们为了使得我们GPU满负荷运转,我们需要让我们的GPU的执行的数据块大小为256x256的,这样才能保证GPU的核心不会发生空转。

如果你设置的数据块大小太大,那么会被分批次执行,那么总会有那么几次,部分GPU核心是空转的。

如果设置的数据块太小,那么肯定是有GPU在空转的。

但是总体来说,使用GPU加速的程序,一般提速都在50~200倍之间。

因此,我们可以看出在做GPU程序设计的时候,数据块的设计本身也是一门技术。


总数据

比如我的总数据块设计成为1000x1000,对于上面的GPU,肯定会产生空转。

但如果我的总数据块设计成为1024x1024,对于上面的GPU,就可以在此基础上设计出一套让GPU满负荷运转的调度。(因为1000x1000肯定不是256x256的整数倍,而1024x1024可以被切割成为整数个256x256大小的数据块)

当然这都是在极限编程的情况下。


分组

那么Group是哪里设置的呢?就是下面这个OpenGL的API

glDispatchCompute(x,y,z)

这个API就是设置的总数据被分为多少个Group,这里定义了Group的大小之后,系统就会自动对总数据进行分组了,分成若干个组(Group)。

总的数据被分组后,这些分组数据被处理的顺序是不可预测的,也就是说,你不知道哪一个分组的数据会被先处理,哪一个后被处理。这里Group之间是并行的,所以你不能让分组的数据之间产生跨组织的依赖性。


每次执行多少数据

这里设置的就是,每一个Group内,每次处理多少个数据。那么这个是哪里设置的呢?是在Shader中设置的,大家可以去翻开我们的Compute Shader课程中的shader代码看看

layout(local_size_x=256,local_size_y=256,local_size_z=1) in;

这就是设置每次我要处理多少个数据,上面的设置是,我每次要处理256x256这么大的数据块。如果我的Group是512x512大小的,那么要处理完毕这个Group的所有数据,需要使用Compute Shader对Group内的数据迭代4次,每次处理其中一块256x256大小的数据。


关于TransformFeedbackObject

有很多人一看到这个玩意就一头雾水,不知道这是干嘛的。

前不久有一个同学跟我们讲,骨骼动画的计算非常耗时,怎么办?我们给他的答案就是使用TransformFeedbackObject。实际上我们光这么讲你肯定又不觉得这靠谱。

但是你们熟悉的游戏引擎Unity中就使用了这个东西对骨骼动画进行处理的。不管怎么说,这种方式是被Unity验证过的,效果马马虎虎还过得去吧。

这个技术是OpenGLES3.0以后的版本就有了的,站在现在这个时间节点,覆盖率是100%。所以不要害怕自己用了特殊的技术,会不被支持,至少在主流的Android和iOS上是100%被支持的。


最后,我们在这里要指出一点的就是,如果有人去百度《兰陵王的骑士》这本书了的话,你就彻底的输了。因为这本书还没有出版。



转载于:https://juejin.im/post/5cce4b0f51882541e37e66e5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值