-
Notifications
You must be signed in to change notification settings - Fork 1
軽量化について
Naoaki-Y edited this page Jan 26, 2020
·
1 revision
500個の方位磁針の個々の物理計算を毎フレームおこないながら、FPS 58を実現しています。
具体的には、シェーダをインスタンス化せずに、シェーダ内で物理計算をおこなって負荷を大幅に減らしています。
なお、軽量化が必要な理由については次項の「UI・表現」で説明します。
以下のように、マテリアルをスクリプトから操作せずに、シェーダに外部変数を受け取る変数を設定し、スクリプトからマテリアルを介さずにシェーダに直接値を代入しています。
CompassesManagedlySimultaneouslyUpdater.cs
void AssignMagnetPosition()
{
var np = barMagnet01NorthPole.transform.position;
var sp = barMagnet01SouthPole.transform.position;
var nv4 = new Vector4(np.x, np.y, np.z, 0); //Vector4 に変換
var sv4 = new Vector4(sp.x, sp.y, sp.z, 0); //Vector4 に変換
// 方位磁針の N 極側のマテリアルのシェーダに座標をセット
CompassesModel.Instance.MatNorth.SetVector("_NorthPolePos", nv4);
CompassesModel.Instance.MatNorth.SetVector("_SouthPolePos", sv4);
// 方位磁針の S 極側のマテリアルのシェーダに座標をセット
CompassesModel.Instance.MatSouth.SetVector("_NorthPolePos", nv4);
CompassesModel.Instance.MatSouth.SetVector("_SouthPolePos", sv4);
}
これによりシェーダがインスタンス化されず、単一のシェーダとして処理されるため、計算負荷を大幅に減らすことができます。
以下のように、シェーダ内で物理計算を行っています。
// 自身(方位磁針)の位置ベクトルvecPを作成
float3 vecP;
vecP = IN.worldPos;
// N極の位置ベクトルvecNを作成
float3 vecN;
vecN.x = _NorthPolePos.x;
vecN.y = _NorthPolePos.y;
vecN.z = _NorthPolePos.z;
// S極の位置ベクトルvecSを作成
float3 vecS;
vecS.x = _SouthPolePos.x;
vecS.y = _SouthPolePos.y;
vecS.z = _SouthPolePos.z;
// 自身から棒磁石に対する変位ベクトルvecDisN、vecDisSを作成
float3 vecDisN, vecDisS;
vecDisN = vecP - vecN;
vecDisS = vecP - vecS;
// 極からの磁力ベクトルvecF_N, vecF_Sを求める
float3 vecF_N, vecF_S;
vecF_N = vecDisN / pow(length(vecDisN), 3);
vecF_S = -1.0 * vecDisS / pow(length(vecDisS), 3);
// 磁力の合力ベクトルvecFを求める
float3 vecF;
vecF = vecF_N + vecF_S;
これにより、物理計算をGPU内で完結させることができ、CPUへの負荷を大幅に減らすことができます。HoloLensのCPUはとても非力なため、必要な処理をどれだけGPUに回せるかが重要です。