uka.apple のすべての投稿

パクリアプリ開発日記 21日目 プログラムの汎用性考慮

今日は、このアプリを将来にわたってどの程度使い続けるか、またどの範囲において使えるようにするかを考え、それに基づいて、タップやUIを扱うアプリーケーション層、OpenGLによるレンダリング処理、頂点データの生成ロジックなど各種処理について、その構成や相互作用などを検討し、どのようにすべきか悩んでいました。

例えばAndroidとiOSの双方に対応しようとした場合、Objective-Cで書くべきではなく、C++で書くべきです。Objective-CはC++と混在して記述できるし、C++にしておけばJavaからも呼べるようになります。

また、将来的にOpenGLがバージョンアップした場合、レンダリングエンジンをインターフェースでうまく疎結合にしておけば、最小限の範囲の手直しで新バージョンに対応出来るようになります。

・・・なんてことを考えていたんですが、多分将来はまた新しい言語とか予期できない仕様変更とか出てくるかもしれないから、あらかじめ準備しても全て無駄で、その度に1からやり直したほうがはるかに柔軟に対応できるし手っ取り早い気がしてきました。個人開発のアプリだし。

過去に自分が作成したプログラムも内容忘れてるからコピペレベルで書き直したほうが早いと思います。

iPhone初代が出たのは2007年6月で、まだ10年経ってません。10年前はスマホが存在しなかったんですよねえ・・・

あんまり先のこと考えてもしょうがないですよね。

★☆★ 次回の作業 ★☆★

設計作業で時間を使わないで素早く作業を終える覚悟を決める。

パクリアプリ開発日記 20日目 OpenGL ES 3.0での実装作業

OpenGL ES 3.0で実装作業をしてました。

3.0で頂点シェーダやフラグメントシェーダの書き方が変更になっていて、ちょっと手間取っていますがぼちぼち進んでいます。

3Dの世界を構築する作業はとっても楽しいです。いっそOpenGLの3D空間の中に入って一生暮らしたいです。どうすれば入れますか?

★☆★ 次回の作業 ★☆★

メモリ量削減の構想に従って引き続き実装作業を行う。

パクリアプリ開発日記 19日目 メモリ使用量の削減

今回は、多数の立方体を描画するためのメモリ使用量削減について検討しました。

具体的には

1.頂点法線の見直し
2.インデックスバッファの使用
3.GL_TRIANGLE_STRIPの使用

の3つです。

ひとつひとつ削減量を確認して行きます。

1.頂点法線の見直し

まず頂点法線ですが、これは主に3Dオブジェクトを滑らかに描画するために使用されます。いわゆるシェーディング表現のためが主です。

私がやろうとしてるのはマイクラのパクリです。マイクラの世界は四角形ばかりですよね?なので不要です。
ただし、明るさの情報は欲しいので追加します。

ひとつの頂点に必要な情報として、

4バイト x 3軸(位置) + 4バイト x 3軸(向き) + 4バイト x 2軸(テクスチャ) = 32バイト

4バイト x 3軸(位置) + 4バイト(明るさ) + 4バイト x 2軸(テクスチャ) = 24バイト

となるので、25%の情報を削減出来ます。

なお、明るさ情報だけで4バイトもいらないので、この部分には将来的に別の情報も追加出来ると思っています。

2.インデックスバッファの使用

前回、立方体を作るには、先ず3角形を2つ組み合わせて4角形を、4角形を6つ組み合わせて立方体を作ることとしました。頂点数は3*2*6=36となります。でも、これって無駄ですよね?

本来、立方体に必要な頂点数は4つで良いはずです。

技術的には、頂点バッファオブジェクトを使う場合は36必要ですが、インデックスバッファを使うと4つで済むようになります。

ただし、インデックスバッファ分が余分に増えます。

インデックスバッファのデータ型は、short(2バイト)にしたいのですが、これだと多数の立方体を作るには足りないので、long(4バイト)にします。

1つの立方体の情報量はインデックスバッファを使わない場合、

36(頂点数) * 24(1頂点あたりの情報量) = 864

で、使う場合は、

4(頂点数) * 24(1頂点あたりの情報量) + 36(インデックスバッファ) * 4(long) = 240

となり、約72%削減できます。

3.GL_TRIANGLE_STRIPの使用

インデックスバッファは、GL_TRIANGLEを使うと一つの立方体に36個必要ですが、GL_TRIANGLE_STRIPを使えば14個で済みます。詳しい話はしませんが済むんです。ただし、離れた立方体を描画するのに”区切り”の情報が欲しいのでもう1個(OpenGLES3.0の場合は区切り情報1個で済みます)必要です。ですので合計15個になります。

よって、

4(頂点数) * 24(1頂点あたりの情報量) + 36(インデックスバッファ) * 4(long) = 240

4(頂点数) * 24(1頂点あたりの情報量) + 15(インデックスバッファ) * 4(long) = 156

で、更に35%削減できます。

以上、1から3を全て行う前と後で比べると、

36(頂点数) * 32(1頂点あたりの情報量) = 1152バイト

4(頂点数) * 24(1頂点あたりの情報量) + 15(インデックスバッファ) * 4(long) = 156バイト

となるので、約86%の情報を削減出来ます。

これならば、例えば 100 * 100 * 100 で合計100万個の立方体を描画したとしても、

156 * 100 * 100 * 100 = 156MB

となり、iPhoneで動きそうですね。削減前だと1GB超えます。ただ、iPhone6sなら削減前でも動きそうです。

自分も思考するためのメモリ使用量を削減して、頭の中の少ないメモリを有効活用したいです。

★☆★ 次回の作業 ★☆★

