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.
164 lines
7.8 KiB
164 lines
7.8 KiB
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
namespace UnityEditor.VFX
|
|
{
|
|
[VFXInfo(name = "Output ParticleStrip|Unlit|Quad", category = "#3Output Strip", experimental = true, synonyms = new []{ "Trail", "Ribbon" })]
|
|
class VFXQuadStripOutput : VFXShaderGraphParticleOutput
|
|
{
|
|
internal const string WriteToPositionMessage = "Writing to Position attribute in a strip output can produce unexpected behavior";
|
|
|
|
[VFXSetting, SerializeField, Tooltip("Specifies the way the UVs are interpolated along the strip. They can either be stretched or repeated per segment.")]
|
|
protected StripTilingMode tilingMode = StripTilingMode.Stretch;
|
|
|
|
[VFXSetting, SerializeField, Tooltip("When enabled, uvs for the strips are swapped.")]
|
|
protected bool swapUV = false;
|
|
|
|
// Deprecated
|
|
[VFXSetting(VFXSettingAttribute.VisibleFlags.None), SerializeField, Tooltip("When enabled, the axisZ attribute is used to orient the strip instead of facing the Camera.")]
|
|
private bool UseCustomZAxis = false;
|
|
|
|
protected VFXQuadStripOutput() : base(true) { }
|
|
|
|
public override string name => "Output ParticleStrip".AppendLabel("Unlit", false) + "\nQuad";
|
|
public override string codeGeneratorTemplate { get { return RenderPipeTemplate("VFXParticlePlanarPrimitive"); } }
|
|
public override VFXTaskType taskType { get { return VFXTaskType.ParticleQuadOutput; } }
|
|
public override bool supportsUV { get { return true; } }
|
|
public override bool implementsMotionVector { get { return true; } }
|
|
|
|
protected IEnumerable<VFXPropertyWithValue> optionalInputProperties
|
|
{
|
|
get
|
|
{
|
|
yield return new VFXPropertyWithValue(new VFXProperty(GetFlipbookType(), "mainTexture", new TooltipAttribute("Specifies the base color (RGB) and opacity (A) of the particle.")), (usesFlipbook ? null : VFXResources.defaultResources.particleTexture));
|
|
}
|
|
}
|
|
|
|
public class CustomUVInputProperties
|
|
{
|
|
[Tooltip("Specifies the texture coordinate value (u or v depending on swap UV being enabled) used along the strip.")]
|
|
public float texCoord = 0.0f;
|
|
}
|
|
|
|
protected override IEnumerable<VFXPropertyWithValue> inputProperties
|
|
{
|
|
get
|
|
{
|
|
IEnumerable<VFXPropertyWithValue> properties = base.inputProperties;
|
|
if (GetOrRefreshShaderGraphObject() == null)
|
|
properties = properties.Concat(optionalInputProperties);
|
|
if (tilingMode == StripTilingMode.Custom)
|
|
properties = properties.Concat(PropertiesFromType("CustomUVInputProperties"));
|
|
return properties;
|
|
}
|
|
}
|
|
|
|
protected override IEnumerable<VFXNamedExpression> CollectGPUExpressions(IEnumerable<VFXNamedExpression> slotExpressions)
|
|
{
|
|
foreach (var exp in base.CollectGPUExpressions(slotExpressions))
|
|
yield return exp;
|
|
|
|
if (GetOrRefreshShaderGraphObject() == null)
|
|
yield return slotExpressions.First(o => o.name == "mainTexture");
|
|
if (tilingMode == StripTilingMode.Custom)
|
|
yield return slotExpressions.First(o => o.name == "texCoord");
|
|
}
|
|
|
|
public override IEnumerable<VFXAttributeInfo> attributes
|
|
{
|
|
get
|
|
{
|
|
yield return new VFXAttributeInfo(VFXAttribute.Position, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.Color, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.Alpha, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.AxisX, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.AxisY, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.AxisZ, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.AngleX, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.AngleY, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.AngleZ, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.PivotX, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.PivotY, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.PivotZ, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.Size, VFXAttributeMode.Read);
|
|
yield return new VFXAttributeInfo(VFXAttribute.ScaleY, VFXAttributeMode.Read);
|
|
|
|
foreach (var attribute in flipbookAttributes)
|
|
yield return attribute;
|
|
}
|
|
}
|
|
|
|
|
|
public override IEnumerable<string> additionalDefines
|
|
{
|
|
get
|
|
{
|
|
foreach (var def in base.additionalDefines)
|
|
yield return def;
|
|
|
|
if (tilingMode == StripTilingMode.Stretch)
|
|
yield return "VFX_STRIPS_UV_STRECHED";
|
|
else if (tilingMode == StripTilingMode.RepeatPerSegment)
|
|
yield return "VFX_STRIPS_UV_PER_SEGMENT";
|
|
|
|
if (swapUV)
|
|
yield return "VFX_STRIPS_SWAP_UV";
|
|
|
|
yield return VFXPlanarPrimitiveHelper.GetShaderDefine(VFXPrimitiveType.Quad);
|
|
}
|
|
}
|
|
|
|
public static void SanitizeOrient(VFXContext model, int version, bool useCustomZAxis)
|
|
{
|
|
if (version < 6)
|
|
{
|
|
Block.Orient orientBlock = model.children.OfType<Block.Orient>().FirstOrDefault();
|
|
if (orientBlock == null) // If no orient block, add one
|
|
{
|
|
Debug.Log("Sanitize Graph: Add Orient block to quad strip output");
|
|
|
|
orientBlock = CreateInstance<Block.Orient>();
|
|
if (useCustomZAxis)
|
|
{
|
|
orientBlock.SetSettingValue("mode", Block.Orient.Mode.CustomZ);
|
|
|
|
var axisZNode = CreateInstance<VFXAttributeParameter>();
|
|
axisZNode.SetSettingValue("attribute", "axisZ");
|
|
axisZNode.position = model.position + new Vector2(-225, 150);
|
|
model.GetGraph().AddChild(axisZNode);
|
|
|
|
axisZNode.GetOutputSlot(0).Link(orientBlock.GetInputSlot(0));
|
|
}
|
|
else
|
|
orientBlock.SetSettingValue("mode", Block.Orient.Mode.FaceCameraPosition);
|
|
|
|
model.AddChild(orientBlock, 0);
|
|
}
|
|
else
|
|
{
|
|
if ((Block.Orient.Mode)orientBlock.GetSettingValue("mode") == Block.Orient.Mode.FaceCameraPlane)
|
|
{
|
|
Debug.Log("Sanitize Graph: Change Orient block mode in quad strip output from \"Face Camera Plane\" to \"Face Camera Position\"");
|
|
orientBlock.SetSettingValue("mode", Block.Orient.Mode.FaceCameraPosition);
|
|
}
|
|
// Other invalid modes (Along Velocity and FixedAxis) will fail and require manual fixing
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void Sanitize(int version)
|
|
{
|
|
SanitizeOrient(this, version, UseCustomZAxis);
|
|
base.Sanitize(version);
|
|
}
|
|
|
|
internal sealed override void GenerateErrors(VFXErrorReporter report)
|
|
{
|
|
if (GetAttributesInfos().Any(x => x.mode.HasFlag(VFXAttributeMode.Write) && x.attrib.Equals(VFXAttribute.Position)))
|
|
{
|
|
report.RegisterError("WritePositionInStrip", VFXErrorType.Warning, WriteToPositionMessage, this);
|
|
}
|
|
}
|
|
}
|
|
}
|