You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

115 lines
4.9 KiB

using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;
namespace UnityEditor.VFX
{
interface IVFXMultiMeshOutput
{
uint meshCount { get; }
}
static class VFXMultiMeshHelper
{
private const string meshName = "mesh";
private const string maskName = "subMeshMask";
private const string indirectIndexName = "indirectIndex";
public const string lodName = "lodValues";
private const string bufferName = "indirectBuffer";
private static readonly Vector4 lodFactors = new Vector4(8.0f, 4.0f, 2.0f, 0.1f);
private static string GetId(uint meshCount, int index)
{
if (meshCount > 1)
return index.ToString();
return string.Empty;
}
public static IEnumerable<VFXPropertyWithValue> GetInputProperties(uint meshCount, VFXOutputUpdate.Features features)
{
for (int i = 0; i < meshCount; ++i)
{
string id = GetId(meshCount, i);
yield return new VFXPropertyWithValue(new VFXProperty(typeof(Mesh), meshName + id, new TooltipAttribute("Specifies the mesh" + id + " used to render the particle.")), VFXResources.defaultResources.mesh);
yield return new VFXPropertyWithValue(new VFXProperty(typeof(uint), maskName + id, new TooltipAttribute("Defines a bitmask to control which submeshes are rendered for mesh" + id + "."), new BitFieldAttribute()), 0xffffffff);
}
if (VFXOutputUpdate.HasFeature(features, VFXOutputUpdate.Features.LOD))
yield return new VFXPropertyWithValue(new VFXProperty(typeof(Vector4), lodName, new TooltipAttribute("Specifies the minimum screen ratio for a LOD mesh to be used (e.g. a value of 25 means the mesh has to occupy 25% of the screen on 1 dimension).")), lodFactors);
if (VFXOutputUpdate.HasFeature(features, VFXOutputUpdate.Features.LOD)
|| VFXOutputUpdate.HasFeature(features, VFXOutputUpdate.Features.FrustumCulling))
yield return new VFXPropertyWithValue(new VFXProperty(typeof(float), "radiusScale", new MinAttribute(0.0f), new TooltipAttribute("Specifies a scale to apply to the radius of the bounding sphere used for LOD and frustum culling. By default the bounding sphere is encompassing a mesh bounding box of side 1.")), 1.0f);
}
public static IEnumerable<string> GetCPUExpressionNames(uint meshCount)
{
for (int i = 0; i < meshCount; ++i)
{
foreach (var name in GetCPUExpressionNames(meshCount, i))
{
yield return name;
}
}
}
public static IEnumerable<string> GetCPUExpressionNames(uint meshCount, int meshIndex)
{
string id = GetId(meshCount, meshIndex);
yield return meshName + id;
yield return maskName + id;
}
public static IEnumerable<VFXMapping> PatchCPUMapping(IEnumerable<VFXMapping> mappings, uint meshCount, int index)
{
string id = GetId(meshCount, index);
foreach (var m in mappings)
{
if (m.name.StartsWith(meshName))
{
if (m.name == meshName + id)
yield return new VFXMapping(meshName, m.index);
}
else if (m.name.StartsWith(maskName))
{
if (m.name == maskName + id)
yield return new VFXMapping(maskName, m.index);
}
else if (m.name == indirectIndexName)
yield return new VFXMapping(indirectIndexName, m.index + index);
else
yield return m;
}
}
public static IEnumerable<VFXMapping> PatchBufferMapping(IEnumerable<VFXMapping> mappings, int bufferIndex)
{
foreach (var m in mappings)
{
if (m.name == bufferName)
yield return new VFXMapping(bufferName, m.index + bufferIndex);
else
yield return m;
}
}
public static void PatchInstancingSplitValues(List<uint> instancingSplitDescValues, VFXExpressionGraph expressionGraph, ReadOnlyCollection<VFXSlot> inputSlots, uint meshCount, int meshIndex)
{
foreach (var name in GetCPUExpressionNames(meshCount, meshIndex))
{
var exp = inputSlots.First(s => s.name == name).GetExpression();
if (exp != null && !exp.IsAny(VFXExpression.Flags.Constant))
{
int index = expressionGraph.GetFlattenedIndex(exp);
if (index >= 0)
{
instancingSplitDescValues.Add((uint)index);
}
}
}
}
}
}