5

iOS のファイルから 4 チャネルのテクスチャ データを読み込みたいので、テクスチャを (連続した) マップと見なします

[0,1]x[0,1] -> [0,1]x[0,1]x[0,1]x[0,1]

fileformat を使用すると.png、XCode/iOS はファイルを画像と見なし、各コンポーネントrgba(事前乗算されたアルファ) を乗算して、データを破損します。これをどのように解決すればよいですか?例としては

  • コンポーネントで 2 つのテクスチャを使用するrgb(3 チャンネル)
  • 分割後のアルファ
  • 別のファイル形式を使用する

これらのうち、私は別のファイル形式を使用することが最善の解決策だと考えています。GL 圧縮ファイル形式 (PVRTC?) は Apple プラットフォームに依存せず、低解像度 (4 ビット) のようです (参照)。

編集: 以下の私自身の答えが当てはまる場合、iOS で png の 4 チャネル データを取得することはできません。OpenGL は画像を表示するのではなく画像を作成するためのものであるため、何らかの方法で 4 チャネル データをロードできるはずです。png は画像のファイル形式です (圧縮は 4 チャンネルすべてに依存します。ただし、1 つのチャネルの圧縮は他のチャネルとは無関係です)。そのため、別のファイル形式を使用する必要があると主張する人もいるかもしれません。では、他のどの圧縮ファイル形式を使用する必要がありますか? iOS で読みやすく統合できるのはどれですか?

更新: 「コンビナトリアル」は、4 チャンネルの事前乗算されていないテクスチャをロードする方法について言及していたので、彼に正しい答えを与える必要がありました。ただし、そのソリューションには、私が気に入らないいくつかの制限がありました。私の次の質問は、「iOSのpngファイルから生の4チャンネルデータにアクセスする」です:)

4 チャンネルの png データを読み込めないのは、ライブラリの設計が悪いと思います。私は、システムが自分より賢くなろうとするのが好きではありません。

4

6 に答える 6

4

あなたが PVRTC を検討したように、 GLKitを使用することはオプションかもしれません。これには、事前にアルファを乗算せずにテクスチャをロードできるGLKTextureLoaderが含まれます。たとえば、次のように使用します。

+ (GLKTextureInfo *)textureWithContentsOfFile:(NSString *)fileName options:(NSDictionary *)textureOperations error:(NSError **)outError

そして、以下を含むオプション ディクショナリを渡します。

GLKTextureLoaderApplyPremultiplication = NO
于 2012-11-28T06:38:11.427 に答える
3

XcodeがPNGファイルを「圧縮」しないように要求するだけです。左上のプロジェクトをクリックし、[ビルド設定]を選択し、[PNGファイルの圧縮]を見つけて、オプションを[いいえ]に設定します。

他のオプションに関しては、分割後は悪い解決策ではありませんが、明らかに全体的な精度が失われ、TIFFとBMPの両方もサポートされていると思います。PVRTCはPowerVR固有であるため、Apple固有ではありませんが、プラットフォームに完全に依存するわけではなく、GPUへの入力がほとんどない状態で解凍するのが簡単な非可逆圧縮になるように特別に設計されています。通常、テクスチャの解像度を上げて、ピクセルあたりのビット数を減らします。

ここに画像の説明を入力してください

于 2012-11-11T22:55:38.930 に答える
3

あらかじめ乗算された色なしで PNG をロードするには、 libpngを使用する必要があります。

C で書かれており、iOS 用にコンパイルする必要があります。

Android でも同様の問題があり、サードパーティのライブラリを使用して、あらかじめ乗算されていない色の PNG ファイルを読み込む必要がありました。

于 2012-11-27T15:42:18.770 に答える
2

これは私自身の質問に答えようとする試みです。

あらかじめ乗算されていない .png ファイルをロードすることはできません。

オプションは有効なオプションですが、 (参照kCGImageAlphaLast)の有効な組み合わせを提供しません。ただし、 の有効なオプションです。CGBitmapContextCreateCGImageRef

COMPRESS_PNG_FILES上記の XCodeのビルド設定が行うことは、.png ファイルを他のファイル形式に変換し、チャンネルrgba(参照) で乗算することです。このオプションを無効にすることで、実際の .png ファイルのチャネル データにアクセスできるようになることを期待していました。しかし、これが可能かどうかはわかりません。次の例は、低レベルで .png データにアクセスしようとする試みですCGImageRef

void test_cgimage(const char* path)
{
    CGDataProviderRef dataProvider = CGDataProviderCreateWithFilename(path);
    CGImageRef cg_image = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO,
                                                           kCGRenderingIntentDefault);
    CGImageAlphaInfo info = CGImageGetAlphaInfo(cg_image);
    switch (info)
    {
        case kCGImageAlphaNone:               printf("kCGImageAlphaNone\n");                break;
        case kCGImageAlphaPremultipliedLast:  printf("kCGImageAlphaPremultipliedLast\n");   break;
        case kCGImageAlphaPremultipliedFirst: printf("kCGImageAlphaPremultipliedFirst\n");  break;
        case kCGImageAlphaLast:               printf("kCGImageAlphaLast\n");                break;
        case kCGImageAlphaFirst:              printf("kCGImageAlphaFirst\n");               break;
        case kCGImageAlphaNoneSkipLast:       printf("kCGImageAlphaNoneSkipLast\n");        break;
        case kCGImageAlphaNoneSkipFirst:      printf("kCGImageAlphaNoneSkipFirst\n");       break;
        default: break;
    }

}

これにより、「kCGImageAlphaPremultipliedLast」がCOMPRESS_PNG_FILES無効になります。したがって、iOS は実行時であっても常に .png ファイルを変換すると思います。

于 2012-11-18T21:14:22.010 に答える
0

あなたが望む100%ではありませんが、私はこのアプローチを使用して問題を回避しました.アルファチャンネルを別の白黒pngに入れ、元のpngをアルファなしで保存します。したがって、使用されるスペースはほぼ同じです。次に、テクスチャ ローダーで両方の画像を読み込み、1 つのテクスチャに結合します。

これが唯一の回避策であることはわかっていますが、少なくとも正しい結果が得られます。はい、非常に面倒です。iOS では、あらかじめ乗算されたアルファなしで PNG からテクスチャをロードすることはできません。

于 2012-12-18T13:33:51.450 に答える