Implement rendering based on position

This commit is contained in:
2026-03-05 17:02:21 +08:00
parent 8d6428660e
commit ee8e817a48
9 changed files with 1957 additions and 179 deletions
+396
View File
@@ -0,0 +1,396 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 10
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 13
m_BakeOnSceneLoad: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 2
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 1
m_PVRFilteringGaussRadiusAO: 1
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 3
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
buildHeightMesh: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1001 &1278960003
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: -774367247743995920, guid: 37755a41ea5c1174cad6f111ea2f209b, type: 3}
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
- target: {fileID: -364223573239433514, guid: 37755a41ea5c1174cad6f111ea2f209b, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: -364223573239433514, guid: 37755a41ea5c1174cad6f111ea2f209b, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -364223573239433514, guid: 37755a41ea5c1174cad6f111ea2f209b, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -364223573239433514, guid: 37755a41ea5c1174cad6f111ea2f209b, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -364223573239433514, guid: 37755a41ea5c1174cad6f111ea2f209b, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -364223573239433514, guid: 37755a41ea5c1174cad6f111ea2f209b, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -364223573239433514, guid: 37755a41ea5c1174cad6f111ea2f209b, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8980549144392899874, guid: 37755a41ea5c1174cad6f111ea2f209b, type: 3}
propertyPath: m_Name
value: splat_30000
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: -4216948427090074523, guid: 37755a41ea5c1174cad6f111ea2f209b, type: 3}
--- !u!1 &1826889287
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1826889290}
- component: {fileID: 1826889289}
- component: {fileID: 1826889288}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &1826889288
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1826889287}
m_Enabled: 1
--- !u!20 &1826889289
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1826889287}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_Iso: 200
m_ShutterSpeed: 0.005
m_Aperture: 16
m_FocusDistance: 10
m_FocalLength: 50
m_BladeCount: 5
m_Curvature: {x: 2, y: 11}
m_BarrelClipping: 0.25
m_Anamorphism: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &1826889290
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1826889287}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1911516430
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1911516433}
- component: {fileID: 1911516432}
- component: {fileID: 1911516431}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1911516431
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1911516430}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.UniversalAdditionalLightData
m_UsePipelineSettings: 1
m_AdditionalLightsShadowResolutionTier: 2
m_CustomShadowLayers: 0
m_LightCookieSize: {x: 1, y: 1}
m_LightCookieOffset: {x: 0, y: 0}
m_SoftShadowQuality: 0
m_RenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_ShadowRenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_Version: 4
m_LightLayerMask: 1
m_ShadowLayerMask: 1
m_RenderingLayers: 1
m_ShadowRenderingLayers: 1
--- !u!108 &1911516432
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1911516430}
m_Enabled: 1
serializedVersion: 12
m_Type: 1
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize2D: {x: 0.5, y: 0.5}
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ForceVisible: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
m_LightUnit: 1
m_LuxAtDistance: 1
m_EnableSpotReflector: 1
--- !u!4 &1911516433
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1911516430}
serializedVersion: 2
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
m_Roots:
- {fileID: 1826889290}
- {fileID: 1911516433}
- {fileID: 1278960003}
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 09fad7c6f4d48844d9510f9903fca619
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+1 -1
View File
@@ -25,7 +25,7 @@ public sealed class SplatData : ScriptableObject
[field:SerializeField] public Quaternion[] RotationArray { get; set; }
[field:SerializeField] public Color[] ColorArray { get; set; }
[field:SerializeField] public float[] OpacityArray { get; set; }
[field:SerializeField] public float[][] SHArray { get; set; }
[field:SerializeField] public float[,] SHArray { get; set; }
#endregion
+62
View File
@@ -0,0 +1,62 @@
using UnityEngine;
using UnityEngine.VFX;
using UnityEngine.VFX.Utility;
namespace SplatVfx {
[AddComponentMenu("VFX/Property Binders/Splat Data Binder")]
[VFXBinder("Splat Data")]
public sealed class VFXSplatDataBinder : VFXBinderBase
{
public SplatData SplatData = null;
// public string SplatCountProperty
// { get => (string)_splatCountProperty;
// set => _splatCountProperty = value; }
public string PositionBufferProperty
{ get => (string)_positionBufferProperty;
set => _positionBufferProperty = value; }
// public string AxisBufferProperty
// { get => (string)_axisBufferProperty;
// set => _axisBufferProperty = value; }
// public string ColorBufferProperty
// { get => (string)_colorBufferProperty;
// set => _colorBufferProperty = value; }
// [VFXPropertyBinding("System.UInt32"), SerializeField]
// ExposedProperty _splatCountProperty = "SplatCount";
[VFXPropertyBinding("UnityEngine.GraphicsBuffer"), SerializeField]
ExposedProperty _positionBufferProperty = "PositionBuffer";
// [VFXPropertyBinding("UnityEngine.GraphicsBuffer"), SerializeField]
// ExposedProperty _axisBufferProperty = "AxisBuffer";
// [VFXPropertyBinding("UnityEngine.GraphicsBuffer"), SerializeField]
// ExposedProperty _colorBufferProperty = "ColorBuffer";
public override bool IsValid(VisualEffect component)
=> SplatData != null &&
// component.HasUInt(_splatCountProperty) &&
component.HasGraphicsBuffer(_positionBufferProperty); // &&
// component.HasGraphicsBuffer(_axisBufferProperty) &&
// component.HasGraphicsBuffer(_colorBufferProperty);
public override void UpdateBinding(VisualEffect component)
{
// component.SetUInt(_splatCountProperty, (uint)SplatData.SplatCount);
component.SetGraphicsBuffer(_positionBufferProperty, SplatData.PositionBuffer);
// component.SetGraphicsBuffer(_axisBufferProperty, SplatData.AxisBuffer);
// component.SetGraphicsBuffer(_colorBufferProperty, SplatData.ColorBuffer);
}
// public override string ToString()
// => $"Splat Data : {_splatCountProperty}, {_positionBufferProperty}, "
// // + $"{_axisBufferProperty}, {_colorBufferProperty}";
// + $"{_colorBufferProperty}";
}
} // namespace SplatVfx
-61
View File
@@ -1,61 +0,0 @@
using UnityEngine;
using UnityEngine.VFX;
using UnityEngine.VFX.Utility;
namespace SplatVfx {
[AddComponentMenu("VFX/Property Binders/Splat Data Binder")]
[VFXBinder("Splat Data")]
public sealed class VFXSplatDataBinder : VFXBinderBase
{
public SplatData SplatData = null;
public string SplatCountProperty
{ get => (string)_splatCountProperty;
set => _splatCountProperty = value; }
public string PositionBufferProperty
{ get => (string)_positionBufferProperty;
set => _positionBufferProperty = value; }
public string AxisBufferProperty
{ get => (string)_axisBufferProperty;
set => _axisBufferProperty = value; }
public string ColorBufferProperty
{ get => (string)_colorBufferProperty;
set => _colorBufferProperty = value; }
[VFXPropertyBinding("System.UInt32"), SerializeField]
ExposedProperty _splatCountProperty = "SplatCount";
[VFXPropertyBinding("UnityEngine.GraphicsBuffer"), SerializeField]
ExposedProperty _positionBufferProperty = "PositionBuffer";
[VFXPropertyBinding("UnityEngine.GraphicsBuffer"), SerializeField]
ExposedProperty _axisBufferProperty = "AxisBuffer";
[VFXPropertyBinding("UnityEngine.GraphicsBuffer"), SerializeField]
ExposedProperty _colorBufferProperty = "ColorBuffer";
public override bool IsValid(VisualEffect component)
=> SplatData != null &&
component.HasUInt(_splatCountProperty) &&
component.HasGraphicsBuffer(_positionBufferProperty) &&
component.HasGraphicsBuffer(_axisBufferProperty) &&
component.HasGraphicsBuffer(_colorBufferProperty);
public override void UpdateBinding(VisualEffect component)
{
component.SetUInt(_splatCountProperty, (uint)SplatData.SplatCount);
component.SetGraphicsBuffer(_positionBufferProperty, SplatData.PositionBuffer);
component.SetGraphicsBuffer(_axisBufferProperty, SplatData.AxisBuffer);
component.SetGraphicsBuffer(_colorBufferProperty, SplatData.ColorBuffer);
}
public override string ToString()
=> $"Splat Data : {_splatCountProperty}, {_positionBufferProperty}, "
+ $"{_axisBufferProperty}, {_colorBufferProperty}";
}
} // namespace SplatVfx
+203 -117
View File
@@ -12,54 +12,77 @@ using System.Runtime.InteropServices;
using System.Text;
using UnityEditor.Rendering.LookDev;
using System.Linq;
using System.Collections.Generic;
using Unity.VectorGraphics;
using Unity.VisualScripting;
using System.Collections;
using Unity.Collections;
namespace SplatVfx.Editor {
/*******************************************************************************
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
*******************************************************************************/
[ScriptedImporter(1, "ply"), BurstCompile]
public sealed class SplatImporter : ScriptedImporter
namespace SplatVfx.Editor
{
#region ScriptedImporter implementation
public override void OnImportAsset(AssetImportContext context)
[ScriptedImporter(1, "ply"), BurstCompile]
public sealed class SplatImporter : ScriptedImporter
{
_ = ParsePLYFile(context.assetPath);
// var data = ImportAsSplatData(context.assetPath);
// var prefab = CreatePrefab(data);
// context.AddObjectToAsset("prefab", prefab);
// context.AddObjectToAsset("data", data);
// context.SetMainObject(prefab);
}
#region ScriptedImporter implementation
#endregion
#region Prefab construction
// const string DefaultVfxPath = "Packages/jp.keijiro.splat-vfx/VFX/Splat.vfx";
// GameObject CreatePrefab(SplatData data)
// {
// var go = new GameObject();
// var vfx = go.AddComponent<VisualEffect>();
// vfx.visualEffectAsset = EditorResources.Load<VisualEffectAsset>(DefaultVfxPath);
// var binderBase = go.AddComponent<VFXPropertyBinder>();
// var binder = binderBase.AddPropertyBinder<VFXSplatDataBinder>();
// binder.SplatData = data;
// return go;
// }
#endregion
#region Reader implementation
(string header, byte[] binaryData) ParsePLYFile(string filePath)
{
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (var reader = new StreamReader(fileStream))
public override void OnImportAsset(AssetImportContext context)
{
StringBuilder headerBuilder = new StringBuilder();
var ply = ParsePLYFile(context.assetPath);
var header_info = ParseHeader(ply.header);
var data = ImportAsSplatData(header_info, ply.binaryData);
var prefab = CreatePrefab(data);
data.name = Path.GetFileNameWithoutExtension(context.assetPath);
context.AddObjectToAsset("prefab", prefab);
context.AddObjectToAsset("data", data);
context.SetMainObject(prefab);
}
#endregion
#region Prefab construction
const string DefaultVfxPath = "Assets/vfx-graph-gs/SplatVFX.vfx";
GameObject CreatePrefab(SplatData data)
{
var go = new GameObject();
var vfx = go.AddComponent<VisualEffect>();
vfx.visualEffectAsset = EditorResources.Load<VisualEffectAsset>(DefaultVfxPath);
var binderBase = go.AddComponent<VFXPropertyBinder>();
var binder = binderBase.AddPropertyBinder<VFXSplatDataBinder>();
binder.SplatData = data;
return go;
}
#endregion
#region Reader implementation
[BurstCompile]
(string header, byte[] binaryData) ParsePLYFile(string filePath)
{
using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
using var reader = new StreamReader(fileStream);
var headerBuilder = new StringBuilder();
string line;
while ((line = reader.ReadLine()) != null)
@@ -74,85 +97,148 @@ public sealed class SplatImporter : ScriptedImporter
long endHeaderPosition = headerBuilder.Length - headerBuilder.ToString().Split('\n').Length + 1;
fileStream.Seek(endHeaderPosition, SeekOrigin.Begin);
byte[] binaryData = new byte[fileStream.Length - endHeaderPosition];
var binaryReader = new BinaryReader(fileStream);
var binaryData = binaryReader.ReadBytes((int)(fileStream.Length - endHeaderPosition));
return (headerBuilder.ToString(), binaryData);
}
[BurstCompile]
(string format, int num_element, List<(string, string)> properties)
ParseHeader(string header)
{
using var reader = new StringReader(header);
string line;
string format = "";
int num_element = 0;
var properties = new List<(string, string)>();
while ((line = reader.ReadLine()) != null)
{
if (line.StartsWith("end_header"))
{
break;
}
var strings = line.Split(" ");
switch (strings.FirstOrDefault())
{
case "format":
format = strings[1];
break;
case "element":
num_element = int.Parse(strings[2]);
break;
case "property":
properties.Add((strings[2].Trim(), strings[1].Trim()));
break;
}
}
return (format, num_element, properties);
}
SplatData ImportAsSplatData((string format, int num_element, List<(string, string)> properties) header_info, byte[] binaryData)
{
var splatData = ScriptableObject.CreateInstance<SplatData>();
var stream = new MemoryStream(binaryData);
var reader = new BinaryReader(stream);
splatData.PositionArray = new Vector3[header_info.num_element];
splatData.ScaleArray = new Vector3[header_info.num_element];
splatData.RotationArray = new Quaternion[header_info.num_element];
splatData.ColorArray = new Color[header_info.num_element];
splatData.OpacityArray = new float[header_info.num_element];
splatData.SHArray = new float[header_info.num_element, 45];
for (int i = 0; i < header_info.num_element; i++)
{
foreach ((string name, string dtype) property in header_info.properties)
{
float val = reader.ReadSingle();
switch (property.name)
{
case "x":
splatData.PositionArray[i].x = val;
break;
case "y":
splatData.PositionArray[i].y = val;
break;
case "z":
splatData.PositionArray[i].z = val;
break;
}
}
}
splatData.ReleaseGpuResources();
return splatData;
}
// struct ReadData
// {
// public float px, py, pz;
// public float sx, sy, sz;
// public byte r, g, b, a;
// public byte rw, rx, ry, rz;
// }
// (Vector3[] position, Vector3[] axis, Color[] color)
// LoadDataArrays(string path)
// {
// var bytes = (Span<byte>)File.ReadAllBytes(path);
// var count = bytes.Length / 32;
// var source = MemoryMarshal.Cast<byte, ReadData>(bytes);
// var position = new Vector3[count];
// var axis = new Vector3[count * 3];
// var color = new Color[count];
// for (var i = 0; i < count; i++)
// ParseReadData(source[i],
// out position[i],
// out axis[i * 3],
// out axis[i * 3 + 1],
// out axis[i * 3 + 2],
// out color[i]);
// return (position, axis, color);
// }
// [BurstCompile]
// void ParseReadData(in ReadData src,
// out Vector3 position,
// out Vector3 axis1,
// out Vector3 axis2,
// out Vector3 axis3,
// out Color color)
// {
// var rv = (math.float4(src.rx, src.ry, src.rz, src.rw) - 128) / 128;
// var q = math.quaternion(-rv.x, -rv.y, rv.z, rv.w);
// position = math.float3(src.px, src.py, -src.pz);
// axis1 = math.mul(q, math.float3(src.sx, 0, 0));
// axis2 = math.mul(q, math.float3(0, src.sy, 0));
// axis3 = math.mul(q, math.float3(0, 0, src.sz));
// color = (Vector4)math.float4(src.r, src.g, src.b, src.a) / 255;
// }
#endregion
}
/*
get number of elements
run down header, building list of data mappings
for element
for data mapping
write data
*/
// SplatData ImportAsSplatData(string path)
// {
// var data = ScriptableObject.CreateInstance<SplatData>();
// data.name = Path.GetFileNameWithoutExtension(path);
// var arrays = LoadDataArrays(path);
// data.PositionArray = arrays.position;
// data.AxisArray = arrays.axis;
// data.ColorArray = arrays.color;
// data.ReleaseGpuResources();
// return data;
// }
// struct ReadData
// {
// public float px, py, pz;
// public float sx, sy, sz;
// public byte r, g, b, a;
// public byte rw, rx, ry, rz;
// }
// (Vector3[] position, Vector3[] axis, Color[] color)
// LoadDataArrays(string path)
// {
// var bytes = (Span<byte>)File.ReadAllBytes(path);
// var count = bytes.Length / 32;
// var source = MemoryMarshal.Cast<byte, ReadData>(bytes);
// var position = new Vector3[count];
// var axis = new Vector3[count * 3];
// var color = new Color[count];
// for (var i = 0; i < count; i++)
// ParseReadData(source[i],
// out position[i],
// out axis[i * 3],
// out axis[i * 3 + 1],
// out axis[i * 3 + 2],
// out color[i]);
// return (position, axis, color);
// }
// [BurstCompile]
// void ParseReadData(in ReadData src,
// out Vector3 position,
// out Vector3 axis1,
// out Vector3 axis2,
// out Vector3 axis3,
// out Color color)
// {
// var rv = (math.float4(src.rx, src.ry, src.rz, src.rw) - 128) / 128;
// var q = math.quaternion(-rv.x, -rv.y, rv.z, rv.w);
// position = math.float3(src.px, src.py, -src.pz);
// axis1 = math.mul(q, math.float3(src.sx, 0, 0));
// axis2 = math.mul(q, math.float3(0, src.sy, 0));
// axis3 = math.mul(q, math.float3(0, 0, src.sz));
// color = (Vector4)math.float4(src.r, src.g, src.b, src.a) / 255;
// }
#endregion
}
} // namespace SplatVfx.Editor
File diff suppressed because it is too large Load Diff
+15
View File
@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: bba3ec2cdc50cbe4f8ef4127933dcdf7
VisualEffectImporter:
externalObjects: {}
serializedVersion: 2
template:
name:
category:
description:
icon: {instanceID: 0}
thumbnail: {instanceID: 0}
useAsTemplate: 0
userData:
assetBundleName:
assetBundleVariant: