OnRenderImage()を定義するコストについて
ふと、OnRenderImageの第1引数をデバッガで参照した時にこんな記述が、
「ImageEffects Temp」…? ふむ、定義した覚えのないRenderTextureですが、Unityちゃんが自動で定義してくれたんだろう。
ん?ということは、OnRenderImage()を定義しただけで負荷が増すということか??
ということで調べてみました。
☆OnRenderImage()を定義していない場合
FrameDebug
プレーンなプロジェクトなので画面クリアだけ
Profiler-Memory-Detailed
RenderTextureは1枚
☆OnRenderImageを定義した場合
FrameDebug
なんか描画パス増えてる。
Profiler-Memory-Detailed
RenderTextureに ImageEffects Temp が2つ増えてる。 2つ!?(AA用?)
という事で、OnRenderImage()を定義しただけで、
・描画パスが増える
・RenderTextureが2つ増える(多分大きさは画面サイズに依存)
ようです。これってモバイル系だと結構無視できない負荷に思えます。
これがモバイルでも同じように動いているなら、特に必要ないようであればOnRenderImage()は定義しないほうが良さそう。
『そんなこと言われたって、スクリーンをキャプチャしなきゃ、色々なスクリーンエフェクトをかけられないじゃないか!』
…という方はOnRenderImage()ではなく、OnPostRender()でScreen(フレームバッファ)の画像をRenderTextureにコピーすれば良いかと。
unity_FogParamsの値について
Builtin_Shadersの中で、UnityCG.cgincを見てみると、フォグに関わるマクロについては
UNITY_CALC_FOG_FACTOR フォグの強さを決める+変数定義
UNITY_FOG_COORDS_PACKED フォグ演算(の結果の値を渡すため)に使うテクスチャ座標の定義
UNITY_FOG_COORDS 同上
UNITY_TRANSFER_FOG VS側で使用。モバイル系だと色決め。UNITY_FOG_LERP_COLOR 線形(lerp)で色決め
UNITY_APPLY_FOG_COLOR UNITY_FOG_LERP_COLORで色決め。
UNITY_APPLY_FOG FS側で使用。UNITY_APPLY_FOG_COLORで色決め。
だいたいそんな感じ。
で、その中で使われている unity_FogColor、unity_FogParams ですが、
マニュアルを見るとRenderSettings.fogColorとRenderSettings.fog[Start,End]Distanceと値が紐付いている模様。
fogの設定を切って、自前Fog演算を作る際に、値を拝借してデータ量を削減しようと試みた所、
fogColorについてはunity_FogColorに値が渡されているようですが、
何とfog[Start,End]Distanceについては、unity_FogParams.zwに値が渡っていない…。
どうやら、fogの設定を切るとunity_FogParamsにRenderSettingsからの値が入らなくなるようです。
多分、UNITY_CALC_FOG_FACTORを見た感じ、
unity_FogParams.zには(-1/(end-start))が入っていて、
unity_FogParams.wには(end/(end-start))が入るようなので
その分の演算+値渡しが省かれているのかな?
結局Shader.GlobalVector()を使って、
自前Global変数に(-1/(end-start))と(end/(end-start))を渡すようにしましたが、果たして軽量化できているのか微妙ですね。。
iPhone用のSetPlatformTextureSettingsが反映されない場合の対処
Unity - Scripting API: TextureImporter.SetPlatformTextureSettings
には、
platform の文字列は BuildTarget の列挙体を文字列へ変換したものと同じものです。
とか書いてあるから
Unity - Scripting API: BuildTarget
を見て、iPhone用に第1引数に "iOS" って書いたのにiPhone用の設定が通らないでやんの。。
"iPhone" と書けば通りましたが、それなら何処かに書いておいてほしいなぁ。。
ARB って何?
シェーダ指定で
fragmentoption ARB_precision_hint_fastest
と指定するとARB命令の精度を良い感じに軽くしてくれる、らしいですが
http://developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide_Japanese.pdf
そもそもこの ARB って何なんだろう??
という事で調べてみました。
OpenGLの機能拡張が分かりにくいワケ | shikihuiku
…ググったらあっさり見つかったわい。
という事でARBは、一定水準以上の有用性のある追加拡張機能を採用した際につけられるプレフィックスという事でしょうか。
どんな命令があるかあまり知らないので引き続き調べてみたいところです。
ParticleSystem の 更新間隔を間引く
朧村正を最近遊んでいて、桜吹雪の更新間隔がキャラの更新間隔よりも遅く、それでいて気にならないので、ParticleSystemで似たようなことができないかどうか試してみました。
書いたコードはこちら↓
using UnityEngine;
using System.Collections;
public class ParticleIntervalUpdater : MonoBehaviour {
ParticleSystem myParticleSystem;
void Awake()
{
myParticleSystem = GetComponent< ParticleSystem >();
}
void Start()
{
StartCoroutine( IntervalUpdate( 0.125f ) );
}
IEnumerator IntervalUpdate( float time )
{
while (true)
{
myParticleSystem.Simulate (time, true, false);
yield return new WaitForSeconds ( time );
}
}
}
動画は面倒くさいので撮ってないですが、パッと見処理落ちしているように見えますが一緒にキャラを動かすと意外と気にならないもんです。
更新間隔も少なくなるので、もしかすると処理負荷も軽い…!?と良いなぁ。
ParticleSystem - Renderer - NormalDirectionを0指定してParticleにライトを当ててみる
最近知ったのですがParticleSystemコンポーネントのRendererのNormalDirectionを0にすると、Particleの中心を0としてのベクトルが法線情報に入るっぽい。
↑法線を表示するシェーダを載せたらこんな感じ
…って事はライティングしてボリューム感出せそうだな〜と思ってセコセコShader書いてましたが、そういえばParticle/VertexLitっていうのが有りましたね;
↑NormalDirectionを0にしてParticle/VectexLitシェーダを入れたもの
↑ちゃんとライト方向でシェードが変わります。
↑普通のParticle/Alpha Blend。コレよりは味が出たかな?
ただまぁLightingしているのでモバイルで似たようなことをする時は仮でライトベクトルを用意して近似するくらいにしておくのが良い気がします。
↑調整すれば中々それっぽく見える気がする
ProjectSettings - Graphics Settings - Built-in shader Settings の設定差によるパッケージサイズの差
GraphicsSettings
http://docs.unity3d.com/ja/current/Manual/class-GraphicsSettings.html
の Built-in shader Settings ですが、モバイルだとほぼほぼDefferdRenderingすることもなさそうだし必要ない気がする。
遅延シェーディング、遅延ライティングとも、使用しない場合はそれぞれ “No Support” と指定すれば、ゲームのデータファイルのスペースを節約できます。
ともあるので、「データファイルのスペース」が果たしてパッケージのサイズなのか起動後のメモリサイズなのかよくわからなかったので、とりあえずapkを作ってパッケージサイズだけでも比べてみた。
※プロジェクトを作った直後のシーンでapk作成
Defferd,Defferd Reflection,Legacy Defferdが全てBuilt-in Shaderの場合
全てNo Supportの場合
という事で、
全てBuilt-in shader … 19,426,543 bytes
全てNo Support … 19,373,868 bytes
とパッケージサイズだけでも52,675 bytes(約50KB)の差ができました。
確か「シェーダは初めて使うときにロードされる(その負荷を防ぐためにShader.WarmupAllShaders()が有る)はずなので、Defferdレンダリングしないなら起動後もメモリに乗ることはなかろう」とは思うのですが、使いもしないDefferdのために容量50KBを残すのもナンなので、NoSupportにしておくべきかと思いました。
http://docs.unity3d.com/ja/current/ScriptReference/Shader.WarmupAllShaders.html
せっかくなので関連として、次はShaderVariantCollectionについても調べてみようと思います