如何在开放gl纹理的alpha中编码发射或镜面反射信息

时间:2014-02-13 11:14:04

标签: ios opengl-es png photoshop texture-mapping

我有一个带有UV贴图的OpenGL纹理。我已经阅读过使用alpha通道存储一些其他值,这样可以节省从某处加载额外地图的费用。例如,您可以在alpha中存储镜面反射信息(光泽)或发射贴图,因为您只需要浮点数并且不使用alpha。

所以我试了一下。编写着色器不是问题。我完成了所有这一部分。问题是只需要将所有4个通道输入到纹理中。

我有所有的地图所以在PSD中我将基本地图放在rgb中,排放地图放在a中。但是当你保存为png时,alpha不会保存(如果你把它添加为新的通道),或者它通过将透明度预乘到rgb来破坏rgb(如果你将地图作为掩码应用)。

显然PNG文件本身支持透明但不支持Alpha通道。所以似乎没有办法控制所有4个频道。

但我已经读过这样做了。那么我可以将哪种格式保存在PSD中,我可以用iPhone中的图像加载器加载它?

NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:type];
NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
UIImage *image = [[UIImage alloc] initWithData:texData];

此方法是否接受其他文件格式?像TIFF那样可以控制所有4个频道吗?

我可以使用texturetool制作PVR ..但是从文档看来它也是一个PNG作为输入。

编辑:

首先要清楚这是在iPhone中。

这可能是psd的错。就像我说的,有两种方法可以在我的psd版本(cc 14.2 mac)中设置文档,我可以找到它。一种是手动添加新频道并将地图粘贴到那里。它显示为红色叠加层。第二个是添加一个蒙版,选项单击它并将alpha粘贴在那里。在这种情况下,它显示它与alpa作为透明度与棋盘格在alpha零区域。当我保存为png时,alpha选项会变灰。

当我将png重新加载到psd时,它似乎是预乘的。我无法在photoshop中找回我的完整rgb数据。

我是否可以使用不同的工具将两张地图合并为一个png,将其存储为png-32?

TIFF不起作用,因为它也不存储alpha。也许我在考虑TGA。

我在装载机中也注意到了这一点......

    GLuint width = CGImageGetWidth(image.CGImage);
    GLuint height = CGImageGetHeight(image.CGImage);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    void *imageData = malloc( height * width * 4 );
    CGContextRef thisContext = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );

    if (flipImage)
    {
        CGContextTranslateCTM (thisContext, 0, height);
        CGContextScaleCTM (thisContext, 1.0, -1.0);
    }

    CGColorSpaceRelease( colorSpace );
    CGContextClearRect( thisContext, CGRectMake( 0, 0, width, height ) );
    CGContextDrawImage( thisContext, CGRectMake( 0, 0, width, height ), image.CGImage );

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

    glBindTexture(GL_TEXTURE_2D, textureInfo[texIndex].texture);

当我创建该上下文时,该选项为kCGImageAlphaPremultipliedLast

也许我确实需要尝试glkit加载器,但似乎我的png是预乘的。

1 个答案:

答案 0 :(得分:0)

可以创建带有Alpha通道的PNG,但是如果没有预乘,您将无法使用内置的iOS API读取该PNG图像。核心问题是CoreGraphics仅出于性能原因支持预乘alpha。您还必须小心禁用Xcode对附加到项目文件的PNG的优化,因为它在编译时进行预乘。您可以做的是在关闭Xcode PNG处理后在您自己的libpng副本中编译和链接,然后直接使用C级别的libpng读取文件。但是,说实话,这是浪费时间。只需使用RGB值保存一个图像,将另一个图像保存为灰度,其中alpha值为0-255灰度值。您可以将这些灰度值表示为您想要的任何内容,并且您不必担心将事情弄得一团糟。你的opengl代码只需要从多个纹理中读取,这不是什么大问题。