我一直在使用 Three.js 来实验和学习 GLSL 和 WebGL。我来自 3D 艺术世界,所以我了解网格、3D 数学、光照等概念。虽然我查阅了 OpenGL 和 WebGL 文献(以及 gpu gems、eric lengyels 数学书等),但我似乎错过了一些关键的东西适用于图形的 CS 概念。
目前,我正在使用颜色进行调试,并使用画布检查器来查看绘制调用需要多长时间。
我感兴趣的是这样的问题:
假设你有这样的东西
vec2 normalizedCoord = gl_FragCoord.xy / uniform_resolution.xy;
vs
vec2 normalizedCoord = gl_FragCoord.xy * uniform_resolution_inverse.xy;
vs
... the same with lowp/mediump/highp
Run Code Online (Sandbox Code Playgroud)
精度/性能会发生什么变化?
或者类似的东西
vec4 someVec4 = ...;
float sum = dot(someVec4,vec4(1.));
vs
float sum = someVec4.x + someVec4.y + someVec4.z + someVec4.w;
Run Code Online (Sandbox Code Playgroud)例如,当进行某种采样(SSAO 或类似的操作)时,纹理查找有何含义?
这是迈克尔·亚伯拉什·布莱克(Michael Abrash Black)书中可以找到的信息类型吗?
如果有人可以帮助我更好地表达这个问题,我将不胜感激:)
我相信比我缺乏经验的人可以给你更好的答案,但事实是。这取决于。
GPU 是并行的,并且它们都是不同的,因此在一个 GPU 上花费一定时间的任务可能在另一个 GPU 上花费更少的时间。
最重要的是,我不知道“画布检查器”是什么意思,但它可能无法向您显示需要多长时间,因为图形管道也是并行的,多线程,多进程的,所以,至少从JavaScript 的 POV 你所能知道的是提交命令花了多长时间,而不是执行它花了多长时间。例如,在 Chrome 中,命令被传递到 GPU 进程,JavaScript 继续执行。然后 GPU 进程将其传递给 GL/DirectX,GL/DirectX 又将命令传递给另一个进程,至少在大多数桌面操作系统上是这样。
人们谈论使用gl.finish来找出某件事需要多长时间,但即使这样也不起作用,因为它并没有告诉您 GPU 运行了多长时间。它告诉您 GPU 运行需要多长时间 + 同步所有这些进程需要多长时间。这有点像问“汽车行驶了多快”,而您唯一可以测量的是汽车从停止状态到另一个停止状态。您可以知道一辆车在一定时间内从 A 点到达 B 点,但您无法测量哪辆车的速度最快。一辆车可能在 1 秒内从 0 加速到 60,然后花了 3 秒减速。对方瞬间0-20,4秒到达球门后瞬间停步。两辆车都用了4秒。如果你能测量的只是他们花了 4 秒,你就无法判断哪个击球速度更快。
更糟糕的是,您拥有与所有 iOS 设备和许多 Android 设备中的平铺架构一样的平铺架构,这些架构在拥有所有命令之前不会真正进行绘制。然后,他们生成命令“图块”来渲染屏幕的不同部分。
好吧,那已经偏离主题了。
一般来说,代码越少速度越快,纹理查找速度很慢,GPU 具有纹理缓存,因此在“典型”使用中,纹理在多边形上延伸,纹理缓存有很大帮助。不过,您可以通过进行随机纹理查找来终止纹理缓存。例如,创建一个随机纹理,使用该纹理来计算另一个纹理的纹理坐标。这将完全杀死纹理缓存,并且 GPU 运行速度会非常慢。
据此调配速度很快。点积很快。乘法和加法很快。线性插值速度很快。