ScreenPocket - 画面の隙間

Unityエンジニアの日々の雑記。たまにpython3、DirectX、PhotoshopScript(JavaScript)も触ります

ARB って何?

シェーダ指定で

fragmentoption ARB_precision_hint_fastest

と指定するとARB命令の精度を良い感じに軽くしてくれる、らしいですが

http://developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide_Japanese.pdf

そもそもこの ARB って何なんだろう??
という事で調べてみました。

OpenGLの機能拡張が分かりにくいワケ | shikihuiku

www.opengl.org

…ググったらあっさり見つかったわい。

という事で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としてのベクトルが法線情報に入るっぽい。

f:id:ScreenPocket:20160115015352p:plain
↑法線を表示するシェーダを載せたらこんな感じ

 

…って事はライティングしてボリューム感出せそうだな〜と思ってセコセコShader書いてましたが、そういえばParticle/VertexLitっていうのが有りましたね;

f:id:ScreenPocket:20160115015628p:plain↑NormalDirectionを0にしてParticle/VectexLitシェーダを入れたもの

f:id:ScreenPocket:20160115015905p:plain↑ちゃんとライト方向でシェードが変わります。

f:id:ScreenPocket:20160115020012p:plain↑普通のParticle/Alpha Blend。コレよりは味が出たかな?

ただまぁLightingしているのでモバイルで似たようなことをする時は仮でライトベクトルを用意して近似するくらいにしておくのが良い気がします。

f:id:ScreenPocket:20160115020201p:plain
↑調整すれば中々それっぽく見える気がする

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の場合

f:id:ScreenPocket:20160114000153p:plain

全てNo Supportの場合

f:id:ScreenPocket:20160114000438p:plain

という事で、
全て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についても調べてみようと思います

PreserveAttribute について

適当に開いてみたリファレンスの項目を適当に調べて見るテスト

今回は「UnityEngine.Scripting.PreserveAttribute」

http://docs.unity3d.com/ja/current/ScriptReference/Scripting.PreserveAttribute.html

https://unity3d.com/jp/unity/whats-new/unity-5.1.2

↑のリリースノート・ドキュメントを見ると

  • iOS/IL2CPP: IL2CPP のストリップからクラス、メソッド、フィールドを除外する PreserveAttribute を追加

との事。このくらいの時期に追加されたのかな。

クラス、メソッド、フィールドにつけられる様で、未使用の項目が自動削除されないように置いておくための属性っぽい??
最適化を防ぐ(抑制する?)という点ではC++のvolatileっぽい感じか。

後、IL2CPP Platformでしか作用しない様なので注意が必要そう。

とりあえず今日はこの辺で。

CameraEvent.Before/AfterSkyboxについて

CameraEvent.AfterEverythingで指定されたCommandBufferは全ての最後に行う…ってことは、逆に全ての最初に行うCameraEventも有るのかな??と思ったのですが対になるCameraEvent.BeforeEverythingは無い模様…。

ならば、きっと最初に描画されるSkyBoxの前、BeforeSkyboxに自前のCommandBuffer(スクリーンをクリアするメッシュを描画する)を発行するようにして、カメラのClearFlagをDon'tClearにすれば、自分で用意したメッシュでフレームバッファをクリアできるぞ!

…と思ったのですが、↑の設定(ClearFlagsをDon'tClearにして、CameraEvent.BeforeSkyboxのタイミングでCommandBufferを発行)だと全く反応がない…。

もしやと思って、AfterSkyboxにしてもやっぱり反応がない…。

 

結局ClearFlagsをSkyboxにしないとBefore/AfterSkyboxは反応しませんでした。

 

…ということは、カメラのClearFlagsに依存しないで一番最初のタイミングでCommandBufferを差し込みたかったらCameraEvent.BeforeForwardOpaqueしかないんだろうか…。(ForwardRenderingでの話。)

スクリプトからのConstantカーブの指定方法

アニメーションのカーブを自前で追加したかったので、
スクリプトでAnimationCurveを作ってKeyframe指定などをしていたのですが、どうにもLinearかSmoothしか指定できない様子。。

調べた結果Keyframeには隠されたパラメータ、tangentMode という項目がありそこに 31 という値を代入すればいける!! との情報を見つけたので試してみたところ上手くいきませんでした;

しかも↑を設定したAnimationClipをAnimationのカーブエディタで確認したところ、キーの値はしっかりConstantになっているのにカーブの実態はSmoothのままという…。

文字通りキーッ!となって調べ倒した結果、
Keyframe設定時のtangentのパラメータにinfinityを代入すればConstant化できる
ようですね

http://answers.unity3d.com/questions/253837/can-i-set-an-animationcurve-keyframes-interpolatio.html

めちゃくちゃ時間かかりましたがとりあえず解決!