Interesting cel-shaded like effect
This commit is contained in:
@@ -157,7 +157,7 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
|
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
|
||||||
propertyPath: m_PropertySheet.m_Float.m_Array.Array.data[0].m_Value
|
propertyPath: m_PropertySheet.m_Float.m_Array.Array.data[0].m_Value
|
||||||
value: 64
|
value: 32
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
|
- target: {fileID: -973084862543737302, guid: 25c54d8c074f08447ab1c822a6a052fa, type: 3}
|
||||||
propertyPath: m_PropertySheet.m_Uint.m_Array.Array.data[0].m_Overridden
|
propertyPath: m_PropertySheet.m_Uint.m_Array.Array.data[0].m_Overridden
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ using UnityEngine.Playables;
|
|||||||
using Unity.Android.Gradle.Manifest;
|
using Unity.Android.Gradle.Manifest;
|
||||||
using UnityEngine.Timeline;
|
using UnityEngine.Timeline;
|
||||||
using Unity.Jobs;
|
using Unity.Jobs;
|
||||||
|
using System.Xml.Schema;
|
||||||
|
using Unity.Android.Gradle;
|
||||||
|
|
||||||
namespace SplatVfx.Editor
|
namespace SplatVfx.Editor
|
||||||
{
|
{
|
||||||
@@ -110,9 +112,24 @@ namespace SplatVfx.Editor
|
|||||||
{
|
{
|
||||||
public uint NumElements;
|
public uint NumElements;
|
||||||
public uint BinaryDataStartOffset;
|
public uint BinaryDataStartOffset;
|
||||||
public int[] ElementByteOffsets;
|
public NativeArray<int> ElementByteOffsets;
|
||||||
public TypeEnum[] ElementTypes;
|
public NativeArray<int> ElementTypes;
|
||||||
public int BytesPerElement;
|
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)
|
private static (string headerString, int endHeaderPosition) GetHeader(string filePath)
|
||||||
@@ -133,20 +150,19 @@ namespace SplatVfx.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Old logic that works because AppendLine adds another \n
|
// Old logic that works because AppendLine adds another \n
|
||||||
// TODO: Fix this logic. Start with using Append instead of AppendLine
|
// TODO: Fix this logic
|
||||||
int endHeaderPosition = headerBuilder.Length - headerBuilder.ToString().Split('\n').Length + 1;
|
int endHeaderPosition = headerBuilder.Length - headerBuilder.ToString().Split('\n').Length + 1;
|
||||||
|
Debug.Log($"Total filesize: {fileStream.Length}");
|
||||||
|
Debug.Log($"Byte stream start position: {endHeaderPosition}");
|
||||||
|
|
||||||
return (headerBuilder.ToString(), endHeaderPosition);
|
return (headerBuilder.ToString(), endHeaderPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HeaderData ParseMetadata(string headerString)
|
private static HeaderData ParseMetadata(string headerString)
|
||||||
{
|
{
|
||||||
HeaderData result = new();
|
HeaderData result = new(59);
|
||||||
string line;
|
string line;
|
||||||
|
|
||||||
result.ElementByteOffsets = new int[59];
|
|
||||||
result.ElementTypes = new TypeEnum[59];
|
|
||||||
|
|
||||||
using var reader = new StringReader(headerString);
|
using var reader = new StringReader(headerString);
|
||||||
|
|
||||||
while ((line = reader.ReadLine()) != null)
|
while ((line = reader.ReadLine()) != null)
|
||||||
@@ -170,13 +186,14 @@ namespace SplatVfx.Editor
|
|||||||
{
|
{
|
||||||
int ix = (int)dataName;
|
int ix = (int)dataName;
|
||||||
result.ElementByteOffsets[ix] = result.BytesPerElement;
|
result.ElementByteOffsets[ix] = result.BytesPerElement;
|
||||||
result.ElementTypes[ix] = dataType;
|
result.ElementTypes[ix] = (int)dataType;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.BytesPerElement += TypeToByteLengths[dataType];
|
result.BytesPerElement += TypeToByteLengths[dataType];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Debug.Log($"Bytes per Element: {result.BytesPerElement}");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -184,21 +201,21 @@ namespace SplatVfx.Editor
|
|||||||
[BurstCompile]
|
[BurstCompile]
|
||||||
private struct SplatDataNative
|
private struct SplatDataNative
|
||||||
{
|
{
|
||||||
NativeArray<float3> position;
|
public NativeArray<float3> position;
|
||||||
NativeArray<float3> color;
|
public NativeArray<float3> color;
|
||||||
NativeArray<float> sh;
|
public NativeArray<float> sh;
|
||||||
NativeArray<float> opacity;
|
public NativeArray<float> opacity;
|
||||||
NativeArray<float3> scale;
|
public NativeArray<float3> scale;
|
||||||
NativeArray<float4> rotation;
|
public NativeArray<float4> rotation;
|
||||||
|
|
||||||
public SplatDataNative(int count)
|
public SplatDataNative(int count)
|
||||||
{
|
{
|
||||||
position = new NativeArray<float3>(count, Allocator.Temp);
|
position = new NativeArray<float3>(count, Allocator.Persistent);
|
||||||
color = new NativeArray<float3>(count, Allocator.Temp);
|
color = new NativeArray<float3>(count, Allocator.Persistent);
|
||||||
sh = new NativeArray<float>(count, Allocator.Temp);
|
sh = new NativeArray<float>(count * 45, Allocator.Persistent);
|
||||||
opacity = new NativeArray<float>(count, Allocator.Temp);
|
opacity = new NativeArray<float>(count, Allocator.Persistent);
|
||||||
scale = new NativeArray<float3>(count, Allocator.Temp);
|
scale = new NativeArray<float3>(count, Allocator.Persistent);
|
||||||
rotation = new NativeArray<float4>(count, Allocator.Temp);
|
rotation = new NativeArray<float4>(count, Allocator.Persistent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@@ -216,67 +233,135 @@ namespace SplatVfx.Editor
|
|||||||
{
|
{
|
||||||
var splatData = ScriptableObject.CreateInstance<SplatData>();
|
var splatData = ScriptableObject.CreateInstance<SplatData>();
|
||||||
|
|
||||||
int elementsPerChunk = MAX_CHUNK_SIZE / headerData.BytesPerElement;
|
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;
|
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);
|
using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||||
using var reader = new BinaryReader(fileStream);
|
|
||||||
fileStream.Seek(endHeaderPosition, SeekOrigin.Begin);
|
fileStream.Seek(endHeaderPosition, SeekOrigin.Begin);
|
||||||
|
|
||||||
var dataList = new List<SplatDataNative>();
|
int totalBytes = (int)fileStream.Length - endHeaderPosition;
|
||||||
var jobHandles = new List<JobHandle>();
|
Debug.Log($"Total bytes: {totalBytes}");
|
||||||
|
|
||||||
for (int pos = endHeaderPosition; pos < fileStream.Length; pos += chunkSize)
|
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)
|
||||||
{
|
{
|
||||||
int currChunkSize = (int)(pos + chunkSize < fileStream.Length ? chunkSize : fileStream.Length - pos);
|
numElemsRead = numBytesRead / headerData.BytesPerElement;
|
||||||
byte[] chunkBytes = reader.ReadBytes(currChunkSize);
|
var splatElementJob = new SplatElementJob
|
||||||
int numElemInChunk = currChunkSize / headerData.BytesPerElement;
|
|
||||||
|
|
||||||
var splatDataNative = new SplatDataNative(numElemInChunk);
|
|
||||||
dataList.Add(splatDataNative);
|
|
||||||
|
|
||||||
var splatChunkJob = new SplatChunkJob
|
|
||||||
{
|
{
|
||||||
chunkBytes = chunkBytes,
|
chunkBytes = chunkBuffer,
|
||||||
splatDataNative = splatDataNative,
|
splatDataNative = splatDataNative,
|
||||||
headerData = headerData,
|
headerData = headerData,
|
||||||
numElem = numElemInChunk
|
totalElemsRead = totalElemsRead,
|
||||||
|
numElemsRead = numElemsRead
|
||||||
};
|
};
|
||||||
|
|
||||||
var handle = splatChunkJob.Schedule();
|
splatElementJob.Schedule().Complete();
|
||||||
jobHandles.Add(handle);
|
|
||||||
|
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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy data here
|
// NativeArray<Vector3>.Copy(splatDataNative.position.Reinterpret<Vector3>(), 0, splatData.PositionArray, totalElemsRead, numElemsRead);
|
||||||
|
|
||||||
|
totalElemsRead += numElemsRead;
|
||||||
|
Debug.Log($"Current Elements Read: {totalElemsRead}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Log($"First position Vector3: {splatData.PositionArray[0]}");
|
||||||
|
|
||||||
|
headerData.Dispose();
|
||||||
|
splatDataNative.Dispose();
|
||||||
|
chunkBuffer.Dispose();
|
||||||
|
|
||||||
splatData.ReleaseGpuResources();
|
splatData.ReleaseGpuResources();
|
||||||
|
|
||||||
return splatData;
|
return splatData;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BurstCompile]
|
[BurstCompile]
|
||||||
private struct SplatChunkJob : IJob
|
private struct SplatElementJob : IJob
|
||||||
{
|
{
|
||||||
public byte[] chunkBytes;
|
public NativeArray<byte> chunkBytes;
|
||||||
public SplatDataNative splatDataNative;
|
public SplatDataNative splatDataNative;
|
||||||
public HeaderData headerData;
|
[ReadOnly] public HeaderData headerData;
|
||||||
public int numElem;
|
[ReadOnly] public int totalElemsRead;
|
||||||
|
[ReadOnly] public int numElemsRead;
|
||||||
|
|
||||||
public void Execute()
|
public void Execute()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
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]];
|
||||||
}
|
}
|
||||||
|
|
||||||
[BurstCompile]
|
float opacity = chunkBytes[start + headerData.ElementByteOffsets[(int)DataEnum.opacity]];
|
||||||
private struct SplatElementJob : IJobParallelFor
|
opacity = 1 / (1 + math.exp(-opacity));
|
||||||
{
|
splatDataNative.opacity[elemIx] = opacity;
|
||||||
public byte[] chunkBytes;
|
|
||||||
public SplatDataNative splatDataNative;
|
|
||||||
public HeaderData headerData;
|
|
||||||
|
|
||||||
public void Execute(int ix)
|
float3 scale = new()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
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])
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ MonoBehaviour:
|
|||||||
x: -692
|
x: -692
|
||||||
y: -492
|
y: -492
|
||||||
width: 1846
|
width: 1846
|
||||||
height: 2501
|
height: 2502
|
||||||
--- !u!114 &114350483966674976
|
--- !u!114 &114350483966674976
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 1
|
m_ObjectHideFlags: 1
|
||||||
@@ -13741,7 +13741,7 @@ MonoBehaviour:
|
|||||||
m_Parent: {fileID: 114350483966674976}
|
m_Parent: {fileID: 114350483966674976}
|
||||||
m_Children:
|
m_Children:
|
||||||
- {fileID: 8926484042661619332}
|
- {fileID: 8926484042661619332}
|
||||||
m_UIPosition: {x: 705, y: 700}
|
m_UIPosition: {x: 705, y: 741}
|
||||||
m_UICollapsed: 0
|
m_UICollapsed: 0
|
||||||
m_UISuperCollapsed: 0
|
m_UISuperCollapsed: 0
|
||||||
m_InputSlots: []
|
m_InputSlots: []
|
||||||
@@ -16773,7 +16773,7 @@ MonoBehaviour:
|
|||||||
m_Type:
|
m_Type:
|
||||||
m_SerializableType: System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral,
|
m_SerializableType: System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral,
|
||||||
PublicKeyToken=b77a5c561934e089
|
PublicKeyToken=b77a5c561934e089
|
||||||
m_SerializableObject: True
|
m_SerializableObject: False
|
||||||
m_Space: -1
|
m_Space: -1
|
||||||
m_Property:
|
m_Property:
|
||||||
name: _vfx_enabled
|
name: _vfx_enabled
|
||||||
|
|||||||
Reference in New Issue
Block a user