#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);
}