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.
 
 
 
 
 

132 lines
4.7 KiB

using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.VFX.Block
{
class PositionSDFDeprecated : PositionBase
{
public override string name => "Set Position (Signed Distance Field)";
public class InputProperties
{
[Tooltip("Sets the Signed Distance Field to sample from.")]
public Texture3D SDF = VFXResources.defaultResources.signedDistanceField;
[Tooltip("Sets the transform with which to position, scale, or rotate the field.")]
public OrientedBox FieldTransform = OrientedBox.defaultValue;
}
public class CustomProperties
{
[Range(0, 1), Tooltip("When using customized emission, control the position around the arc to emit particles from.")]
public float ArcSequencer = 0.0f;
}
protected override bool needDirectionWrite { get { return true; } }
[VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), Tooltip("Specifies whether we want to kill particles whose position is off the desired surface or volume")]
public bool killOutliers = false;
[VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), Tooltip("Specifies the number of steps used by the block to project the particle on the surface of the SDF. This can impact performance, but can yield less outliers. "), Min(1u)]
public uint projectionSteps = 2u;
public override IEnumerable<VFXAttributeInfo> attributes
{
get
{
foreach (var attrib in base.attributes)
{
yield return attrib;
}
if (killOutliers)
yield return new VFXAttributeInfo(VFXAttribute.Alive, VFXAttributeMode.Write);
}
}
// Not used anymore so remove implementation due to LinQ usage
public override IEnumerable<VFXNamedExpression> parameters
{
get
{
throw new NotImplementedException();
}
}
public override string source
{
get
{
string outSource = @"float cosPhi = 2.0f * RAND - 1.0f;";
if (spawnMode == SpawnMode.Random)
outSource += @"float theta = TWO_PI * RAND;";
else
outSource += @"float theta = TWO_PI * ArcSequencer;";
switch (positionMode)
{
case (PositionMode.Surface):
outSource += @" float Thickness = 0.0f;";
break;
case (PositionMode.Volume):
outSource += @" float Thickness = scalingFactor;";
break;
case (PositionMode.ThicknessRelative):
outSource += @" Thickness *= scalingFactor * 0.5f;";
break;
}
outSource += @"
//Initialize position within texture bounds
float2 sincosTheta;
sincos(theta, sincosTheta.x, sincosTheta.y);
sincosTheta *= sqrt(1.0f - cosPhi * cosPhi);
direction = float3(sincosTheta, cosPhi) * sqrt(3)/2;
float maxDir = max(0.5f, max(abs(direction.x), max(abs(direction.y), abs(direction.z))));
direction = direction * (projectionRayWithMargin/maxDir);
float3 tPos = direction * pow(RAND, 1.0f/3.0f);
float3 coord = tPos + 0.5f;
float3 wPos, n, worldNormal;
for(uint proj_step=0; proj_step < n_steps; proj_step++){
float dist = SampleSDF(SDF, coord);
n = -normalize(SampleSDFDerivativesFast(SDF, coord, dist));
dist *= scalingFactor;
//Projection on surface/volume
float3 delta;
worldNormal = VFXSafeNormalize(mul(float4(n, 0), InvFieldTransform).xyz);
if (dist > 0)
delta = dist * worldNormal;
else
{
delta = min(dist + Thickness, 0) * worldNormal;
}
wPos = mul(FieldTransform, float4(tPos,1)).xyz + delta;
tPos = mul(InvFieldTransform, float4(wPos,1)).xyz;
coord = tPos + 0.5f;
}
position = wPos;
direction = -worldNormal;
";
if (killOutliers)
{
outSource += @"
float dist = SampleSDF(SDF, coord);
if (dist * scalingFactor > 0.01)
alive = false;
";
}
return outSource;
}
}
public override void Sanitize(int version)
{
var newPositionShape = ScriptableObject.CreateInstance<PositionShape>();
SanitizeHelper.MigrateBlockPositionToComposed(GetGraph(), GetParent().position, newPositionShape, this, PositionShapeBase.Type.SignedDistanceField);
ReplaceModel(newPositionShape, this);
}
}
}