テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】Burstコンパイラでルックアップテーブルを使用する

f:id:tsubaki_t1:20191011215417j:plain

ルックアップテーブルを使おう

ルックアップテーブル:複雑な計算処理を単純な配列の参照処理で置き換えて効率化を図るために作られた、配列や連想配列などのデータ構造のことをいう。(Wikipediaより)

 事前計算を使用するというのは割とありがたいアプローチの一つです。例えば角度からベクトルを計算したい時、角度をラジアンに変換して云々という処理を毎回じっこうせずとも、特定の要素にアクセスすれば値を得られるという形にできます。当然、値の制度は非常に低い物になるでしょうが、それが必要な場合は十分とも言えます。

// 毎回計算する場合
var rad = math.radians(angle);
var velocity = new Vector3(math.cos(rad), math.sin(rad));

// 事前計算した結果を使用する場合
var velocity = AngleToVelocity[angle]

 これをBurstでも使いたいと思いますが、一つ問題があります。Burstはマネージドメモリを使用できないという点です。そのためNativeArrayで定義する必要がありそうに見えます。これは問題ないと言えば問題ないかもしれませんが、やる場合には通常の配列を定義してNativeArrayに変換する流れが必要になってくるので、あまりイケてないように見えます。

Burstでルックアップテーブルを使おう

 先日のUniteの講演で気づいたのですが、どうやら通常のフィールドとして定義した配列を使用できる方法があるみたいです。

 利用できる条件は単純で static readonly な配列は使用できるみたいです。例えば下のように定義しておくと、Burstでも使用することが出来ました。

    public static readonly float2[] AngleToVelocity = new float2[] {
        new float2(0f, 1f),
        new float2(-0.01745241f, 0.9998477f),
        new float2(-0.0348995f, 0.9993908f),
        new float2(-0.05233596f, 0.9986295f),
       .
       .
       .

 注意点としては、BurstとC#で少し挙動が変わるという点です。C#の動作では static readonlyな配列は、中身を変更することが可能です。しかしBurstの場合は変更した中身を無視して最初に定義した数値を使用します。この問題はエディターだと分かりやすく、Burstコンパイルが完了するまでは*1値を書き換えることが可能ですが、Burstのコンパイル完了後はコードに記述した値が使用されます。

f:id:tsubaki_t1:20191011215915j:plain
定義

サンプル

角度の方向に向かってGameObjectを進めます。

using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Jobs;
using Unity.Burst;
using Unity.Jobs;
using Unity.Collections;

public class MoveByAngle : MonoBehaviour
{
    [Range(0, 359)]
    public int angle;

    [BurstCompile]
    struct MoveTransform : IJobParallelForTransform
    {
        public int angle;
        public void Execute(int index, TransformAccess transform)
        {
            var velocity2D = AngleToVelocity[angle] * 0.1f;
            transform.position += new Vector3(velocity2D.x, velocity2D.y);
        }
    }

    JobHandle handle;

    TransformAccessArray transforms;

    void OnEnable()
    {
        transforms = new TransformAccessArray(1);
        transforms.Add(transform);
    }

    void OnDisable()
    {
        handle.Complete();
        transforms.Dispose();
    }

    void Update()
    {
        handle.Complete();
        handle = new MoveTransform { angle = angle }.Schedule(transforms, handle);
        JobHandle.ScheduleBatchedJobs();
    }

    public static readonly float2[] AngleToVelocity = new float2[] {
        new float2(0f, 1f),
        new float2(-0.01745241f, 0.9998477f),
        new float2(-0.0348995f, 0.9993908f),
        new float2(-0.05233596f, 0.9986295f),
        new float2(-0.06975648f, 0.9975641f),
        new float2(-0.08715575f, 0.9961947f),
        new float2(-0.1045285f, 0.9945219f),
        new float2(-0.1218694f, 0.9925461f),
        new float2(-0.1391731f, 0.9902681f),
        new float2(-0.1564345f, 0.9876884f),
        new float2(-0.1736482f, 0.9848077f),
        new float2(-0.190809f, 0.9816272f),
        new float2(-0.2079117f, 0.9781476f),
        new float2(-0.2249511f, 0.9743701f),
        new float2(-0.2419219f, 0.9702957f),
        new float2(-0.2588191f, 0.9659258f),
        new float2(-0.2756374f, 0.9612617f),
        new float2(-0.2923717f, 0.9563047f),
        new float2(-0.309017f, 0.9510565f),
        new float2(-0.3255681f, 0.9455186f),
        new float2(-0.3420202f, 0.9396926f),
        new float2(-0.3583679f, 0.9335804f),
        new float2(-0.3746066f, 0.9271839f),
        new float2(-0.3907311f, 0.9205049f),
        new float2(-0.4067367f, 0.9135454f),
        new float2(-0.4226183f, 0.9063078f),
        new float2(-0.4383712f, 0.8987941f),
        new float2(-0.4539905f, 0.8910065f),
        new float2(-0.4694716f, 0.8829476f),
        new float2(-0.4848097f, 0.8746197f),
        new float2(-0.5f, 0.8660254f),
        new float2(-0.5150381f, 0.8571673f),
        new float2(-0.5299193f, 0.8480481f),
        new float2(-0.5446391f, 0.8386706f),
        new float2(-0.5591929f, 0.8290375f),
        new float2(-0.5735765f, 0.819152f),
        new float2(-0.5877853f, 0.809017f),
        new float2(-0.601815f, 0.7986355f),
        new float2(-0.6156614f, 0.7880108f),
        new float2(-0.6293204f, 0.7771459f),
        new float2(-0.6427876f, 0.7660444f),
        new float2(-0.6560591f, 0.7547096f),
        new float2(-0.6691306f, 0.7431449f),
        new float2(-0.6819984f, 0.7313536f),
        new float2(-0.6946583f, 0.7193398f),
        new float2(-0.7071068f, 0.7071067f),
        new float2(-0.7193398f, 0.6946583f),
        new float2(-0.7313538f, 0.6819984f),
        new float2(-0.7431449f, 0.6691306f),
        new float2(-0.7547097f, 0.656059f),
        new float2(-0.7660445f, 0.6427876f),
        new float2(-0.777146f, 0.6293204f),
        new float2(-0.7880108f, 0.6156614f),
        new float2(-0.7986355f, 0.601815f),
        new float2(-0.8090171f, 0.5877851f),
        new float2(-0.819152f, 0.5735765f),
        new float2(-0.8290376f, 0.5591928f),
        new float2(-0.8386706f, 0.544639f),
        new float2(-0.8480482f, 0.5299191f),
        new float2(-0.8571673f, 0.5150381f),
        new float2(-0.8660254f, 0.5f),
        new float2(-0.8746197f, 0.4848096f),
        new float2(-0.8829477f, 0.4694715f),
        new float2(-0.8910065f, 0.4539905f),
        new float2(-0.8987942f, 0.438371f),
        new float2(-0.9063078f, 0.4226182f),
        new float2(-0.9135455f, 0.4067366f),
        new float2(-0.9205048f, 0.3907312f),
        new float2(-0.9271839f, 0.3746065f),
        new float2(-0.9335805f, 0.3583679f),
        new float2(-0.9396927f, 0.34202f),
        new float2(-0.9455186f, 0.3255681f),
        new float2(-0.9510565f, 0.309017f),
        new float2(-0.9563048f, 0.2923716f),
        new float2(-0.9612617f, 0.2756373f),
        new float2(-0.9659258f, 0.258819f),
        new float2(-0.9702958f, 0.2419218f),
        new float2(-0.9743701f, 0.224951f),
        new float2(-0.9781476f, 0.2079117f),
        new float2(-0.9816272f, 0.190809f),
        new float2(-0.9848078f, 0.1736481f),
        new float2(-0.9876883f, 0.1564345f),
        new float2(-0.9902681f, 0.1391731f),
        new float2(-0.9925462f, 0.1218693f),
        new float2(-0.9945219f, 0.1045284f),
        new float2(-0.9961946f, 0.08715588f),
        new float2(-0.9975641f, 0.06975645f),
        new float2(-0.9986296f, 0.05233604f),
        new float2(-0.9993908f, 0.03489941f),
        new float2(-0.9998477f, 0.01745242f),
        new float2(-0.9999999f, 5.960464E-08f),
        new float2(-0.9998477f, -0.01745248f),
        new float2(-0.9993908f, -0.03489959f),
        new float2(-0.9986296f, -0.05233586f),
        new float2(-0.9975641f, -0.06975651f),
        new float2(-0.9961947f, -0.08715594f),
        new float2(-0.9945219f, -0.1045285f),
        new float2(-0.9925462f, -0.1218693f),
        new float2(-0.990268f, -0.1391732f),
        new float2(-0.9876884f, -0.1564347f),
        new float2(-0.9848078f, -0.1736484f),
        new float2(-0.9816272f, -0.1908089f),
        new float2(-0.9781476f, -0.2079117f),
        new float2(-0.97437f, -0.224951f),
        new float2(-0.9702957f, -0.241922f),
        new float2(-0.9659258f, -0.258819f),
        new float2(-0.9612617f, -0.2756375f),
        new float2(-0.9563047f, -0.2923716f),
        new float2(-0.9510565f, -0.3090172f),
        new float2(-0.9455186f, -0.3255682f),
        new float2(-0.9396927f, -0.3420202f),
        new float2(-0.9335804f, -0.3583682f),
        new float2(-0.9271838f, -0.3746067f),
        new float2(-0.9205049f, -0.3907312f),
        new float2(-0.9135454f, -0.4067367f),
        new float2(-0.9063078f, -0.4226184f),
        new float2(-0.8987939f, -0.4383713f),
        new float2(-0.8910066f, -0.4539905f),
        new float2(-0.8829476f, -0.4694716f),
        new float2(-0.8746197f, -0.4848098f),
        new float2(-0.8660254f, -0.5000001f),
        new float2(-0.8571673f, -0.515038f),
        new float2(-0.848048f, -0.5299193f),
        new float2(-0.8386706f, -0.5446391f),
        new float2(-0.8290375f, -0.559193f),
        new float2(-0.8191521f, -0.5735766f),
        new float2(-0.8090171f, -0.5877852f),
        new float2(-0.7986354f, -0.601815f),
        new float2(-0.7880107f, -0.6156617f),
        new float2(-0.777146f, -0.6293204f),
        new float2(-0.7660444f, -0.6427877f),
        new float2(-0.7547095f, -0.656059f),
        new float2(-0.7431448f, -0.6691307f),
        new float2(-0.7313538f, -0.6819984f),
        new float2(-0.7193397f, -0.6946584f),
        new float2(-0.7071068f, -0.7071067f),
        new float2(-0.6946582f, -0.7193398f),
        new float2(-0.6819984f, -0.7313538f),
        new float2(-0.6691306f, -0.7431448f),
        new float2(-0.656059f, -0.7547096f),
        new float2(-0.6427875f, -0.7660446f),
        new float2(-0.6293203f, -0.777146f),
        new float2(-0.6156614f, -0.7880107f),
        new float2(-0.6018149f, -0.7986356f),
        new float2(-0.5877852f, -0.8090171f),
        new float2(-0.5735763f, -0.8191522f),
        new float2(-0.5591928f, -0.8290377f),
        new float2(-0.544639f, -0.8386706f),
        new float2(-0.5299191f, -0.8480481f),
        new float2(-0.515038f, -0.8571672f),
        new float2(-0.5000001f, -0.8660253f),
        new float2(-0.4848095f, -0.8746197f),
        new float2(-0.4694716f, -0.8829476f),
        new float2(-0.4539904f, -0.8910065f),
        new float2(-0.4383711f, -0.8987941f),
        new float2(-0.4226183f, -0.9063078f),
        new float2(-0.4067366f, -0.9135456f),
        new float2(-0.3907309f, -0.9205049f),
        new float2(-0.3746065f, -0.9271837f),
        new float2(-0.3583679f, -0.9335804f),
        new float2(-0.34202f, -0.9396927f),
        new float2(-0.3255681f, -0.9455187f),
        new float2(-0.3090171f, -0.9510566f),
        new float2(-0.2923716f, -0.9563048f),
        new float2(-0.2756374f, -0.9612616f),
        new float2(-0.2588189f, -0.9659259f),
        new float2(-0.2419219f, -0.9702957f),
        new float2(-0.2249511f, -0.9743701f),
        new float2(-0.2079116f, -0.9781476f),
        new float2(-0.1908088f, -0.9816272f),
        new float2(-0.1736483f, -0.9848078f),
        new float2(-0.1564344f, -0.9876882f),
        new float2(-0.139173f, -0.9902682f),
        new float2(-0.1218693f, -0.9925461f),
        new float2(-0.1045285f, -0.9945219f),
        new float2(-0.08715564f, -0.9961947f),
        new float2(-0.06975647f, -0.9975641f),
        new float2(-0.05233581f, -0.9986296f),
        new float2(-0.03489945f, -0.9993908f),
        new float2(-0.01745246f, -0.9998477f),
        new float2(8.742278E-08f, -1f),
        new float2(0.01745239f, -0.9998477f),
        new float2(0.03489963f, -0.9993908f),
        new float2(0.05233599f, -0.9986296f),
        new float2(0.06975664f, -0.9975641f),
        new float2(0.08715582f, -0.9961947f),
        new float2(0.1045284f, -0.9945219f),
        new float2(0.1218695f, -0.9925461f),
        new float2(0.1391731f, -0.9902682f),
        new float2(0.1564344f, -0.9876882f),
        new float2(0.1736485f, -0.9848076f),
        new float2(0.190809f, -0.9816272f),
        new float2(0.207912f, -0.9781474f),
        new float2(0.2249513f, -0.9743699f),
        new float2(0.2419218f, -0.9702957f),
        new float2(0.2588193f, -0.9659257f),
        new float2(0.2756375f, -0.9612616f),
        new float2(0.2923715f, -0.9563048f),
        new float2(0.3090172f, -0.9510564f),
        new float2(0.3255683f, -0.9455185f),
        new float2(0.3420204f, -0.9396925f),
        new float2(0.3583681f, -0.9335804f),
        new float2(0.3746066f, -0.9271837f),
        new float2(0.3907313f, -0.9205048f),
        new float2(0.4067367f, -0.9135454f),
        new float2(0.4226183f, -0.9063078f),
        new float2(0.4383713f, -0.8987941f),
        new float2(0.4539905f, -0.8910065f),
        new float2(0.4694717f, -0.8829476f),
        new float2(0.4848097f, -0.8746197f),
        new float2(0.5f, -0.8660253f),
        new float2(0.5150382f, -0.8571672f),
        new float2(0.5299193f, -0.8480481f),
        new float2(0.5446389f, -0.8386706f),
        new float2(0.559193f, -0.8290374f),
        new float2(0.5735764f, -0.819152f),
        new float2(0.5877855f, -0.8090168f),
        new float2(0.601815f, -0.7986356f),
        new float2(0.6156614f, -0.7880108f),
        new float2(0.6293206f, -0.7771457f),
        new float2(0.6427876f, -0.7660444f),
        new float2(0.6560589f, -0.7547096f),
        new float2(0.6691308f, -0.7431448f),
        new float2(0.6819984f, -0.7313536f),
        new float2(0.6946586f, -0.7193396f),
        new float2(0.7071069f, -0.7071067f),
        new float2(0.7193398f, -0.6946584f),
        new float2(0.7313538f, -0.6819981f),
        new float2(0.7431449f, -0.6691306f),
        new float2(0.7547097f, -0.6560589f),
        new float2(0.7660446f, -0.6427875f),
        new float2(0.777146f, -0.6293204f),
        new float2(0.788011f, -0.615661f),
        new float2(0.7986357f, -0.6018147f),
        new float2(0.8090169f, -0.5877855f),
        new float2(0.8191521f, -0.5735763f),
        new float2(0.8290375f, -0.5591928f),
        new float2(0.8386708f, -0.5446388f),
        new float2(0.8480482f, -0.5299189f),
        new float2(0.8571674f, -0.515038f),
        new float2(0.8660255f, -0.5f),
        new float2(0.8746197f, -0.4848095f),
        new float2(0.8829475f, -0.4694716f),
        new float2(0.8910066f, -0.4539902f),
        new float2(0.8987941f, -0.4383709f),
        new float2(0.9063078f, -0.4226182f),
        new float2(0.9135455f, -0.4067366f),
        new float2(0.9205048f, -0.3907312f),
        new float2(0.9271839f, -0.3746064f),
        new float2(0.9335805f, -0.3583677f),
        new float2(0.9396926f, -0.34202f),
        new float2(0.9455186f, -0.3255682f),
        new float2(0.9510564f, -0.3090171f),
        new float2(0.9563048f, -0.2923715f),
        new float2(0.9612618f, -0.2756373f),
        new float2(0.9659258f, -0.258819f),
        new float2(0.9702958f, -0.2419214f),
        new float2(0.9743701f, -0.2249513f),
        new float2(0.9781476f, -0.207912f),
        new float2(0.9816273f, -0.1908089f),
        new float2(0.9848078f, -0.1736481f),
        new float2(0.9876884f, -0.1564341f),
        new float2(0.9902681f, -0.1391728f),
        new float2(0.9925462f, -0.1218692f),
        new float2(0.994522f, -0.1045284f),
        new float2(0.9961947f, -0.0871557f),
        new float2(0.997564f, -0.06975651f),
        new float2(0.9986296f, -0.05233574f),
        new float2(0.9993908f, -0.03489923f),
        new float2(0.9998477f, -0.01745224f),
        new float2(0.9999999f, 5.960464E-08f),
        new float2(0.9998477f, 0.01745224f),
        new float2(0.9993908f, 0.03489977f),
        new float2(0.9986295f, 0.05233622f),
        new float2(0.9975641f, 0.06975663f),
        new float2(0.9961947f, 0.0871557f),
        new float2(0.9945219f, 0.1045284f),
        new float2(0.9925461f, 0.1218696f),
        new float2(0.9902681f, 0.1391733f),
        new float2(0.9876884f, 0.1564345f),
        new float2(0.9848077f, 0.1736486f),
        new float2(0.9816272f, 0.190809f),
        new float2(0.9781475f, 0.207912f),
        new float2(0.97437f, 0.2249513f),
        new float2(0.9702957f, 0.241922f),
        new float2(0.9659258f, 0.2588195f),
        new float2(0.9612616f, 0.2756377f),
        new float2(0.9563048f, 0.2923715f),
        new float2(0.9510565f, 0.3090172f),
        new float2(0.9455186f, 0.3255681f),
        new float2(0.9396925f, 0.3420205f),
        new float2(0.9335804f, 0.3583682f),
        new float2(0.9271838f, 0.3746067f),
        new float2(0.9205048f, 0.3907313f),
        new float2(0.9135455f, 0.4067366f),
        new float2(0.9063078f, 0.4226182f),
        new float2(0.8987939f, 0.4383714f),
        new float2(0.8910065f, 0.4539906f),
        new float2(0.8829475f, 0.4694717f),
        new float2(0.8746198f, 0.4848096f),
        new float2(0.8660255f, 0.4999999f),
        new float2(0.8571672f, 0.5150383f),
        new float2(0.848048f, 0.5299194f),
        new float2(0.8386706f, 0.5446391f),
        new float2(0.8290375f, 0.5591929f),
        new float2(0.8191521f, 0.5735763f),
        new float2(0.8090168f, 0.5877855f),
        new float2(0.7986354f, 0.6018151f),
        new float2(0.7880107f, 0.6156615f),
        new float2(0.7771457f, 0.6293207f),
        new float2(0.7660446f, 0.6427875f),
        new float2(0.7547097f, 0.6560588f),
        new float2(0.7431448f, 0.6691307f),
        new float2(0.7313537f, 0.6819984f),
        new float2(0.7193395f, 0.6946587f),
        new float2(0.7071066f, 0.707107f),
        new float2(0.6946582f, 0.71934f),
        new float2(0.6819983f, 0.7313538f),
        new float2(0.6691306f, 0.7431449f),
        new float2(0.6560587f, 0.7547098f),
        new float2(0.6427874f, 0.7660446f),
        new float2(0.6293203f, 0.7771461f),
        new float2(0.6156614f, 0.7880108f),
        new float2(0.601815f, 0.7986355f),
        new float2(0.5877853f, 0.8090169f),
        new float2(0.5735762f, 0.8191522f),
        new float2(0.5591927f, 0.8290377f),
        new float2(0.5446389f, 0.8386706f),
        new float2(0.5299193f, 0.8480481f),
        new float2(0.5150382f, 0.8571672f),
        new float2(0.4999998f, 0.8660255f),
        new float2(0.4848095f, 0.8746198f),
        new float2(0.4694715f, 0.8829476f),
        new float2(0.4539901f, 0.8910067f),
        new float2(0.4383713f, 0.898794f),
        new float2(0.422618f, 0.9063079f)
    };
}

関連

www.youtube.com

*1:エディターでBurstを実行する場合、コンパイル完了まで通常のC#の処理が実行される