Compare commits

...

3 Commits

Author SHA1 Message Date
rsformoso 6d4166ed60 Implement Burst compiled importer 2026-03-18 17:05:13 +08:00
rsformoso 8ca58a1f13 Interesting cel-shaded like effect 2026-03-18 16:49:41 +08:00
rsformoso 77040b7d56 tmp 2026-03-17 17:41:49 +08:00
3 changed files with 383 additions and 99 deletions
+72
View File
@@ -133,6 +133,10 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Float.m_Array.Array.size
value: 2
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.size
value: 1
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
@@ -147,6 +151,10 @@ PrefabInstance:
propertyPath: m_PropertySheet.m_Float.m_Array.Array.data[0].m_Name
value: ScaleMultiplier
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Float.m_Array.Array.data[1].m_Name
value: OpacityMultiplier
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Uint.m_Array.Array.data[0].m_Value
value: 200000
@@ -159,6 +167,14 @@ PrefabInstance:
propertyPath: m_PropertySheet.m_Float.m_Array.Array.data[0].m_Value
value: 64
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Float.m_Array.Array.data[1].m_Value
value: 1
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Name
value: GradientScale
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Uint.m_Array.Array.data[0].m_Overridden
value: 1
@@ -171,6 +187,62 @@ PrefabInstance:
propertyPath: m_PropertySheet.m_Float.m_Array.Array.data[0].m_Overridden
value: 1
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Float.m_Array.Array.data[1].m_Overridden
value: 1
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Overridden
value: 1
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.atime0
value: 0
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.atime1
value: 65535
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.ctime0
value: 0
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.ctime1
value: 65535
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.key1.a
value: 1
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.key1.b
value: 1
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.key1.g
value: 1
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.key1.r
value: 1
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.m_Mode
value: 0
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.m_ColorSpace
value: 1
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.m_NumAlphaKeys
value: 2
objectReference: {fileID: 0}
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_PropertySheet.m_Gradient.m_Array.Array.data[0].m_Value.m_NumColorKeys
value: 2
objectReference: {fileID: 0}
- target: {fileID: -774367247743995920, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
propertyPath: m_Enabled
value: 1
+268 -58
View File
@@ -18,19 +18,12 @@ using Unity.VisualScripting;
using System.Collections;
using Unity.Collections;
using UnityEditor.Experimental.GraphView;
/*******************************************************************************
TODO:
1. Move header parsing to ParsePLYFile
2. Improve exception reporting and handling
3. Use Burst compiler for parsing binary data
4. If we can reasonably assume that items are contigious (e.g. position)
use MemoryMarshal
5. Use a struct for header_info
6. Write handler for data other than 32 bit float
7. Pass around Span<byte> instead of byte[] for memory safety
8. Implement opacity clamping in the VFX Graph
*******************************************************************************/
using UnityEngine.Playables;
using Unity.Android.Gradle.Manifest;
using UnityEngine.Timeline;
using Unity.Jobs;
using System.Xml.Schema;
using Unity.Android.Gradle;
namespace SplatVfx.Editor
{
@@ -39,16 +32,14 @@ namespace SplatVfx.Editor
public sealed class SplatImporter : ScriptedImporter
{
const float SH_C0 = 0.28209479177387814f;
const string DefaultVfxPath = "Assets/vfx-graph-gs/SplatVFX.vfx";
#region ScriptedImporter implementation
[BurstCompile]
public override void OnImportAsset(AssetImportContext context)
{
var ply = ParsePLYFile(context.assetPath);
var header_info = ParseHeader(ply.header);
var (headerString, endHeaderPosition) = GetHeader(context.assetPath);
var headerData = ParseMetadata(headerString);
var data = ImportAsSplatData(header_info, ply.binaryData);
var data = ImportData(headerData, context.assetPath, endHeaderPosition);
data.name = Path.GetFileNameWithoutExtension(context.assetPath);
context.AddObjectToAsset("data", data);
@@ -57,14 +48,7 @@ namespace SplatVfx.Editor
context.SetMainObject(prefab);
}
#endregion
#region Prefab construction
const string DefaultVfxPath = "Assets/vfx-graph-gs/SplatVFX.vfx";
[BurstCompile]
GameObject CreatePrefab(SplatData data)
private GameObject CreatePrefab(SplatData data)
{
var go = new GameObject();
var vfx = go.AddComponent<VisualEffect>();
@@ -78,12 +62,77 @@ namespace SplatVfx.Editor
return go;
}
#endregion
const int MAX_CHUNK_SIZE = 1048576 * 256; // 256MiB
#region Reader implementation
private enum TypeEnum
{
None, Float32, Float64, Float16, Int8, UInt8, Char, Short, UInt16
}
[BurstCompile]
(string header, byte[] binaryData) ParsePLYFile(string filePath)
private enum DataEnum
{
x, y, z, f_dc_0, f_dc_1, f_dc_2, f_rest_0, f_rest_1, f_rest_2,
f_rest_3, f_rest_4, f_rest_5, f_rest_6, f_rest_7, f_rest_8,
f_rest_9, f_rest_10, f_rest_11, f_rest_12, f_rest_13, f_rest_14,
f_rest_15, f_rest_16, f_rest_17, f_rest_18, f_rest_19, f_rest_20,
f_rest_21, f_rest_22, f_rest_23, f_rest_24, f_rest_25, f_rest_26,
f_rest_27, f_rest_28, f_rest_29, f_rest_30, f_rest_31, f_rest_32,
f_rest_33, f_rest_34, f_rest_35, f_rest_36, f_rest_37, f_rest_38,
f_rest_39, f_rest_40, f_rest_41, f_rest_42, f_rest_43, f_rest_44,
opacity, scale_0, scale_1, scale_2, rot_0, rot_1, rot_2, rot_3
}
/***********************************************************************
- TODO: Add support for more data types
***********************************************************************/
private static readonly Dictionary<TypeEnum, int> TypeToByteLengths =
new()
{
{ TypeEnum.Float32, 4 },
{ TypeEnum.Float64, 8 },
{ TypeEnum.Float16, 2 }, // keeping this here to support half precision floats in the future
{ TypeEnum.UInt8, 1 },
{ TypeEnum.Int8, 1 }
};
private static readonly Dictionary<string, TypeEnum> TypeMappings =
new()
{
{ "float", TypeEnum.Float32 },
{ "double", TypeEnum.Float64 },
{ "uint8", TypeEnum.UInt8 },
{ "int8", TypeEnum.Int8 }
};
/***********************************************************************
- TODO: Add endianness
- TODO: Add float size
***********************************************************************/
private struct HeaderData
{
public uint NumElements;
public uint BinaryDataStartOffset;
public NativeArray<int> ElementByteOffsets;
public NativeArray<int> ElementTypes;
public int BytesPerElement;
public HeaderData(int count)
{
NumElements = 0;
BinaryDataStartOffset = 0;
ElementByteOffsets = new NativeArray<int>(count, Allocator.Persistent);
ElementTypes = new NativeArray<int>(count, Allocator.Persistent);
BytesPerElement = 0;
}
public void Dispose()
{
ElementByteOffsets.Dispose();
ElementTypes.Dispose();
}
}
private static (string headerString, int endHeaderPosition) GetHeader(string filePath)
{
using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
using var reader = new StreamReader(fileStream);
@@ -100,58 +149,220 @@ namespace SplatVfx.Editor
}
}
long endHeaderPosition = headerBuilder.Length - headerBuilder.ToString().Split('\n').Length + 1;
fileStream.Seek(endHeaderPosition, SeekOrigin.Begin);
// Old logic that works because AppendLine adds another \n
// TODO: Fix this logic
int endHeaderPosition = headerBuilder.Length - headerBuilder.ToString().Split('\n').Length + 1;
Debug.Log($"Total filesize: {fileStream.Length}");
Debug.Log($"Byte stream start position: {endHeaderPosition}");
var binaryReader = new BinaryReader(fileStream);
var binaryData = binaryReader.ReadBytes((int)(fileStream.Length - endHeaderPosition));
return (headerBuilder.ToString(), binaryData);
return (headerBuilder.ToString(), endHeaderPosition);
}
[BurstCompile]
(string format, int num_element, List<(string, string)> properties)
ParseHeader(string header)
private static HeaderData ParseMetadata(string headerString)
{
using var reader = new StringReader(header);
HeaderData result = new(59);
string line;
string format = "";
int num_element = 0;
var properties = new List<(string, string)>();
using var reader = new StringReader(headerString);
while ((line = reader.ReadLine()) != null)
{
if (line.StartsWith("end_header"))
{
if (line.Trim() == "end_header")
break;
}
var strings = line.Split(" ");
switch (strings.FirstOrDefault())
{
case "format":
format = strings[1];
break;
case "element":
num_element = int.Parse(strings[2]);
result.NumElements = uint.Parse(strings[2]);
break;
case "property":
properties.Add((strings[2].Trim(), strings[1].Trim()));
TypeEnum dataType = TypeMappings[strings[1]];
// If in DataEnum, store byte offset and type
if (DataEnum.TryParse(strings[2], out DataEnum dataName))
{
int ix = (int)dataName;
result.ElementByteOffsets[ix] = result.BytesPerElement;
result.ElementTypes[ix] = (int)dataType;
}
result.BytesPerElement += TypeToByteLengths[dataType];
break;
}
}
Debug.Log($"Bytes per Element: {result.BytesPerElement}");
return (format, num_element, properties);
return result;
}
[BurstCompile]
private struct SplatDataNative
{
public NativeArray<float3> position;
public NativeArray<float3> color;
public NativeArray<float> sh;
public NativeArray<float> opacity;
public NativeArray<float3> scale;
public NativeArray<float4> rotation;
public SplatDataNative(int count)
{
position = new NativeArray<float3>(count, Allocator.Persistent);
color = new NativeArray<float3>(count, Allocator.Persistent);
sh = new NativeArray<float>(count * 45, Allocator.Persistent);
opacity = new NativeArray<float>(count, Allocator.Persistent);
scale = new NativeArray<float3>(count, Allocator.Persistent);
rotation = new NativeArray<float4>(count, Allocator.Persistent);
}
public void Dispose()
{
position.Dispose();
color.Dispose();
sh.Dispose();
opacity.Dispose();
scale.Dispose();
rotation.Dispose();
}
}
private static SplatData ImportData(HeaderData headerData, string filePath, int endHeaderPosition)
{
var splatData = ScriptableObject.CreateInstance<SplatData>();
splatData.PositionArray = new Vector3[headerData.NumElements];
splatData.ScaleArray = new Vector3[headerData.NumElements];
splatData.RotationArray = new Quaternion[headerData.NumElements];
splatData.ColorArray = new Color[headerData.NumElements];
splatData.OpacityArray = new float[headerData.NumElements];
splatData.SHArray = new float[headerData.NumElements * 45];
int elementsPerChunk = Mathf.Min(
MAX_CHUNK_SIZE / headerData.BytesPerElement,
(int)headerData.NumElements
);
int chunkSize = elementsPerChunk * headerData.BytesPerElement;
Debug.Log($"Elements per chunk: {elementsPerChunk}");
Debug.Log($"Chunk size: {chunkSize}");
using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
fileStream.Seek(endHeaderPosition, SeekOrigin.Begin);
int totalBytes = (int)fileStream.Length - endHeaderPosition;
Debug.Log($"Total bytes: {totalBytes}");
var splatDataNative = new SplatDataNative(elementsPerChunk);
var chunkBuffer = new NativeArray<byte>(chunkSize, Allocator.Persistent);
var chunkBufferSpan = MemoryMarshal.AsBytes<byte>(chunkBuffer);
int numBytesRead;
int numElemsRead;
int totalElemsRead = 0;
while ((numBytesRead = fileStream.Read(chunkBufferSpan)) > 0)
{
numElemsRead = numBytesRead / headerData.BytesPerElement;
var splatElementJob = new SplatElementJob
{
chunkBytes = chunkBuffer,
splatDataNative = splatDataNative,
headerData = headerData,
totalElemsRead = totalElemsRead,
numElemsRead = numElemsRead
};
splatElementJob.Schedule().Complete();
for (int i = 0; i < numElemsRead; i++)
{
splatData.PositionArray[totalElemsRead + i] = splatDataNative.position[i];
splatData.ColorArray[totalElemsRead + i].r = splatDataNative.color[i].x;
splatData.ColorArray[totalElemsRead + i].g = splatDataNative.color[i].y;
splatData.ColorArray[totalElemsRead + i].b = splatDataNative.color[i].z;
splatData.OpacityArray[totalElemsRead + i] = splatDataNative.opacity[i];
splatData.ScaleArray[totalElemsRead + i] = splatDataNative.scale[i];
splatData.RotationArray[totalElemsRead + i] = new quaternion(splatDataNative.rotation[i]);
}
totalElemsRead += numElemsRead;
Debug.Log($"Current Elements Read: {totalElemsRead}");
}
Debug.Log($"First position Vector3: {splatData.PositionArray[0]}");
headerData.Dispose();
splatDataNative.Dispose();
chunkBuffer.Dispose();
splatData.ReleaseGpuResources();
return splatData;
}
[BurstCompile]
private struct SplatElementJob : IJob
{
public NativeArray<byte> chunkBytes;
public SplatDataNative splatDataNative;
[ReadOnly] public HeaderData headerData;
[ReadOnly] public int totalElemsRead;
[ReadOnly] public int numElemsRead;
public void Execute()
{
for (int i = 0; i < numElemsRead; i++)
{
int elemIx = i;
int start = elemIx * headerData.BytesPerElement;
splatDataNative.position[elemIx] = new()
{
x = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.x]),
y = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.y]),
z = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.z])
};
float3 color = new()
{
x = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.f_dc_0]),
y = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.f_dc_1]),
z = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.f_dc_2])
};
color = 0.5f + color * SH_C0;
splatDataNative.color[elemIx] = color;
for (int j = 0; j < 45; j++)
{
splatDataNative.sh[elemIx + j] = chunkBytes[start + headerData.ElementByteOffsets[(int)DataEnum.f_rest_0 + j]];
}
float opacity = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.opacity]);
opacity = 1 / (1 + math.exp(-opacity));
splatDataNative.opacity[elemIx] = opacity;
float3 scale = new()
{
x = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.scale_0]),
y = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.scale_1]),
z = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.scale_2])
};
scale = math.exp(scale);
splatDataNative.scale[elemIx] = scale;
splatDataNative.rotation[elemIx] = new()
{
w = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.rot_0]),
x = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.rot_1]),
y = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.rot_2]),
z = chunkBytes.ReinterpretLoad<float>(start + headerData.ElementByteOffsets[(int)DataEnum.rot_3])
};
}
}
}
SplatData ImportAsSplatData((string format, int num_element, List<(string, string)> properties) header_info, byte[] binaryData)
{
var splatData = ScriptableObject.CreateInstance<SplatData>();
@@ -322,7 +533,6 @@ namespace SplatVfx.Editor
// color = (Vector4)math.float4(src.r, src.g, src.b, src.a) / 255;
// }
#endregion
}
} // namespace SplatVfx.Editor
}
+43 -41
View File
@@ -209,7 +209,7 @@ MonoBehaviour:
x: -692
y: -492
width: 1846
height: 2501
height: 2502
--- !u!114 &114350483966674976
MonoBehaviour:
m_ObjectHideFlags: 1
@@ -797,7 +797,7 @@ MonoBehaviour:
m_UICollapsed: 0
m_UISuperCollapsed: 0
m_InputSlots:
- {fileID: 8926484042661618395}
- {fileID: 8926484042661619458}
- {fileID: 8926484042661614618}
m_OutputSlots: []
m_Label:
@@ -6171,7 +6171,9 @@ MonoBehaviour:
- m_Id: 0
linkedSlots:
- outputSlot: {fileID: 8926484042661618390}
inputSlot: {fileID: 8926484042661618395}
inputSlot: {fileID: 0}
- outputSlot: {fileID: 8926484042661618390}
inputSlot: {fileID: 8926484042661619458}
position: {x: 533, y: 1299}
expandedSlots: []
expanded: 1
@@ -6210,42 +6212,7 @@ MonoBehaviour:
Culture=neutral, PublicKeyToken=null
m_Direction: 1
m_LinkedSlots:
- {fileID: 8926484042661618395}
--- !u!114 &8926484042661618395
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 76f778ff57c4e8145b9681fe3268d8e9, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.VisualEffectGraph.Editor::UnityEditor.VFX.VFXSlotGradient
m_UIIgnoredErrors: []
m_Parent: {fileID: 0}
m_Children: []
m_UIPosition: {x: 0, y: 0}
m_UICollapsed: 1
m_UISuperCollapsed: 0
m_MasterSlot: {fileID: 8926484042661618395}
m_MasterData:
m_Owner: {fileID: 8926484042661614617}
m_Value:
m_Type:
m_SerializableType: UnityEngine.Gradient, UnityEngine.CoreModule, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
m_SerializableObject: '{"colorKeys":[{"color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0},"time":0.0},{"color":{"r":0.75,"g":0.15000000596046449,"b":0.0,"a":1.0},"time":0.3000076413154602},{"color":{"r":1.25,"g":0.5600000023841858,"b":0.11999999731779099,"a":1.0},"time":0.5000076293945313},{"color":{"r":3.5,"g":2.0,"b":0.5,"a":1.0},"time":0.7000076174736023},{"color":{"r":4.0,"g":3.5,"b":1.2000000476837159,"a":1.0},"time":0.9000076055526733},{"color":{"r":12.0,"g":10.0,"b":2.5,"a":1.0},"time":1.0}],"alphaKeys":[{"alpha":0.0,"time":0.0},{"alpha":1.0,"time":1.0}],"gradientMode":0}'
m_Space: -1
m_Property:
name: gradient
m_serializedType:
m_SerializableType: UnityEngine.Gradient, UnityEngine.CoreModule, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
m_Direction: 0
m_LinkedSlots:
- {fileID: 8926484042661618390}
- {fileID: 8926484042661619458}
--- !u!114 &8926484042661618746
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -13741,7 +13708,7 @@ MonoBehaviour:
m_Parent: {fileID: 114350483966674976}
m_Children:
- {fileID: 8926484042661619332}
m_UIPosition: {x: 705, y: 700}
m_UIPosition: {x: 705, y: 741}
m_UICollapsed: 0
m_UISuperCollapsed: 0
m_InputSlots: []
@@ -16773,7 +16740,7 @@ MonoBehaviour:
m_Type:
m_SerializableType: System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
m_SerializableObject: True
m_SerializableObject: False
m_Space: -1
m_Property:
name: _vfx_enabled
@@ -16782,3 +16749,38 @@ MonoBehaviour:
PublicKeyToken=b77a5c561934e089
m_Direction: 0
m_LinkedSlots: []
--- !u!114 &8926484042661619458
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 76f778ff57c4e8145b9681fe3268d8e9, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.VisualEffectGraph.Editor::UnityEditor.VFX.VFXSlotGradient
m_UIIgnoredErrors: []
m_Parent: {fileID: 0}
m_Children: []
m_UIPosition: {x: 0, y: 0}
m_UICollapsed: 1
m_UISuperCollapsed: 0
m_MasterSlot: {fileID: 8926484042661619458}
m_MasterData:
m_Owner: {fileID: 8926484042661614617}
m_Value:
m_Type:
m_SerializableType: UnityEngine.Gradient, UnityEngine.CoreModule, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
m_SerializableObject: '{"colorKeys":[{"color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0},"time":0.0},{"color":{"r":0.75,"g":0.15000000596046449,"b":0.0,"a":1.0},"time":0.3000076413154602},{"color":{"r":1.25,"g":0.5600000023841858,"b":0.11999999731779099,"a":1.0},"time":0.5000076293945313},{"color":{"r":3.5,"g":2.0,"b":0.5,"a":1.0},"time":0.7000076174736023},{"color":{"r":4.0,"g":3.5,"b":1.2000000476837159,"a":1.0},"time":0.9000076055526733},{"color":{"r":12.0,"g":10.0,"b":2.5,"a":1.0},"time":1.0}],"alphaKeys":[{"alpha":0.0,"time":0.0},{"alpha":1.0,"time":1.0}],"gradientMode":0}'
m_Space: -1
m_Property:
name: gradient
m_serializedType:
m_SerializableType: UnityEngine.Gradient, UnityEngine.CoreModule, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
m_Direction: 0
m_LinkedSlots:
- {fileID: 8926484042661618390}