メモリ量削減の構想に従って実装作業を行う。

パクリアプリ開発日記 18日目

どうやら1080 TIは、35%程度性能アップする代わりに30%以上消費電力が上がってるみたいで、電力効率としてはそれほど改善されていないようです。まあTIですからね。力任せな感じですね。

ということは、先日購入した1070は、ワットパフォーマンスという点では未だにトップクラスと言うことです。ある程度負荷かけてもファンの音がそれほどしないし、40℃すら行かないその様を見てると、とても頼もしいです。

ちょっと立ち直ってきました。

★☆★ 次回の作業 ★☆★

最新グラボ買った直後、新型が出たショックから立ち直る。

パクリアプリ開発日記 15日目

新GPU「GeForce GTX 1080Ti」が発表されたようです!

私、先週GTX1070買ったばかりなんですけど。

1080Ti登場に合わせて、1080を約1万円程度値下げするそうです。また、1080と1060のメモリクロック向上版が登場するそうです。

私、先週GTX1070買ったばかりなんですけど。

1070については値下げも、メモリクロック向上版もないのかな?

なんか、戦場で流れ弾をギリギリ避け続けているような心境です。ちょっとでも気をぬくと死にそうです。

★☆★ 次回の作業 ★☆★

最新グラボ買った直後、新型が出たショックから立ち直る。

パクリアプリ開発日記 14日目 OpenGLで12万5千個の立方体を描画するためのメモリ量を考える

★☆★ 今回の作業 ★☆★

前回、12万5千個の立方体をUnityで作ったプロジェクトからiPhone6sで描画しようとしたら、Xcodeからメモリ足りねーよ馬鹿がと言われて落ち込んだため、使用メモリ量の計算をちゃんとしようと思います。

立方体は6つの四角形で形成されます。3次元座標 xyz の3軸の位置情報が4つあれば1つの四角形を、そしてそれが6個あれば立方体を定義出来ます。ただし、OpenGL ESでは四角形がサポートされません。ですので四角形は2つの三角形を組み合わせます。

(OpenGL知ってる方は分かると思いますが、GL_TRIANGLESを使います。GL_TRIANGLE_STRIPは先ずは置いておきます。)

xyzの位置情報の精度はfloatの4バイトが一般的だと思います。

4バイト x 3軸(位置) = 12バイト

ただし、各頂点の向きを決めなければいけません。向きがないと表や裏の区別が付きません。また、テキスチャで絵を表示したいため、その情報も必要です。向き情報は各頂点毎にxyzの3軸それぞれに対してfloatの4バイトで定義します。テクスチャは各頂点毎にxとyの2次元でやはりfloat値により位置を指定します。

よって、1つの頂点の情報は、

4バイト x 3軸(位置) + 4バイト x 3軸(向き) + 4バイト x 2軸(テクスチャ) = 32バイト

になりました。

この32バイトに3を掛けると三角形が、さらに2を掛けると四角形が、さらに6を掛けると立方体になるので1つの立方体の情報量は

32バイト x 3 x 2 x 6 = 1,152バイト

です。

12万5千個の立方体を描画するには

1,152バイト x 125,000 = 144,000,000

で、144メガバイトとなりました。

あれ?iPhone6sの2ギガバイトに収まりますね?

何してるんですかUnity君?

何も言わないと標準で付いてくる、オプション盛り盛りな携帯電話の契約を思い出します。多分物理演算用の情報とかいっぱい付いてるんだろうな。

わたしはオプションの内容を細かく調べて、不要なものを全部解約出来る自信はないです。

ちなみに、iPhoneのマイクラって100ブロック先位まで見えてますよね?なので、本当は 200 x 200 x 200 で 800万個 くらいの立方体を1度に描画したいです。工夫すればここまでの数は必要ないと思いますが、何れにしても25ブロック先も見えないマイクラやりたくないです。(50*50*50=12万5千)

Unityは使わない事にしました。

★☆★ 次回の作業 ★☆★

1つの立方体の情報量をもっと少なくできないか検討する。

パクリアプリ開発日記 13日目 Unityで12万5千個の立方体を描画する際のFPS計測

★☆★ 今回の作業 ★☆★

Unity上でCubeを”Duplicate”(複製)し、ひたすらコピーしていきます。重くはなりましたが、なんとか12万5千個の立方体を並べる事が出来ました。

この段階で動かなくなれば、”バーカバーカ役たたーず”とか言ってUnityを馬鹿にするつもりでしたが大丈夫でした。惜しいな。

次に、UnityからiOSのプロジェクトを作成しましたが、ここは馬鹿にしていいと思います。iOSのプロジェクト生成するのになんと5時間かかりました。

バーカバーカ役たたーず。

でもちゃんと生成できました。そしてiOS上で実行してみました。iPhone6sで動かします。自力でOpenGLES3.0使って
描画した時は、21FPSでました。Unityでは何FPS出るんでしょか?やはり最適化されて、無駄な描画とか極力省くようになっているから21FPSより良い結果になるんでしょうか?

・・・

・・

・・・あれ?実行されないな。

Xcodeを見ると、

“Finished running”(実行が終了した)

と出ています。あれ?おかしいな。まだ実行されてないんですけど。で、よくよく見ると、Xcodeでメッセージが出ています。

Message from debugger: Terminated due to memory issue

翻訳:12万5千個も立方体作ればメモリ不足になるのがわからないのか?iPhone6sの2GBでも足りねーわ。お前の頭がメモリ不足です。

・・・その通りです。

こうしてFPS計測不能という事がわかりました。

★☆★ 次回の作業 ★☆★

Xcodeに馬鹿にされたことから立ち直る。