はじめに
初投稿です。
まずGraphics.DrawMeshInstancedProceduralで色の異なるメッシュを大量に表示したいと思いました。
material.SetBuffer()でMaterialにNativeArrayで大量の色を送るにはfloat4でもいいですが、計算コストおよびメモリ消費削減のためにもColor32のまま送る方法を考えました。既出でしたらすみません。
目次
結論
先に結論です。
細かくは説明しませんが、前もって計算しておいたNativeArrayからColor32をとりあえずそのまま送ります。
NativeArray<Color32> ColorsArray;
Material material;
var target = GraphicsBuffer.Target.IndirectArguments;
var colorsBuffer = new GraphicsBuffer(target, ColorsArray.Length, 4);//Color32 なので32bit=4byte
colorsBuffer.SetData(ColorsArray);
material.SetBuffer("colorsBuffer", colorsBuffer);
hlslにColor32はなさそうなので、同じ32bitの型で受け取ります。
uintで受け取ることで、以下のようにfloat4に恐らく高速で0~1のfloat4に置き換えられます。
StructuredBuffer<uint> colorsBuffer;
inline float4 uintToColor(uint u){ //vertでconst uint u=colorsBuffer[instanceID];
const uint b=255; // o.color =uintToColor(u) のように使う
return float4(u & b,u>>8 & b, u>>16 & b, u>>24)/255;
}
解説
SetBufferは型を判断しないので、同じ大きさ(byte)なら受け取ることができます。
そこから4つのbyteを取り出したいですが、byteもcharもないし、そもそもポインタがいります。
そこで、bit演算を行って4つのuintとして取り出します。
uintの中の下8桁に対応するビットを取り出すには11111111(2)=255(10)をand演算&をすれば、
上の24桁が0になるので、0~255までの値が取り出せます。
あとはシフト演算>>で桁を落としてから同様にすれば良いだけですが、
気を付けるべきはメモリの順番で、例えば00010011(2)はメモリでは11001000のように並んでいるので、
下8桁がStructLayoutで最初に並んだ r です。
こうしてあとはfloatにキャストして255で割れば上のuintToColorのように0~1のfloat4にできます。
よりよい方法があればコメントお願いします。