低成本的图像到NSData转换,用于馈送SCNTechnique的sampler2D输入 [英] Low cost Image to NSData conversion for feeding SCNTechnique's sampler2D inputs

查看:102
本文介绍了低成本的图像到NSData转换,用于馈送SCNTechnique的sampler2D输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时唯一的方法将宝贵的数据隐藏在纹理中,从而将它们从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