我还没有写过很多金属内核着色器;这是两个RGBX-32图像之间的一个初出茅庐的“淡入淡出”着色器,使用inBuffer1(0.0)到inBuffer2(1.0)之间的补间值0.0到1.0。
我在这里缺少什么?有些事情让我觉得这可能非常低效。
我的第一个想法是尝试使用可能更好的矢量数据类型(例如char4
)进行减法和乘法,但结果肯定是未定义的(因为某些组件将为负数)
此外,使用MTLTexture
与MTLBuffer
对象有什么好处吗?
kernel void fade_Kernel(device const uchar4 *inBuffer1 [[ buffer(0) ]],
device const uchar4 *inBuffer2 [[ buffer(1) ]],
device const float *tween [[ buffer(2) ]],
device uchar4 *outBuffer [[ buffer(3) ]],
uint gid [[ thread_position_in_grid ]])
{
const float t = tween[0];
uchar4 pixel1 = inBuffer1[gid];
uchar4 pixel2 = inBuffer2[gid];
// these values will be negative
short r=(pixel2.r-pixel1.r)*t;
short g=(pixel2.g-pixel1.g)*t;
short b=(pixel2.b-pixel1.b)*t;
outBuffer[gid]=uchar4(pixel1.r+r,pixel1.g+g,pixel1.b+b,0xff);
}
答案 0 :(得分:2)
首先,您应该将tween
参数声明为:
constant float &tween [[ buffer(2) ]],
使用constant
地址空间更适合这样的值,对于函数的所有调用(并且不通过网格位置等索引)都是相同的。此外,将其作为引用而不是指针告诉编译器您不会将"数组中的其他元素编入索引。指针可能是。
最后,有一个mix()
函数可以执行您在此处执行的计算。因此,您可以使用以下函数替换函数体:
uchar4 pixel1 = inBuffer1[gid];
uchar4 pixel2 = inBuffer2[gid];
outBuffer[gid] = uchar4(uchar3(mix(float3(pixel1.rgb), float3(pixel2.rgb), tween)), 0xff);
关于使用纹理是否更好,这在某种程度上取决于您在运行此内核后计划对结果做什么。无论如何,如果你要用它做类似纹理的东西,那么在整个过程中使用纹理可能会更好。实际上,使用混合而不是计算内核来绘制操作可能会更好。毕竟,这种混合是GPU必须始终做的事情,因此路径可能很快。您必须测试每种方法的性能。
答案 1 :(得分:0)
如果您正在处理图像,使用MTLTexture比使用MTLBuffer要高效得多。使用“一半”比“uchar”更好。我今年直接从WWDC的Apple工程师那里学到了这一点。
unmerged paths:
deleted by them : db.sqlite3
both modifiled : management/__pacache__/forms.cpython-35.pyc