低成本的图像到NSData转换,用于馈送SCNTechnique的sampler2D输入 [英] Low cost Image to NSData conversion for feeding SCNTechnique's sampler2D inputs
问题描述
有时唯一的方法将宝贵的数据隐藏在纹理中,从而将它们从CPU传递到GPU.
Sometimes the only way to pass precious data from CPU to GPU is by hiding it in textures.
我试图欺骗SCNTechnique,并简单地传递[NSData dataWithBytes:length:]
或包含我准备好的原始像素数据字节的CGDataProviderRef
,但是SceneKit足够聪明,可以检测到我的险恶尝试.
I tried to trick SCNTechnique and simply pass [NSData dataWithBytes:length:]
or a CGDataProviderRef
containing my neatly prepared raw pixel data bytes, but SceneKit is smart enough to detect my sinister attempts.
但是我没有放弃,发现了一个漏洞:
But I did not give up, and found a loophole:
[_sceneView.technique setValue: UIImagePNGRepresentation(encodeInSinglePixelUIImage(pos.x, pos.y)) forKey:@"blob_pos_"];
您可以负担得起在移动设备上以60fps的速率对单像素PNG进行编码和解码的费用,而在iPhone X上,它只需花费2ms的时间,并使您的手掌保持温暖. 但是直到11月,我才不需要任何发热功能,所以我想知道这种方法是否有很酷的替代方法.
Encoding and decoding single pixel PNGs at 60fps on a mobile device is something you can afford, on an iPhone X it just costs 2ms and keeps your palm a little bit warmer. However I do not need any heat-generating features till november, so I was wondering if there's a cool alternative to this method.
推荐答案
我发现最有效的方法是构造浮点RGB TIFF. 它仍然不是超级快,在iPhone X上消耗了0.7毫秒,但比PNG方法要快得多.
The most efficient way I found is constructing floating point RGB TIFFs. It's still not super fast, consuming 0.7ms on the iPhone X, but a lot faster than the PNG method.
具有浮点纹理还具有直接浮点传输的优点,即无需在CPU上对多个uint8 RGBA值进行编码,而无需在GPU上重建浮点.
Having a float texture also have the benefits of direct float transfer, that is, no encoding to multiple uint8 RGBA values on the CPU and reconstructing floats on the GPU.
方法如下:
NSData * tiffencode(float x, float y)
{
const uint8_t tags = 9;
const uint8_t headerlen = 8+2+tags*12+4;
const uint8_t width = 1;
const uint8_t height = 1;
const uint8_t datalen = width*height*3*4;
static uint8_t tiff[headerlen+datalen] = {
'I', 'I', 0x2a, 0, //little endian/'I'ntel
8, 0, 0, 0, //index of metadata
tags, 0,
0x00, 1, 4, 0, 1, 0, 0, 0, width, 0, 0, 0, //width
0x01, 1, 4, 0, 1, 0, 0, 0, height, 0, 0, 0, //height
0x02, 1, 3, 0, 1, 0, 0, 0, 32, 0, 0, 0, //bits per sample(s)
0x06, 1, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, //photometric interpretation: RGB
0x11, 1, 4, 0, 1, 0, 0, 0, headerlen, 0, 0, 0,//strip offset
0x15, 1, 3, 0, 1, 0, 0, 0, 3, 0, 0, 0, //samples per pixel: 3
0x16, 1, 4, 0, 1, 0, 0, 0, height, 0, 0, 0, //rows per strip: height
0x17, 1, 4, 0, 1, 0, 0, 0, datalen, 0, 0, 0, //strip byte length
0x53, 1, 3, 0, 1, 0, 0, 0, 3, 0, 0, 0, //sampleformat: float
0, 0, 0, 0, //end of metadata
//RGBRGB.. pixeldata here
};
float *rawData = tiff+headerlen;
rawData[0] = x;
rawData[1] = y;
NSData *data = [NSData dataWithBytes:&tiff length:sizeof(tiff)];
return data;
}
我使用的有用的TIFF链接:
Useful TIFF links I used:
http://www.fileformat.info/format/tiff/corion.htm
http://paulbourke.net/dataformats/tiff/
https://www.fileformat.info/format/tiff/egff.htm
https://www.awaresystems.be/imaging/tiff/tifftags/sampleformat.html
这篇关于低成本的图像到NSData转换,用于馈送SCNTechnique的sampler2D输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!