(Unity) Как преобразовать данные (Vector3 и Color32) в текстуры для рендеринга?

#unity3d #particle-system #render-to-texture

#unity-игровой движок #система частиц #рендеринг в текстуру

Вопрос:

С недавним внедрением VFX Graph карты атрибутов используются для «задания положения / цвета на карте».

Чтобы получить карту атрибутов, необходимо преобразовать данные о местоположении и цвете в текстуры для рендеринга. Но я не смог найти ни одной ссылки на то, как это сделать, ни даже в документах Unity.

Любая помощь о том, как это сделать, будет оценена!

Комментарии:

1. Я ничего не знаю о графике VFX, но обработка текстур обычно заключается в создании нового Texture2D и использовании setColor( ) для заполнения деталей. Не забудьте применить ()

Ответ №1:

В большинстве случаев вы хотели бы использовать вычислительный шейдер для преобразования списка точек в ваши текстуры. Я бы посоветовал вам проверить эти репозитории для справки:

Преобразовать данные средства рендеринга сетки в текстурыhttps://github.com/keijiro/Smrvfx

Преобразовать данные Kinect в текстуры https://github.com/roelkok/Kinect-VFX-Graph

Преобразовать данные pointcloud в текстуру: https://github.com/keijiro/Pcx

Лично я использую эти скрипты, которые работают для моих целей, хотя я не эксперт в вычислительных шейдерах:

 public class FramePositionBaker
{


ComputeShader bakerShader;

RenderTexture VFXpositionMap;

RenderTexture inputPositionTexture;

private ComputeBuffer positionBuffer;

const int texSize = 256;

public FramePositionBaker(RenderTexture _VFXPositionMap)
{

    inputPositionTexture = new RenderTexture(texSize, texSize, 0, RenderTextureFormat.ARGBFloat);

    inputPositionTexture.enableRandomWrite = true;

    inputPositionTexture.Create();

    bakerShader = (ComputeShader)Resources.Load("FramePositionBaker");

    if (bakerShader == null)
    {
        Debug.LogError("[FramePositionBaker] baking shader not found in any Resources folder");
    }

    VFXpositionMap = _VFXPositionMap;

}



public void BakeFrame(ref Vector3[] vertices)
{

    int pointCount = vertices.Length;

    positionBuffer = new ComputeBuffer(pointCount, 3 * sizeof(float));

    positionBuffer.SetData(vertices);

    //Debug.Log("Length "   vertices.Length);

    bakerShader.SetInt("dim", texSize);

    bakerShader.SetTexture(0, "PositionTexture", inputPositionTexture);

    bakerShader.SetBuffer(0, "PositionBuffer", positionBuffer);

    bakerShader.Dispatch(0, (texSize / 8)   1, (texSize / 8)   1, 1);

    Graphics.CopyTexture(inputPositionTexture, VFXpositionMap);

    positionBuffer.Dispose();


}

}
  

Вычислительный шейдер:

 // Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain

// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
RWTexture2D<float4> PositionTexture;

uint dim;

Buffer<float3> PositionBuffer;

[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
// TODO: insert actual code here!

uint index = id.y * dim   id.x;

uint lastIndex = PositionBuffer.Length - 1;

// Trick for generating a pseudo-random number.
// Inspired by a similar trick in Keijiro's PCX repo (BakedPointCloud.cs). 
// The points that are in excess because of the square texture, point randomly to a point in the texture.
// e.g. if (index > lastIndex) index = 0 generates excessive particles in the first position, resulting in a visible artifact.

//if (index > lastIndex) index = ( index * 132049U ) % lastIndex;

float3 pos;

if (index > lastIndex amp;amp; lastIndex != 0) {

    //pos = 0;
    index = ( index * 132049U ) % lastIndex;
}


    pos = PositionBuffer[index];

PositionTexture[id.xy] = float4 (pos.x, pos.y, pos.z, 1);
}