diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..72c27e4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,71 @@ +# This .gitignore file should be placed at the root of your Unity project directory +# +# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore +# +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/[Ll]ogs/ +/[Uu]ser[Ss]ettings/ + +# MemoryCaptures can get excessive in size. +# They also could contain extremely sensitive data +/[Mm]emoryCaptures/ + +# Asset meta data should only be ignored when the corresponding asset is also ignored +!/[Aa]ssets/**/*.meta + +# Uncomment this line if you wish to ignore the asset store tools plugin +# /[Aa]ssets/AssetStoreTools* + +# Autogenerated Jetbrains Rider plugin +/[Aa]ssets/Plugins/Editor/JetBrains* + +# Visual Studio cache directory +.vs/ + +# Gradle cache directory +.gradle/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta +*.mdb.meta + +# Unity3D generated file on crash reports +sysinfo.txt + +# Builds +*.apk +*.aab +*.unitypackage + +# Crashlytics generated file +crashlytics-build.properties + +# Packed Addressables +/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* + +# Temporary auto-generated Android Assets +/[Aa]ssets/[Ss]treamingAssets/aa.meta +/[Aa]ssets/[Ss]treamingAssets/aa/* diff --git a/Assets/Materials.meta b/Assets/Materials.meta new file mode 100644 index 0000000..82a6451 --- /dev/null +++ b/Assets/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5b87fab38f23d714c8a8aa96257d9fe3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Floor.mat b/Assets/Materials/Floor.mat new file mode 100644 index 0000000..e14a671 --- /dev/null +++ b/Assets/Materials/Floor.mat @@ -0,0 +1,83 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Floor + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.03773582, g: 0.03773582, b: 0.03773582, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Floor.mat.meta b/Assets/Materials/Floor.mat.meta new file mode 100644 index 0000000..1ecbd2a --- /dev/null +++ b/Assets/Materials/Floor.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e897138cef95d5545bcf5e7e52db78a0 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes.meta b/Assets/Scenes.meta new file mode 100644 index 0000000..d228558 --- /dev/null +++ b/Assets/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: de985a1975545934cacf8b7faceb28d6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Test A (2D).unity b/Assets/Scenes/Test A (2D).unity new file mode 100644 index 0000000..291b901 --- /dev/null +++ b/Assets/Scenes/Test A (2D).unity @@ -0,0 +1,352 @@ +%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: 9 + 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_IndirectSpecularColor: {r: 0.37311953, g: 0.38074014, b: 0.3587274, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + 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_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 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!1 &271053315 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 271053318} + - component: {fileID: 271053319} + - component: {fileID: 271053320} + - component: {fileID: 271053323} + m_Layer: 0 + m_Name: Simulation + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &271053318 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + 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!114 &271053319 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bf901970f9cf132479a879d7a4acde3d, type: 3} + m_Name: + m_EditorClassIdentifier: + timeScale: 1 + fixedTimeStep: 0 + iterationsPerFrame: 3 + gravity: -12 + collisionDamping: 0.95 + smoothingRadius: 0.35 + targetDensity: 55 + pressureMultiplier: 500 + nearPressureMultiplier: 18 + viscosityStrength: 0.06 + boundsSize: {x: 17.1, y: 9.3} + obstacleSize: {x: 0, y: 0} + obstacleCentre: {x: 0, y: 0} + interactionRadius: 2 + interactionStrength: 90 + compute: {fileID: 7200000, guid: 1c77ce8de78fddb419ed2d15cae41af0, type: 3} + spawner: {fileID: 271053320} + display: {fileID: 271053323} +--- !u!114 &271053320 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 895837b52d5fc53409ded3589d4da696, type: 3} + m_Name: + m_EditorClassIdentifier: + particleCount: 4032 + initialVelocity: {x: 0, y: 0} + spawnCentre: {x: 3.35, y: 0.51} + spawnSize: {x: 7, y: 7} + jitterStr: 0.025 + showSpawnBoundsGizmos: 1 +--- !u!114 &271053323 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b090cee05a6cd0e4291a0e02381231c1, type: 3} + m_Name: + m_EditorClassIdentifier: + mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} + shader: {fileID: 4800000, guid: 441b7193936682446b30d2140d15792a, type: 3} + scale: 0.08 + colourMap: + serializedVersion: 2 + key0: {r: 0.13363299, g: 0.34235913, b: 0.7264151, a: 1} + key1: {r: 0.2980392, g: 1, b: 0.56327766, a: 1} + key2: {r: 1, g: 0.9309917, b: 0, a: 0} + key3: {r: 0.96862745, g: 0.28555763, b: 0.031372573, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 4064 + ctime1: 33191 + ctime2: 46738 + ctime3: 65535 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 2 + m_ColorSpace: -1 + m_NumColorKeys: 4 + m_NumAlphaKeys: 2 + gradientResolution: 64 + velocityDisplayMax: 6.5 +--- !u!1 &963194225 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 963194228} + - component: {fileID: 963194227} + - component: {fileID: 963194226} + 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 &963194226 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 +--- !u!20 &963194227 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0, g: 0, b: 0, 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: 1 + 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 &963194228 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, 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!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 963194228} + - {fileID: 271053318} diff --git a/Assets/Scenes/Test A (2D).unity.meta b/Assets/Scenes/Test A (2D).unity.meta new file mode 100644 index 0000000..eea9359 --- /dev/null +++ b/Assets/Scenes/Test A (2D).unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 553a18d1ebb4c1a42879001af73f632b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Test B (2D).unity b/Assets/Scenes/Test B (2D).unity new file mode 100644 index 0000000..3575a24 --- /dev/null +++ b/Assets/Scenes/Test B (2D).unity @@ -0,0 +1,352 @@ +%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: 9 + 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_IndirectSpecularColor: {r: 0.37311953, g: 0.38074014, b: 0.3587274, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + 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_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 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!1 &271053315 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 271053318} + - component: {fileID: 271053319} + - component: {fileID: 271053320} + - component: {fileID: 271053322} + m_Layer: 0 + m_Name: Simulation + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &271053318 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + 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!114 &271053319 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bf901970f9cf132479a879d7a4acde3d, type: 3} + m_Name: + m_EditorClassIdentifier: + timeScale: 1 + fixedTimeStep: 0 + iterationsPerFrame: 7 + gravity: -13 + collisionDamping: 0.5 + smoothingRadius: 0.2 + targetDensity: 234 + pressureMultiplier: 225 + nearPressureMultiplier: 18 + viscosityStrength: 0.03 + boundsSize: {x: 17.1, y: 9.3} + obstacleSize: {x: 2.75, y: 5} + obstacleCentre: {x: 4.8, y: -1} + interactionRadius: 2.5 + interactionStrength: 75 + compute: {fileID: 7200000, guid: 1c77ce8de78fddb419ed2d15cae41af0, type: 3} + spawner: {fileID: 271053320} + display: {fileID: 271053322} +--- !u!114 &271053320 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 895837b52d5fc53409ded3589d4da696, type: 3} + m_Name: + m_EditorClassIdentifier: + particleCount: 16000 + initialVelocity: {x: 0, y: 0} + spawnCentre: {x: -1.28, y: 0.58} + spawnSize: {x: 6.24, y: 7.72} + jitterStr: 0.02 + showSpawnBoundsGizmos: 1 +--- !u!114 &271053322 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b090cee05a6cd0e4291a0e02381231c1, type: 3} + m_Name: + m_EditorClassIdentifier: + mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} + shader: {fileID: 4800000, guid: 441b7193936682446b30d2140d15792a, type: 3} + scale: 0.045 + colourMap: + serializedVersion: 2 + key0: {r: 0.105820596, g: 0.34020147, b: 0.7735849, a: 1} + key1: {r: 0.23082057, g: 0.7843372, b: 0.8584906, a: 1} + key2: {r: 1, g: 0.9309917, b: 0, a: 0} + key3: {r: 0.96862745, g: 0.28555763, b: 0.031372573, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 4064 + ctime1: 25571 + ctime2: 37594 + ctime3: 65535 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 2 + m_ColorSpace: -1 + m_NumColorKeys: 4 + m_NumAlphaKeys: 2 + gradientResolution: 64 + velocityDisplayMax: 7 +--- !u!1 &963194225 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 963194228} + - component: {fileID: 963194227} + - component: {fileID: 963194226} + 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 &963194226 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 +--- !u!20 &963194227 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0, g: 0, b: 0, 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: 1 + 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 &963194228 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, 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!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 963194228} + - {fileID: 271053318} diff --git a/Assets/Scenes/Test B (2D).unity.meta b/Assets/Scenes/Test B (2D).unity.meta new file mode 100644 index 0000000..0829ad5 --- /dev/null +++ b/Assets/Scenes/Test B (2D).unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 36ab9b6fbf0666145b2b63c6cc2d6548 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Test C (3D).unity b/Assets/Scenes/Test C (3D).unity new file mode 100644 index 0000000..dd82456 --- /dev/null +++ b/Assets/Scenes/Test C (3D).unity @@ -0,0 +1,542 @@ +%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: 9 + 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_IndirectSpecularColor: {r: 0.4492334, g: 0.49930477, b: 0.5757145, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + 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_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 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!1 &128587419 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 128587421} + - component: {fileID: 128587420} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &128587420 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 128587419} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 1 + m_Shape: 0 + m_Color: {r: 0.9231027, g: 0.9245283, b: 0.8416696, a: 1} + m_Intensity: 0.9 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: 3 + m_CustomResolution: -1 + m_Strength: 0.9 + 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_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &128587421 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 128587419} + serializedVersion: 2 + m_LocalRotation: {x: 0.42612273, y: 0.26698598, z: 0.11941972, w: 0.85608226} + m_LocalPosition: {x: 0, y: 2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 41.746, y: 48.511, z: 35.381} +--- !u!1 &271053315 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 271053318} + - component: {fileID: 271053319} + - component: {fileID: 271053320} + - component: {fileID: 271053323} + - component: {fileID: 271053322} + m_Layer: 0 + m_Name: Simulation + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &271053318 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 8.6, y: 5.16, z: 5} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 620375868} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &271053319 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c8b3b79f98be3f34e8fefade4cef2ade, type: 3} + m_Name: + m_EditorClassIdentifier: + timeScale: 0.9 + fixedTimeStep: 0 + iterationsPerFrame: 3 + gravity: -10 + collisionDamping: 0.95 + smoothingRadius: 0.2 + targetDensity: 630 + pressureMultiplier: 288 + nearPressureMultiplier: 2.25 + viscosityStrength: 0.001 + compute: {fileID: 7200000, guid: 9443696acfd0ebe4fb503b56d952256c, type: 3} + spawner: {fileID: 271053323} + display: {fileID: 271053320} + floorDisplay: {fileID: 620375868} +--- !u!114 &271053320 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bdfe3008efbf29745879ab1d40574478, type: 3} + m_Name: + m_EditorClassIdentifier: + shader: {fileID: 4800000, guid: bebe529033c51cb4f99d667ea48fa0c7, type: 3} + scale: 0.05 + col: {r: 0.27803493, g: 0.49487686, b: 0.8301887, a: 1} + colourMap: + serializedVersion: 2 + key0: {r: 0.13363299, g: 0.34235913, b: 0.7264151, a: 1} + key1: {r: 0.2980392, g: 1, b: 0.56327766, a: 1} + key2: {r: 1, g: 0.9309917, b: 0, a: 0} + key3: {r: 0.96862745, g: 0.28555763, b: 0.031372573, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 4064 + ctime1: 33191 + ctime2: 46738 + ctime3: 65535 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 2 + m_ColorSpace: -1 + m_NumColorKeys: 4 + m_NumAlphaKeys: 2 + gradientResolution: 50 + velocityDisplayMax: 6 + meshResolution: 3 + debug_MeshTriCount: 2 +--- !u!33 &271053322 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!114 &271053323 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 271053315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f99a384512b94654fbeb7c06c43f81ba, type: 3} + m_Name: + m_EditorClassIdentifier: + numParticlesPerAxis: 35 + centre: {x: 0, y: -0.47, z: 0} + initialVel: + x: 0 + y: 0 + z: 0 + size: 3.7 + jitterStrength: 0.035 + showSpawnBounds: 1 + debug_numParticles: 42875 +--- !u!1 &620375867 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 620375868} + - component: {fileID: 620375871} + - component: {fileID: 620375870} + m_Layer: 0 + m_Name: Floor Display + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &620375868 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 620375867} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: -0.5, z: 0} + m_LocalScale: {x: 1, y: 0.01, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 271053318} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!23 &620375870 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 620375867} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: e897138cef95d5545bcf5e7e52db78a0, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &620375871 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 620375867} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &963194225 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 963194228} + - component: {fileID: 963194227} + - component: {fileID: 963194226} + 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 &963194226 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 +--- !u!20 &963194227 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0, g: 0, b: 0, 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 &963194228 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + serializedVersion: 2 + m_LocalRotation: {x: 0.040845454, y: -0, z: -0, w: 0.9991655} + m_LocalPosition: {x: 0, y: 0.76, z: -8.244} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 4.682, y: 0, z: 0} +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 963194228} + - {fileID: 271053318} + - {fileID: 128587421} diff --git a/Assets/Scenes/Test C (3D).unity.meta b/Assets/Scenes/Test C (3D).unity.meta new file mode 100644 index 0000000..e1ddcc5 --- /dev/null +++ b/Assets/Scenes/Test C (3D).unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1e2ac58142c607641a0cfa53d7656680 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts.meta b/Assets/Scripts.meta new file mode 100644 index 0000000..472fb8c --- /dev/null +++ b/Assets/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: af4e1f4c757289c46ad70535c291f34b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Compute Helpers.meta b/Assets/Scripts/Compute Helpers.meta new file mode 100644 index 0000000..d0f2064 --- /dev/null +++ b/Assets/Scripts/Compute Helpers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2899f7edea912bd49ba6d764aee2ccf3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Compute Helpers/ComputeHelper.cs b/Assets/Scripts/Compute Helpers/ComputeHelper.cs new file mode 100644 index 0000000..43c14f7 --- /dev/null +++ b/Assets/Scripts/Compute Helpers/ComputeHelper.cs @@ -0,0 +1,437 @@ + +using UnityEngine; +using UnityEngine.Experimental.Rendering; + +// This class contains some helper functions to make life a little easier working with compute shaders +// (Very work-in-progress!) + +public enum DepthMode { None = 0, Depth16 = 16, Depth24 = 24 } + +public static class ComputeHelper +{ + + public const FilterMode defaultFilterMode = FilterMode.Bilinear; + public const GraphicsFormat defaultGraphicsFormat = GraphicsFormat.R32G32B32A32_SFloat; + + + + static ComputeShader normalizeTextureCompute; + static ComputeShader clearTextureCompute; + static ComputeShader swizzleTextureCompute; + static ComputeShader copy3DCompute; + static Shader bicubicUpscale; + + /// Convenience method for dispatching a compute shader. + /// It calculates the number of thread groups based on the number of iterations needed. + public static void Dispatch(ComputeShader cs, int numIterationsX, int numIterationsY = 1, int numIterationsZ = 1, int kernelIndex = 0) + { + Vector3Int threadGroupSizes = GetThreadGroupSizes(cs, kernelIndex); + int numGroupsX = Mathf.CeilToInt(numIterationsX / (float)threadGroupSizes.x); + int numGroupsY = Mathf.CeilToInt(numIterationsY / (float)threadGroupSizes.y); + int numGroupsZ = Mathf.CeilToInt(numIterationsZ / (float)threadGroupSizes.y); + cs.Dispatch(kernelIndex, numGroupsX, numGroupsY, numGroupsZ); + } + + /// Convenience method for dispatching a compute shader. + /// It calculates the number of thread groups based on the size of the given texture. + public static void Dispatch(ComputeShader cs, RenderTexture texture, int kernelIndex = 0) + { + Vector3Int threadGroupSizes = GetThreadGroupSizes(cs, kernelIndex); + Dispatch(cs, texture.width, texture.height, texture.volumeDepth, kernelIndex); + } + + public static void Dispatch(ComputeShader cs, Texture2D texture, int kernelIndex = 0) + { + Vector3Int threadGroupSizes = GetThreadGroupSizes(cs, kernelIndex); + Dispatch(cs, texture.width, texture.height, 1, kernelIndex); + } + + public static int GetStride() + { + return System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)); + } + + public static ComputeBuffer CreateAppendBuffer(int size = 1) + { + int stride = GetStride(); + ComputeBuffer buffer = new ComputeBuffer(size, stride, ComputeBufferType.Append); + buffer.SetCounterValue(0); + return buffer; + + } + + + public static void CreateStructuredBuffer(ref ComputeBuffer buffer, int count) + { + int stride = GetStride(); + bool createNewBuffer = buffer == null || !buffer.IsValid() || buffer.count != count || buffer.stride != stride; + if (createNewBuffer) + { + Release(buffer); + buffer = new ComputeBuffer(count, stride); + } + } + + + public static ComputeBuffer CreateStructuredBuffer(T[] data) + { + var buffer = new ComputeBuffer(data.Length, GetStride()); + buffer.SetData(data); + return buffer; + } + + public static ComputeBuffer CreateStructuredBuffer(int count) + { + return new ComputeBuffer(count, GetStride()); + } + + public static void CreateStructuredBuffer(ref ComputeBuffer buffer, T[] data) + { + CreateStructuredBuffer(ref buffer, data.Length); + buffer.SetData(data); + } + + public static void SetBuffer(ComputeShader compute, ComputeBuffer buffer, string id, params int[] kernels) + { + for (int i = 0; i < kernels.Length; i++) + { + compute.SetBuffer(kernels[i], id, buffer); + } + } + + public static ComputeBuffer CreateAndSetBuffer(T[] data, ComputeShader cs, string nameID, int kernelIndex = 0) + { + ComputeBuffer buffer = null; + CreateAndSetBuffer(ref buffer, data, cs, nameID, kernelIndex); + return buffer; + } + + public static void CreateAndSetBuffer(ref ComputeBuffer buffer, T[] data, ComputeShader cs, string nameID, int kernelIndex = 0) + { + int stride = System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)); + CreateStructuredBuffer(ref buffer, data.Length); + buffer.SetData(data); + cs.SetBuffer(kernelIndex, nameID, buffer); + } + + public static ComputeBuffer CreateAndSetBuffer(int length, ComputeShader cs, string nameID, int kernelIndex = 0) + { + ComputeBuffer buffer = null; + CreateAndSetBuffer(ref buffer, length, cs, nameID, kernelIndex); + return buffer; + } + + public static void CreateAndSetBuffer(ref ComputeBuffer buffer, int length, ComputeShader cs, string nameID, int kernelIndex = 0) + { + CreateStructuredBuffer(ref buffer, length); + cs.SetBuffer(kernelIndex, nameID, buffer); + } + + + + /// Releases supplied buffer/s if not null + public static void Release(params ComputeBuffer[] buffers) + { + for (int i = 0; i < buffers.Length; i++) + { + if (buffers[i] != null) + { + buffers[i].Release(); + } + } + } + + /// Releases supplied render textures/s if not null + public static void Release(params RenderTexture[] textures) + { + for (int i = 0; i < textures.Length; i++) + { + if (textures[i] != null) + { + textures[i].Release(); + } + } + } + + public static Vector3Int GetThreadGroupSizes(ComputeShader compute, int kernelIndex = 0) + { + uint x, y, z; + compute.GetKernelThreadGroupSizes(kernelIndex, out x, out y, out z); + return new Vector3Int((int)x, (int)y, (int)z); + } + + // ------ Texture Helpers ------ + + public static RenderTexture CreateRenderTexture(RenderTexture template) + { + RenderTexture renderTexture = null; + CreateRenderTexture(ref renderTexture, template); + return renderTexture; + } + + public static RenderTexture CreateRenderTexture(int width, int height, FilterMode filterMode, GraphicsFormat format, string name = "Unnamed", DepthMode depthMode = DepthMode.None, bool useMipMaps = false) + { + RenderTexture texture = new RenderTexture(width, height, (int)depthMode); + texture.graphicsFormat = format; + texture.enableRandomWrite = true; + texture.autoGenerateMips = false; + texture.useMipMap = useMipMaps; + texture.Create(); + + texture.name = name; + texture.wrapMode = TextureWrapMode.Clamp; + texture.filterMode = filterMode; + return texture; + } + + public static void CreateRenderTexture(ref RenderTexture texture, RenderTexture template) + { + if (texture != null) + { + texture.Release(); + } + texture = new RenderTexture(template.descriptor); + texture.enableRandomWrite = true; + texture.Create(); + } + + public static void CreateRenderTexture(ref RenderTexture texture, int width, int height) + { + CreateRenderTexture(ref texture, width, height, defaultFilterMode, defaultGraphicsFormat); + } + + + public static bool CreateRenderTexture(ref RenderTexture texture, int width, int height, FilterMode filterMode, GraphicsFormat format, string name = "Unnamed", DepthMode depthMode = DepthMode.None, bool useMipMaps = false) + { + if (texture == null || !texture.IsCreated() || texture.width != width || texture.height != height || texture.graphicsFormat != format || texture.depth != (int)depthMode || texture.useMipMap != useMipMaps) + { + if (texture != null) + { + texture.Release(); + } + texture = CreateRenderTexture(width, height, filterMode, format, name, depthMode, useMipMaps); + return true; + } + else + { + texture.name = name; + texture.wrapMode = TextureWrapMode.Clamp; + texture.filterMode = filterMode; + } + + return false; + } + + + public static void CreateRenderTexture3D(ref RenderTexture texture, RenderTexture template) + { + CreateRenderTexture(ref texture, template); + } + + public static void CreateRenderTexture3D(ref RenderTexture texture, int size, GraphicsFormat format, TextureWrapMode wrapMode = TextureWrapMode.Repeat, string name = "Untitled", bool mipmaps = false) + { + if (texture == null || !texture.IsCreated() || texture.width != size || texture.height != size || texture.volumeDepth != size || texture.graphicsFormat != format) + { + //Debug.Log ("Create tex: update noise: " + updateNoise); + if (texture != null) + { + texture.Release(); + } + const int numBitsInDepthBuffer = 0; + texture = new RenderTexture(size, size, numBitsInDepthBuffer); + texture.graphicsFormat = format; + texture.volumeDepth = size; + texture.enableRandomWrite = true; + texture.dimension = UnityEngine.Rendering.TextureDimension.Tex3D; + texture.useMipMap = mipmaps; + texture.autoGenerateMips = false; + texture.Create(); + } + texture.wrapMode = wrapMode; + texture.filterMode = FilterMode.Bilinear; + texture.name = name; + } + + /// Copy the contents of one render texture into another. Assumes textures are the same size. + public static void CopyRenderTexture(Texture source, RenderTexture target) + { + Graphics.Blit(source, target); + } + + /// Copy the contents of one render texture into another. Assumes textures are the same size. + public static void CopyRenderTexture3D(Texture source, RenderTexture target) + { + LoadComputeShader(ref copy3DCompute, "Copy3D"); + copy3DCompute.SetInts("dimensions", target.width, target.height, target.volumeDepth); + copy3DCompute.SetTexture(0, "Source", source); + copy3DCompute.SetTexture(0, "Target", target); + Dispatch(copy3DCompute, target.width, target.height, target.volumeDepth);// + } + /// ---- Processing ----- + + /// Sets all pixels of supplied texture to 0 + public static void ClearRenderTexture(RenderTexture source) + { + LoadComputeShader(ref clearTextureCompute, "ClearTexture"); + + clearTextureCompute.SetInt("width", source.width); + clearTextureCompute.SetInt("height", source.height); + clearTextureCompute.SetTexture(0, "Source", source); + Dispatch(clearTextureCompute, source.width, source.height, 1, 0); + } + + /// Work in progress, currently only works with one channel and very slow + public static void NormalizeRenderTexture(RenderTexture source) + { + LoadComputeShader(ref normalizeTextureCompute, "NormalizeTexture"); + + normalizeTextureCompute.SetInt("width", source.width); + normalizeTextureCompute.SetInt("height", source.height); + normalizeTextureCompute.SetTexture(0, "Source", source); + normalizeTextureCompute.SetTexture(1, "Source", source); + + ComputeBuffer minMaxBuffer = CreateAndSetBuffer(new int[] { int.MaxValue, 0 }, normalizeTextureCompute, "minMaxBuffer", 0); + normalizeTextureCompute.SetBuffer(1, "minMaxBuffer", minMaxBuffer); + + Dispatch(normalizeTextureCompute, source.width, source.height, 1, 0); + Dispatch(normalizeTextureCompute, source.width, source.height, 1, 1); + + Release(minMaxBuffer); + } + + public static RenderTexture BicubicUpscale(RenderTexture original, int sizeMultiplier = 2) + { + RenderTexture upscaled = CreateRenderTexture(original.width * sizeMultiplier, original.height * sizeMultiplier, original.filterMode, original.graphicsFormat, original.name + " upscaled"); + upscaled.wrapModeU = original.wrapModeU; + upscaled.wrapModeV = original.wrapModeV; + LoadShader(ref bicubicUpscale, "BicubicUpscale"); + Material material = new Material(bicubicUpscale); + material.SetVector("textureSize", new Vector2(original.width, original.height)); + Graphics.Blit(original, upscaled, material); + return upscaled; + } + + // ------ Instancing Helpers + + // Create args buffer for instanced indirect rendering + public static ComputeBuffer CreateArgsBuffer(Mesh mesh, int numInstances) + { + const int subMeshIndex = 0; + uint[] args = new uint[5]; + args[0] = (uint)mesh.GetIndexCount(subMeshIndex); + args[1] = (uint)numInstances; + args[2] = (uint)mesh.GetIndexStart(subMeshIndex); + args[3] = (uint)mesh.GetBaseVertex(subMeshIndex); + args[4] = 0; // offset + + ComputeBuffer argsBuffer = new ComputeBuffer(1, 5 * sizeof(uint), ComputeBufferType.IndirectArguments); + argsBuffer.SetData(args); + return argsBuffer; + } + + // Create args buffer for instanced indirect rendering (number of instances comes from size of append buffer) + public static ComputeBuffer CreateArgsBuffer(Mesh mesh, ComputeBuffer appendBuffer) + { + var buffer = CreateArgsBuffer(mesh, 0); + ComputeBuffer.CopyCount(appendBuffer, buffer, sizeof(uint)); + return buffer; + } + + // Read number of elements in append buffer + public static int ReadAppendBufferLength(ComputeBuffer appendBuffer) + { + ComputeBuffer countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw); + ComputeBuffer.CopyCount(appendBuffer, countBuffer, 0); + + int[] data = new int[1]; + countBuffer.GetData(data); + Release(countBuffer); + return data[0]; + } + + // ------ Set compute shader properties ------ + + public static void AssignTexture(ComputeShader compute, Texture texture, string name, params int[] kernels) + { + for (int i = 0; i < kernels.Length; i++) + { + compute.SetTexture(kernels[i], name, texture); + } + } + + public static void AssignBuffer(ComputeShader compute, ComputeBuffer texture, string name, params int[] kernels) + { + for (int i = 0; i < kernels.Length; i++) + { + compute.SetBuffer(kernels[i], name, texture); + } + } + + // Set all values from settings object on the shader. Note, variable names must be an exact match in the shader. + // Settings object can be any class/struct containing vectors/ints/floats/bools + public static void SetParams(System.Object settings, ComputeShader shader, string variableNamePrefix = "", string variableNameSuffix = "") + { + var fields = settings.GetType().GetFields(); + foreach (var field in fields) + { + var fieldType = field.FieldType; + string shaderVariableName = variableNamePrefix + field.Name + variableNameSuffix; + + if (fieldType == typeof(UnityEngine.Vector4) || fieldType == typeof(Vector3) || fieldType == typeof(Vector2)) + { + shader.SetVector(shaderVariableName, (Vector4)field.GetValue(settings)); + } + else if (fieldType == typeof(int)) + { + shader.SetInt(shaderVariableName, (int)field.GetValue(settings)); + } + else if (fieldType == typeof(float)) + { + shader.SetFloat(shaderVariableName, (float)field.GetValue(settings)); + } + else if (fieldType == typeof(bool)) + { + shader.SetBool(shaderVariableName, (bool)field.GetValue(settings)); + } + else + { + Debug.Log($"Type {fieldType} not implemented"); + } + } + } + + // ------ MISC ------- + + + // https://cmwdexint.com/2017/12/04/computeshader-setfloats/ + public static float[] PackFloats(params float[] values) + { + float[] packed = new float[values.Length * 4]; + for (int i = 0; i < values.Length; i++) + { + packed[i * 4] = values[i]; + } + return values; + } + + public static void LoadComputeShader(ref ComputeShader shader, string name) + { + if (shader == null) + { + shader = LoadComputeShader(name); + } + } + + public static ComputeShader LoadComputeShader(string name) + { + return Resources.Load(name.Split('.')[0]); + } + + static void LoadShader(ref Shader shader, string name) + { + if (shader == null) + { + shader = (Shader)Resources.Load(name); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Compute Helpers/ComputeHelper.cs.meta b/Assets/Scripts/Compute Helpers/ComputeHelper.cs.meta new file mode 100644 index 0000000..95616e2 --- /dev/null +++ b/Assets/Scripts/Compute Helpers/ComputeHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7c863392f8630b49a1dfc6ae6827d5c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Compute Helpers/GPU Sort.meta b/Assets/Scripts/Compute Helpers/GPU Sort.meta new file mode 100644 index 0000000..a696fd6 --- /dev/null +++ b/Assets/Scripts/Compute Helpers/GPU Sort.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7ba8cf4753029394495a867201021255 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Compute Helpers/GPU Sort/GPUSort.cs b/Assets/Scripts/Compute Helpers/GPU Sort/GPUSort.cs new file mode 100644 index 0000000..f309ca5 --- /dev/null +++ b/Assets/Scripts/Compute Helpers/GPU Sort/GPUSort.cs @@ -0,0 +1,61 @@ +using UnityEngine; +using static UnityEngine.Mathf; + +public class GPUSort +{ + const int sortKernel = 0; + const int calculateOffsetsKernel = 1; + + readonly ComputeShader sortCompute; + ComputeBuffer indexBuffer; + + public GPUSort() + { + sortCompute = ComputeHelper.LoadComputeShader("BitonicMergeSort"); + } + + public void SetBuffers(ComputeBuffer indexBuffer, ComputeBuffer offsetBuffer) + { + this.indexBuffer = indexBuffer; + + sortCompute.SetBuffer(sortKernel, "Entries", indexBuffer); + ComputeHelper.SetBuffer(sortCompute, offsetBuffer, "Offsets", calculateOffsetsKernel); + ComputeHelper.SetBuffer(sortCompute, indexBuffer, "Entries", calculateOffsetsKernel); + } + + // Sorts given buffer of integer values using bitonic merge sort + // Note: buffer size is not restricted to powers of 2 in this implementation + public void Sort() + { + sortCompute.SetInt("numEntries", indexBuffer.count); + + // Launch each step of the sorting algorithm (once the previous step is complete) + // Number of steps = [log2(n) * (log2(n) + 1)] / 2 + // where n = nearest power of 2 that is greater or equal to the number of inputs + int numStages = (int)Log(NextPowerOfTwo(indexBuffer.count), 2); + + for (int stageIndex = 0; stageIndex < numStages; stageIndex++) + { + for (int stepIndex = 0; stepIndex < stageIndex + 1; stepIndex++) + { + // Calculate some pattern stuff + int groupWidth = 1 << (stageIndex - stepIndex); + int groupHeight = 2 * groupWidth - 1; + sortCompute.SetInt("groupWidth", groupWidth); + sortCompute.SetInt("groupHeight", groupHeight); + sortCompute.SetInt("stepIndex", stepIndex); + // Run the sorting step on the GPU + ComputeHelper.Dispatch(sortCompute, NextPowerOfTwo(indexBuffer.count) / 2); + } + } + } + + + public void SortAndCalculateOffsets() + { + Sort(); + + ComputeHelper.Dispatch(sortCompute, indexBuffer.count, kernelIndex: calculateOffsetsKernel); + } + +} \ No newline at end of file diff --git a/Assets/Scripts/Compute Helpers/GPU Sort/GPUSort.cs.meta b/Assets/Scripts/Compute Helpers/GPU Sort/GPUSort.cs.meta new file mode 100644 index 0000000..9384a93 --- /dev/null +++ b/Assets/Scripts/Compute Helpers/GPU Sort/GPUSort.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef4310023e53c0348a8b67288ab1a4a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Compute Helpers/GPU Sort/Resources.meta b/Assets/Scripts/Compute Helpers/GPU Sort/Resources.meta new file mode 100644 index 0000000..3f1e3ad --- /dev/null +++ b/Assets/Scripts/Compute Helpers/GPU Sort/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 28215577b833ba34287850db72bcddca +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Compute Helpers/GPU Sort/Resources/BitonicMergeSort.compute b/Assets/Scripts/Compute Helpers/GPU Sort/Resources/BitonicMergeSort.compute new file mode 100644 index 0000000..a1293c2 --- /dev/null +++ b/Assets/Scripts/Compute Helpers/GPU Sort/Resources/BitonicMergeSort.compute @@ -0,0 +1,64 @@ +#pragma kernel Sort +#pragma kernel CalculateOffsets + +struct Entry +{ + uint originalIndex; + uint hash; + uint key; +}; + +RWStructuredBuffer Entries; +const uint numEntries; +const uint groupWidth; +const uint groupHeight; +const uint stepIndex; + +// Sort the given entries by their keys (smallest to largest) +// This is done using bitonic merge sort, and takes multiple iterations +[numthreads(128, 1, 1)] +void Sort (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + uint hIndex = i & (groupWidth - 1); + uint indexLeft = hIndex + (groupHeight + 1) * (i / groupWidth); + uint rightStepSize = stepIndex == 0 ? groupHeight - 2 * hIndex : (groupHeight + 1) / 2; + uint indexRight = indexLeft + rightStepSize; + + // Exit if out of bounds (for non-power of 2 input sizes) + if (indexRight >= numEntries) return; + + uint valueLeft = Entries[indexLeft].key; + uint valueRight = Entries[indexRight].key; + + // Swap entries if value is descending + if (valueLeft > valueRight) + { + Entry temp = Entries[indexLeft]; + Entries[indexLeft] = Entries[indexRight]; + Entries[indexRight] = temp; + } +} + +// Calculate offsets into the sorted buffer (used for spatial hashing). +// For example if the sorted buffer looks like -> Sorted: {0001223333} +// The resulting offsets would be -> Offsets: {0003446666} +// This means that, if for instance we look up Sorted[8] (which has a value of 3), we could then look up +// Offsets[8] to get a value of 6, which is the index where the group of 3's begins in the Sorted buffer. +// NOTE: offsets buffer must filled with values equal to (or greater than) its length +RWStructuredBuffer Offsets; + +[numthreads(128, 1, 1)] +void CalculateOffsets (uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numEntries) { return;} + uint i = id.x; + + uint key = Entries[i].key; + uint keyPrev = i == 0 ? 9999999 : Entries[i-1].key; + if (key != keyPrev) + { + Offsets[key] = i; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Compute Helpers/GPU Sort/Resources/BitonicMergeSort.compute.meta b/Assets/Scripts/Compute Helpers/GPU Sort/Resources/BitonicMergeSort.compute.meta new file mode 100644 index 0000000..15a5bcb --- /dev/null +++ b/Assets/Scripts/Compute Helpers/GPU Sort/Resources/BitonicMergeSort.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4ac47673a6e7c8949acab0ae0a0070ab +ComputeShaderImporter: + externalObjects: {} + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 2D.meta b/Assets/Scripts/Sim 2D.meta new file mode 100644 index 0000000..879ece7 --- /dev/null +++ b/Assets/Scripts/Sim 2D.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 10082105529eb5e4bbcbbc3ae308bc63 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 2D/Compute.meta b/Assets/Scripts/Sim 2D/Compute.meta new file mode 100644 index 0000000..359956d --- /dev/null +++ b/Assets/Scripts/Sim 2D/Compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 394455a81bc42ac4cbb82e7567631b0b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 2D/Compute/FluidMaths2D.hlsl b/Assets/Scripts/Sim 2D/Compute/FluidMaths2D.hlsl new file mode 100644 index 0000000..97f6c07 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Compute/FluidMaths2D.hlsl @@ -0,0 +1,55 @@ +const float Poly6ScalingFactor; +const float SpikyPow3ScalingFactor; +const float SpikyPow2ScalingFactor; +const float SpikyPow3DerivativeScalingFactor; +const float SpikyPow2DerivativeScalingFactor; + +float SmoothingKernelPoly6(float dst, float radius) +{ + if (dst < radius) + { + float v = radius * radius - dst * dst; + return v * v * v * Poly6ScalingFactor; + } + return 0; +} + +float SpikyKernelPow3(float dst, float radius) +{ + if (dst < radius) + { + float v = radius - dst; + return v * v * v * SpikyPow3ScalingFactor; + } + return 0; +} + +float SpikyKernelPow2(float dst, float radius) +{ + if (dst < radius) + { + float v = radius - dst; + return v * v * SpikyPow2ScalingFactor; + } + return 0; +} + +float DerivativeSpikyPow3(float dst, float radius) +{ + if (dst <= radius) + { + float v = radius - dst; + return -v * v * SpikyPow3DerivativeScalingFactor; + } + return 0; +} + +float DerivativeSpikyPow2(float dst, float radius) +{ + if (dst <= radius) + { + float v = radius - dst; + return -v * SpikyPow2DerivativeScalingFactor; + } + return 0; +} diff --git a/Assets/Scripts/Sim 2D/Compute/FluidMaths2D.hlsl.meta b/Assets/Scripts/Sim 2D/Compute/FluidMaths2D.hlsl.meta new file mode 100644 index 0000000..94168f7 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Compute/FluidMaths2D.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8d175c48d58901e4b936f10b4ddb4476 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 2D/Compute/FluidSim2D.compute b/Assets/Scripts/Sim 2D/Compute/FluidSim2D.compute new file mode 100644 index 0000000..aedbbb1 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Compute/FluidSim2D.compute @@ -0,0 +1,341 @@ +#pragma kernel ExternalForces +#pragma kernel UpdateSpatialHash +#pragma kernel CalculateDensities +#pragma kernel CalculatePressureForce +#pragma kernel CalculateViscosity +#pragma kernel UpdatePositions + +// Includes +#include "./FluidMaths2D.hlsl" +#include "./SpatialHash.hlsl" + +static const int NumThreads = 64; + +// Buffers +RWStructuredBuffer Positions; +RWStructuredBuffer PredictedPositions; +RWStructuredBuffer Velocities; +RWStructuredBuffer Densities; // Density, Near Density +RWStructuredBuffer SpatialIndices; // used for spatial hashing +RWStructuredBuffer SpatialOffsets; // used for spatial hashing + +// Settings +const uint numParticles; +const float gravity; +const float deltaTime; +const float collisionDamping; +const float smoothingRadius; +const float targetDensity; +const float pressureMultiplier; +const float nearPressureMultiplier; +const float viscosityStrength; +const float2 boundsSize; +const float2 interactionInputPoint; +const float interactionInputStrength; +const float interactionInputRadius; + +const float2 obstacleSize; +const float2 obstacleCentre; + +float DensityKernel(float dst, float radius) +{ + return SpikyKernelPow2(dst, radius); +} + +float NearDensityKernel(float dst, float radius) +{ + return SpikyKernelPow3(dst, radius); +} + +float DensityDerivative(float dst, float radius) +{ + return DerivativeSpikyPow2(dst, radius); +} + +float NearDensityDerivative(float dst, float radius) +{ + return DerivativeSpikyPow3(dst, radius); +} + +float ViscosityKernel(float dst, float radius) +{ + return SmoothingKernelPoly6(dst, smoothingRadius); +} + +float2 CalculateDensity(float2 pos) +{ + int2 originCell = GetCell2D(pos, smoothingRadius); + float sqrRadius = smoothingRadius * smoothingRadius; + float density = 0; + float nearDensity = 0; + + // Neighbour search + for (int i = 0; i < 9; i++) + { + uint hash = HashCell2D(originCell + offsets2D[i]); + uint key = KeyFromHash(hash, numParticles); + uint currIndex = SpatialOffsets[key]; + + while (currIndex < numParticles) + { + uint3 indexData = SpatialIndices[currIndex]; + currIndex++; + // Exit if no longer looking at correct bin + if (indexData[2] != key) break; + // Skip if hash does not match + if (indexData[1] != hash) continue; + + uint neighbourIndex = indexData[0]; + float2 neighbourPos = PredictedPositions[neighbourIndex]; + float2 offsetToNeighbour = neighbourPos - pos; + float sqrDstToNeighbour = dot(offsetToNeighbour, offsetToNeighbour); + + // Skip if not within radius + if (sqrDstToNeighbour > sqrRadius) continue; + + // Calculate density and near density + float dst = sqrt(sqrDstToNeighbour); + density += DensityKernel(dst, smoothingRadius); + nearDensity += NearDensityKernel(dst, smoothingRadius); + } + } + + return float2(density, nearDensity); +} + +float PressureFromDensity(float density) +{ + return (density - targetDensity) * pressureMultiplier; +} + +float NearPressureFromDensity(float nearDensity) +{ + return nearPressureMultiplier * nearDensity; +} + +float2 ExternalForces(float2 pos, float2 velocity) +{ + // Gravity + float2 gravityAccel = float2(0, gravity); + + // Input interactions modify gravity + if (interactionInputStrength != 0) { + float2 inputPointOffset = interactionInputPoint - pos; + float sqrDst = dot(inputPointOffset, inputPointOffset); + if (sqrDst < interactionInputRadius * interactionInputRadius) + { + float dst = sqrt(sqrDst); + float edgeT = (dst / interactionInputRadius); + float centreT = 1 - edgeT; + float2 dirToCentre = inputPointOffset / dst; + + float gravityWeight = 1 - (centreT * saturate(interactionInputStrength / 10)); + float2 accel = gravityAccel * gravityWeight + dirToCentre * centreT * interactionInputStrength; + accel -= velocity * centreT; + return accel; + } + } + + return gravityAccel; +} + + +void HandleCollisions(uint particleIndex) +{ + float2 pos = Positions[particleIndex]; + float2 vel = Velocities[particleIndex]; + + // Keep particle inside bounds + const float2 halfSize = boundsSize * 0.5; + float2 edgeDst = halfSize - abs(pos); + + if (edgeDst.x <= 0) + { + pos.x = halfSize.x * sign(pos.x); + vel.x *= -1 * collisionDamping; + } + if (edgeDst.y <= 0) + { + pos.y = halfSize.y * sign(pos.y); + vel.y *= -1 * collisionDamping; + } + + // Collide particle against the test obstacle + const float2 obstacleHalfSize = obstacleSize * 0.5; + float2 obstacleEdgeDst = obstacleHalfSize - abs(pos - obstacleCentre); + + if (obstacleEdgeDst.x >= 0 && obstacleEdgeDst.y >= 0) + { + if (obstacleEdgeDst.x < obstacleEdgeDst.y) { + pos.x = obstacleHalfSize.x * sign(pos.x - obstacleCentre.x) + obstacleCentre.x; + vel.x *= -1 * collisionDamping; + } + else { + pos.y = obstacleHalfSize.y * sign(pos.y - obstacleCentre.y) + obstacleCentre.y; + vel.y *= -1 * collisionDamping; + } + } + + // Update position and velocity + Positions[particleIndex] = pos; + Velocities[particleIndex] = vel; +} + +[numthreads(NumThreads,1,1)] +void ExternalForces(uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + // External forces (gravity and input interaction) + Velocities[id.x] += ExternalForces(Positions[id.x], Velocities[id.x]) * deltaTime; + + // Predict + const float predictionFactor = 1 / 120.0; + PredictedPositions[id.x] = Positions[id.x] + Velocities[id.x] * predictionFactor; +} + +[numthreads(NumThreads,1,1)] +void UpdateSpatialHash (uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + // Reset offsets + SpatialOffsets[id.x] = numParticles; + // Update index buffer + uint index = id.x; + int2 cell = GetCell2D(PredictedPositions[index], smoothingRadius); + uint hash = HashCell2D(cell); + uint key = KeyFromHash(hash, numParticles); + SpatialIndices[id.x] = uint3(index, hash, key); +} + +[numthreads(NumThreads,1,1)] +void CalculateDensities (uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + float2 pos = PredictedPositions[id.x]; + Densities[id.x] = CalculateDensity(pos); +} + +[numthreads(NumThreads,1,1)] +void CalculatePressureForce (uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + float density = Densities[id.x][0]; + float densityNear = Densities[id.x][1]; + float pressure = PressureFromDensity(density); + float nearPressure = NearPressureFromDensity(densityNear); + float2 pressureForce = 0; + + float2 pos = PredictedPositions[id.x]; + int2 originCell = GetCell2D(pos, smoothingRadius); + float sqrRadius = smoothingRadius * smoothingRadius; + + // Neighbour search + for (int i = 0; i < 9; i ++) + { + uint hash = HashCell2D(originCell + offsets2D[i]); + uint key = KeyFromHash(hash, numParticles); + uint currIndex = SpatialOffsets[key]; + + while (currIndex < numParticles) + { + uint3 indexData = SpatialIndices[currIndex]; + currIndex ++; + // Exit if no longer looking at correct bin + if (indexData[2] != key) break; + // Skip if hash does not match + if (indexData[1] != hash) continue; + + uint neighbourIndex = indexData[0]; + // Skip if looking at self + if (neighbourIndex == id.x) continue; + + float2 neighbourPos = PredictedPositions[neighbourIndex]; + float2 offsetToNeighbour = neighbourPos - pos; + float sqrDstToNeighbour = dot(offsetToNeighbour, offsetToNeighbour); + + // Skip if not within radius + if (sqrDstToNeighbour > sqrRadius) continue; + + // Calculate pressure force + float dst = sqrt(sqrDstToNeighbour); + float2 dirToNeighbour = dst > 0 ? offsetToNeighbour / dst : float2(0, 1); + + float neighbourDensity = Densities[neighbourIndex][0]; + float neighbourNearDensity = Densities[neighbourIndex][1]; + float neighbourPressure = PressureFromDensity(neighbourDensity); + float neighbourNearPressure = NearPressureFromDensity(neighbourNearDensity); + + float sharedPressure = (pressure + neighbourPressure) * 0.5; + float sharedNearPressure = (nearPressure + neighbourNearPressure) * 0.5; + + pressureForce += dirToNeighbour * DensityDerivative(dst, smoothingRadius) * sharedPressure / neighbourDensity; + pressureForce += dirToNeighbour * NearDensityDerivative(dst, smoothingRadius) * sharedNearPressure / neighbourNearDensity; + } + } + + float2 acceleration = pressureForce / density; + Velocities[id.x] += acceleration * deltaTime;// +} + + + +[numthreads(NumThreads,1,1)] +void CalculateViscosity (uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + + float2 pos = PredictedPositions[id.x]; + int2 originCell = GetCell2D(pos, smoothingRadius); + float sqrRadius = smoothingRadius * smoothingRadius; + + float2 viscosityForce = 0; + float2 velocity = Velocities[id.x]; + + for (int i = 0; i < 9; i ++) + { + uint hash = HashCell2D(originCell + offsets2D[i]); + uint key = KeyFromHash(hash, numParticles); + uint currIndex = SpatialOffsets[key]; + + while (currIndex < numParticles) + { + uint3 indexData = SpatialIndices[currIndex]; + currIndex ++; + // Exit if no longer looking at correct bin + if (indexData[2] != key) break; + // Skip if hash does not match + if (indexData[1] != hash) continue; + + uint neighbourIndex = indexData[0]; + // Skip if looking at self + if (neighbourIndex == id.x) continue; + + float2 neighbourPos = PredictedPositions[neighbourIndex]; + float2 offsetToNeighbour = neighbourPos - pos; + float sqrDstToNeighbour = dot(offsetToNeighbour, offsetToNeighbour); + + // Skip if not within radius + if (sqrDstToNeighbour > sqrRadius) continue; + + float dst = sqrt(sqrDstToNeighbour); + float2 neighbourVelocity = Velocities[neighbourIndex]; + viscosityForce += (neighbourVelocity - velocity) * ViscosityKernel(dst, smoothingRadius); + } + + } + Velocities[id.x] += viscosityForce * viscosityStrength * deltaTime; +} + +[numthreads(NumThreads, 1, 1)] +void UpdatePositions(uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + Positions[id.x] += Velocities[id.x] * deltaTime; + HandleCollisions(id.x); +} \ No newline at end of file diff --git a/Assets/Scripts/Sim 2D/Compute/FluidSim2D.compute.meta b/Assets/Scripts/Sim 2D/Compute/FluidSim2D.compute.meta new file mode 100644 index 0000000..4cb1949 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Compute/FluidSim2D.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1c77ce8de78fddb419ed2d15cae41af0 +ComputeShaderImporter: + externalObjects: {} + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 2D/Compute/SpatialHash.hlsl b/Assets/Scripts/Sim 2D/Compute/SpatialHash.hlsl new file mode 100644 index 0000000..8ad8614 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Compute/SpatialHash.hlsl @@ -0,0 +1,36 @@ +static const int2 offsets2D[9] = +{ + int2(-1, 1), + int2(0, 1), + int2(1, 1), + int2(-1, 0), + int2(0, 0), + int2(1, 0), + int2(-1, -1), + int2(0, -1), + int2(1, -1), +}; + +// Constants used for hashing +static const uint hashK1 = 15823; +static const uint hashK2 = 9737333; + +// Convert floating point position into an integer cell coordinate +int2 GetCell2D(float2 position, float radius) +{ + return (int2)floor(position / radius); +} + +// Hash cell coordinate to a single unsigned integer +uint HashCell2D(int2 cell) +{ + cell = (uint2)cell; + uint a = cell.x * hashK1; + uint b = cell.y * hashK2; + return (a + b); +} + +uint KeyFromHash(uint hash, uint tableSize) +{ + return hash % tableSize; +} diff --git a/Assets/Scripts/Sim 2D/Compute/SpatialHash.hlsl.meta b/Assets/Scripts/Sim 2D/Compute/SpatialHash.hlsl.meta new file mode 100644 index 0000000..3103990 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Compute/SpatialHash.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 086ddce26edf5ab419e75850d3c8f7da +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 2D/Display.meta b/Assets/Scripts/Sim 2D/Display.meta new file mode 100644 index 0000000..d7f69c6 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Display.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 52511ca163f9b9a46a7ca343af4991d6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 2D/Display/Particle2D.shader b/Assets/Scripts/Sim 2D/Display/Particle2D.shader new file mode 100644 index 0000000..4c7c7f2 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Display/Particle2D.shader @@ -0,0 +1,70 @@ +Shader "Instanced/Particle2D" { + Properties { + + } + SubShader { + + Tags { "RenderType"="Transparent" "Queue"="Transparent" } + Blend SrcAlpha OneMinusSrcAlpha + ZWrite Off + + Pass { + + CGPROGRAM + + #pragma vertex vert + #pragma fragment frag + #pragma target 4.5 + + #include "UnityCG.cginc" + + StructuredBuffer Positions2D; + StructuredBuffer Velocities; + StructuredBuffer DensityData; + float scale; + float4 colA; + Texture2D ColourMap; + SamplerState linear_clamp_sampler; + float velocityMax; + + struct v2f + { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float3 colour : TEXCOORD1; + }; + + v2f vert (appdata_full v, uint instanceID : SV_InstanceID) + { + float speed = length(Velocities[instanceID]); + float speedT = saturate(speed / velocityMax); + float colT = speedT; + + float3 centreWorld = float3(Positions2D[instanceID], 0); + float3 worldVertPos = centreWorld + mul(unity_ObjectToWorld, v.vertex * scale); + float3 objectVertPos = mul(unity_WorldToObject, float4(worldVertPos.xyz, 1)); + + v2f o; + o.uv = v.texcoord; + o.pos = UnityObjectToClipPos(objectVertPos); + o.colour = ColourMap.SampleLevel(linear_clamp_sampler, float2(colT, 0.5), 0); + + return o; + } + + + float4 frag (v2f i) : SV_Target + { + float2 centreOffset = (i.uv.xy - 0.5) * 2; + float sqrDst = dot(centreOffset, centreOffset); + float delta = fwidth(sqrt(sqrDst)); + float alpha = 1 - smoothstep(1 - delta, 1 + delta, sqrDst); + + float3 colour = i.colour; + return float4(colour, alpha); + } + + ENDCG + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Sim 2D/Display/Particle2D.shader.meta b/Assets/Scripts/Sim 2D/Display/Particle2D.shader.meta new file mode 100644 index 0000000..090d1e0 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Display/Particle2D.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 441b7193936682446b30d2140d15792a +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 2D/Display/ParticleDisplayGPU.cs b/Assets/Scripts/Sim 2D/Display/ParticleDisplayGPU.cs new file mode 100644 index 0000000..805b306 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Display/ParticleDisplayGPU.cs @@ -0,0 +1,92 @@ +using UnityEngine; + +public class ParticleDisplay2D : MonoBehaviour +{ + public Mesh mesh; + public Shader shader; + public float scale; + public Gradient colourMap; + public int gradientResolution; + public float velocityDisplayMax; + + Material material; + ComputeBuffer argsBuffer; + Bounds bounds; + Texture2D gradientTexture; + bool needsUpdate; + + + public void Init(Simulation2D sim) + { + material = new Material(shader); + material.SetBuffer("Positions2D", sim.positionBuffer); + material.SetBuffer("Velocities", sim.velocityBuffer); + material.SetBuffer("DensityData", sim.densityBuffer); + + argsBuffer = ComputeHelper.CreateArgsBuffer(mesh, sim.positionBuffer.count); + bounds = new Bounds(Vector3.zero, Vector3.one * 10000); + } + + void LateUpdate() + { + if (shader != null) + { + UpdateSettings(); + Graphics.DrawMeshInstancedIndirect(mesh, 0, material, bounds, argsBuffer); + } + } + + void UpdateSettings() + { + if (needsUpdate) + { + needsUpdate = false; + TextureFromGradient(ref gradientTexture, gradientResolution, colourMap); + material.SetTexture("ColourMap", gradientTexture); + + material.SetFloat("scale", scale); + material.SetFloat("velocityMax", velocityDisplayMax); + } + } + + public static void TextureFromGradient(ref Texture2D texture, int width, Gradient gradient, FilterMode filterMode = FilterMode.Bilinear) + { + if (texture == null) + { + texture = new Texture2D(width, 1); + } + else if (texture.width != width) + { + texture.Reinitialize(width, 1); + } + if (gradient == null) + { + gradient = new Gradient(); + gradient.SetKeys( + new GradientColorKey[] { new GradientColorKey(Color.black, 0), new GradientColorKey(Color.black, 1) }, + new GradientAlphaKey[] { new GradientAlphaKey(1, 0), new GradientAlphaKey(1, 1) } + ); + } + texture.wrapMode = TextureWrapMode.Clamp; + texture.filterMode = filterMode; + + Color[] cols = new Color[width]; + for (int i = 0; i < cols.Length; i++) + { + float t = i / (cols.Length - 1f); + cols[i] = gradient.Evaluate(t); + } + texture.SetPixels(cols); + texture.Apply(); + } + + void OnValidate() + { + needsUpdate = true; + } + + void OnDestroy() + { + ComputeHelper.Release(argsBuffer); + } +} diff --git a/Assets/Scripts/Sim 2D/Display/ParticleDisplayGPU.cs.meta b/Assets/Scripts/Sim 2D/Display/ParticleDisplayGPU.cs.meta new file mode 100644 index 0000000..bc07598 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Display/ParticleDisplayGPU.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b090cee05a6cd0e4291a0e02381231c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 2D/ParticleSpawner.cs b/Assets/Scripts/Sim 2D/ParticleSpawner.cs new file mode 100644 index 0000000..1b9101d --- /dev/null +++ b/Assets/Scripts/Sim 2D/ParticleSpawner.cs @@ -0,0 +1,65 @@ +using UnityEngine; +using Unity.Mathematics; + +public class ParticleSpawner : MonoBehaviour +{ + public int particleCount; + + public Vector2 initialVelocity; + public Vector2 spawnCentre; + public Vector2 spawnSize; + public float jitterStr; + public bool showSpawnBoundsGizmos; + + public ParticleSpawnData GetSpawnData() + { + ParticleSpawnData data = new ParticleSpawnData(particleCount); + var rng = new Unity.Mathematics.Random(42); + + float2 s = spawnSize; + int numX = Mathf.CeilToInt(Mathf.Sqrt(s.x / s.y * particleCount + (s.x - s.y) * (s.x - s.y) / (4 * s.y * s.y)) - (s.x - s.y) / (2 * s.y)); + int numY = Mathf.CeilToInt(particleCount / (float)numX); + int i = 0; + + for (int y = 0; y < numY; y++) + { + for (int x = 0; x < numX; x++) + { + if (i >= particleCount) break; + + float tx = numX <= 1 ? 0.5f : x / (numX - 1f); + float ty = numY <= 1 ? 0.5f : y / (numY - 1f); + + float angle = (float)rng.NextDouble() * 3.14f * 2; + Vector2 dir = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)); + Vector2 jitter = dir * jitterStr * ((float)rng.NextDouble() - 0.5f); + data.positions[i] = new Vector2((tx - 0.5f) * spawnSize.x, (ty - 0.5f) * spawnSize.y) + jitter + spawnCentre; + data.velocities[i] = initialVelocity; + i++; + } + } + + return data; + } + + public struct ParticleSpawnData + { + public float2[] positions; + public float2[] velocities; + + public ParticleSpawnData(int num) + { + positions = new float2[num]; + velocities = new float2[num]; + } + } + + void OnDrawGizmos() + { + if (showSpawnBoundsGizmos && !Application.isPlaying) + { + Gizmos.color = new Color(1, 1, 0, 0.5f); + Gizmos.DrawWireCube(spawnCentre, Vector2.one * spawnSize); + } + } +} diff --git a/Assets/Scripts/Sim 2D/ParticleSpawner.cs.meta b/Assets/Scripts/Sim 2D/ParticleSpawner.cs.meta new file mode 100644 index 0000000..5e0298f --- /dev/null +++ b/Assets/Scripts/Sim 2D/ParticleSpawner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 895837b52d5fc53409ded3589d4da696 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 2D/Simulation2D.cs b/Assets/Scripts/Sim 2D/Simulation2D.cs new file mode 100644 index 0000000..28712d6 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Simulation2D.cs @@ -0,0 +1,244 @@ +using UnityEngine; +using Unity.Mathematics; + +public class Simulation2D : MonoBehaviour +{ + public event System.Action SimulationStepCompleted; + + [Header("Simulation Settings")] + public float timeScale = 1; + public bool fixedTimeStep; + public int iterationsPerFrame; + public float gravity; + [Range(0, 1)] public float collisionDamping = 0.95f; + public float smoothingRadius = 2; + public float targetDensity; + public float pressureMultiplier; + public float nearPressureMultiplier; + public float viscosityStrength; + public Vector2 boundsSize; + public Vector2 obstacleSize; + public Vector2 obstacleCentre; + + [Header("Interaction Settings")] + public float interactionRadius; + public float interactionStrength; + + [Header("References")] + public ComputeShader compute; + public ParticleSpawner spawner; + public ParticleDisplay2D display; + + // Buffers + public ComputeBuffer positionBuffer { get; private set; } + public ComputeBuffer velocityBuffer { get; private set; } + public ComputeBuffer densityBuffer { get; private set; } + ComputeBuffer predictedPositionBuffer; + ComputeBuffer spatialIndices; + ComputeBuffer spatialOffsets; + GPUSort gpuSort; + + // Kernel IDs + const int externalForcesKernel = 0; + const int spatialHashKernel = 1; + const int densityKernel = 2; + const int pressureKernel = 3; + const int viscosityKernel = 4; + const int updatePositionKernel = 5; + + // State + bool isPaused; + ParticleSpawner.ParticleSpawnData spawnData; + bool pauseNextFrame; + + public int numParticles { get; private set; } + + + void Start() + { + Debug.Log("Controls: Space = Play/Pause, R = Reset, LMB = Attract, RMB = Repel"); + + float deltaTime = 1 / 60f; + Time.fixedDeltaTime = deltaTime; + + spawnData = spawner.GetSpawnData(); + numParticles = spawnData.positions.Length; + + // Create buffers + positionBuffer = ComputeHelper.CreateStructuredBuffer(numParticles); + predictedPositionBuffer = ComputeHelper.CreateStructuredBuffer(numParticles); + velocityBuffer = ComputeHelper.CreateStructuredBuffer(numParticles); + densityBuffer = ComputeHelper.CreateStructuredBuffer(numParticles); + spatialIndices = ComputeHelper.CreateStructuredBuffer(numParticles); + spatialOffsets = ComputeHelper.CreateStructuredBuffer(numParticles); + + // Set buffer data + SetInitialBufferData(spawnData); + + // Init compute + ComputeHelper.SetBuffer(compute, positionBuffer, "Positions", externalForcesKernel, updatePositionKernel); + ComputeHelper.SetBuffer(compute, predictedPositionBuffer, "PredictedPositions", externalForcesKernel, spatialHashKernel, densityKernel, pressureKernel, viscosityKernel); + ComputeHelper.SetBuffer(compute, spatialIndices, "SpatialIndices", spatialHashKernel, densityKernel, pressureKernel, viscosityKernel); + ComputeHelper.SetBuffer(compute, spatialOffsets, "SpatialOffsets", spatialHashKernel, densityKernel, pressureKernel, viscosityKernel); + ComputeHelper.SetBuffer(compute, densityBuffer, "Densities", densityKernel, pressureKernel, viscosityKernel); + ComputeHelper.SetBuffer(compute, velocityBuffer, "Velocities", externalForcesKernel, pressureKernel, viscosityKernel, updatePositionKernel); + + compute.SetInt("numParticles", numParticles); + + gpuSort = new(); + gpuSort.SetBuffers(spatialIndices, spatialOffsets); + + + // Init display + display.Init(this); + } + + void FixedUpdate() + { + if (fixedTimeStep) + { + RunSimulationFrame(Time.fixedDeltaTime); + } + } + + void Update() + { + // Run simulation if not in fixed timestep mode + // (skip running for first few frames as deltaTime can be disproportionaly large) + if (!fixedTimeStep && Time.frameCount > 10) + { + RunSimulationFrame(Time.deltaTime); + } + + if (pauseNextFrame) + { + isPaused = true; + pauseNextFrame = false; + } + + HandleInput(); + } + + void RunSimulationFrame(float frameTime) + { + if (!isPaused) + { + float timeStep = frameTime / iterationsPerFrame * timeScale; + + UpdateSettings(timeStep); + + for (int i = 0; i < iterationsPerFrame; i++) + { + RunSimulationStep(); + SimulationStepCompleted?.Invoke(); + } + } + } + + void RunSimulationStep() + { + ComputeHelper.Dispatch(compute, numParticles, kernelIndex: externalForcesKernel); + ComputeHelper.Dispatch(compute, numParticles, kernelIndex: spatialHashKernel); + gpuSort.SortAndCalculateOffsets(); + ComputeHelper.Dispatch(compute, numParticles, kernelIndex: densityKernel); + ComputeHelper.Dispatch(compute, numParticles, kernelIndex: pressureKernel); + ComputeHelper.Dispatch(compute, numParticles, kernelIndex: viscosityKernel); + ComputeHelper.Dispatch(compute, numParticles, kernelIndex: updatePositionKernel); + + } + + void UpdateSettings(float deltaTime) + { + compute.SetFloat("deltaTime", deltaTime); + compute.SetFloat("gravity", gravity); + compute.SetFloat("collisionDamping", collisionDamping); + compute.SetFloat("smoothingRadius", smoothingRadius); + compute.SetFloat("targetDensity", targetDensity); + compute.SetFloat("pressureMultiplier", pressureMultiplier); + compute.SetFloat("nearPressureMultiplier", nearPressureMultiplier); + compute.SetFloat("viscosityStrength", viscosityStrength); + compute.SetVector("boundsSize", boundsSize); + compute.SetVector("obstacleSize", obstacleSize); + compute.SetVector("obstacleCentre", obstacleCentre); + + compute.SetFloat("Poly6ScalingFactor", 4 / (Mathf.PI * Mathf.Pow(smoothingRadius, 8))); + compute.SetFloat("SpikyPow3ScalingFactor", 10 / (Mathf.PI * Mathf.Pow(smoothingRadius, 5))); + compute.SetFloat("SpikyPow2ScalingFactor", 6 / (Mathf.PI * Mathf.Pow(smoothingRadius, 4))); + compute.SetFloat("SpikyPow3DerivativeScalingFactor", 30 / (Mathf.Pow(smoothingRadius, 5) * Mathf.PI)); + compute.SetFloat("SpikyPow2DerivativeScalingFactor", 12 / (Mathf.Pow(smoothingRadius, 4) * Mathf.PI)); + + // Mouse interaction settings: + Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); + bool isPullInteraction = Input.GetMouseButton(0); + bool isPushInteraction = Input.GetMouseButton(1); + float currInteractStrength = 0; + if (isPushInteraction || isPullInteraction) + { + currInteractStrength = isPushInteraction ? -interactionStrength : interactionStrength; + } + + compute.SetVector("interactionInputPoint", mousePos); + compute.SetFloat("interactionInputStrength", currInteractStrength); + compute.SetFloat("interactionInputRadius", interactionRadius); + } + + void SetInitialBufferData(ParticleSpawner.ParticleSpawnData spawnData) + { + float2[] allPoints = new float2[spawnData.positions.Length]; + System.Array.Copy(spawnData.positions, allPoints, spawnData.positions.Length); + + positionBuffer.SetData(allPoints); + predictedPositionBuffer.SetData(allPoints); + velocityBuffer.SetData(spawnData.velocities); + } + + void HandleInput() + { + if (Input.GetKeyDown(KeyCode.Space)) + { + isPaused = !isPaused; + } + if (Input.GetKeyDown(KeyCode.RightArrow)) + { + isPaused = false; + pauseNextFrame = true; + } + + if (Input.GetKeyDown(KeyCode.R)) + { + isPaused = true; + // Reset positions, the run single frame to get density etc (for debug purposes) and then reset positions again + SetInitialBufferData(spawnData); + RunSimulationStep(); + SetInitialBufferData(spawnData); + } + } + + + void OnDestroy() + { + ComputeHelper.Release(positionBuffer, predictedPositionBuffer, velocityBuffer, densityBuffer, spatialIndices, spatialOffsets); + } + + + void OnDrawGizmos() + { + Gizmos.color = new Color(0, 1, 0, 0.4f); + Gizmos.DrawWireCube(Vector2.zero, boundsSize); + Gizmos.DrawWireCube(obstacleCentre, obstacleSize); + + if (Application.isPlaying) + { + Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); + bool isPullInteraction = Input.GetMouseButton(0); + bool isPushInteraction = Input.GetMouseButton(1); + bool isInteracting = isPullInteraction || isPushInteraction; + if (isInteracting) + { + Gizmos.color = isPullInteraction ? Color.green : Color.red; + Gizmos.DrawWireSphere(mousePos, interactionRadius); + } + } + + } +} diff --git a/Assets/Scripts/Sim 2D/Simulation2D.cs.meta b/Assets/Scripts/Sim 2D/Simulation2D.cs.meta new file mode 100644 index 0000000..94c2a53 --- /dev/null +++ b/Assets/Scripts/Sim 2D/Simulation2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf901970f9cf132479a879d7a4acde3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D.meta b/Assets/Scripts/Sim 3D.meta new file mode 100644 index 0000000..c9f4231 --- /dev/null +++ b/Assets/Scripts/Sim 3D.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d512adafd69830d44aa4ef97eb5e2bb1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Compute.meta b/Assets/Scripts/Sim 3D/Compute.meta new file mode 100644 index 0000000..0716689 --- /dev/null +++ b/Assets/Scripts/Sim 3D/Compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1a85826ec8ddbe744b47c9780241f05d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Compute/FluidMaths3D.hlsl b/Assets/Scripts/Sim 3D/Compute/FluidMaths3D.hlsl new file mode 100644 index 0000000..88c892d --- /dev/null +++ b/Assets/Scripts/Sim 3D/Compute/FluidMaths3D.hlsl @@ -0,0 +1,85 @@ +static const float PI = 3.1415926; + + +// 3d conversion: done +float SmoothingKernelPoly6(float dst, float radius) +{ + if (dst < radius) + { + float scale = 315 / (64 * PI * pow(abs(radius), 9)); + float v = radius * radius - dst * dst; + return v * v * v * scale; + } + return 0; +} + +// 3d conversion: done +float SpikyKernelPow3(float dst, float radius) +{ + if (dst < radius) + { + float scale = 15 / (PI * pow(radius, 6)); + float v = radius - dst; + return v * v * v * scale; + } + return 0; +} + +// 3d conversion: done +//Integrate[(h-r)^2 r^2 Sin[θ], {r, 0, h}, {θ, 0, π}, {φ, 0, 2*π}] +float SpikyKernelPow2(float dst, float radius) +{ + if (dst < radius) + { + float scale = 15 / (2 * PI * pow(radius, 5)); + float v = radius - dst; + return v * v * scale; + } + return 0; +} + +// 3d conversion: done +float DerivativeSpikyPow3(float dst, float radius) +{ + if (dst <= radius) + { + float scale = 45 / (pow(radius, 6) * PI); + float v = radius - dst; + return -v * v * scale; + } + return 0; +} + +// 3d conversion: done +float DerivativeSpikyPow2(float dst, float radius) +{ + if (dst <= radius) + { + float scale = 15 / (pow(radius, 5) * PI); + float v = radius - dst; + return -v * scale; + } + return 0; +} + +float DensityKernel(float dst, float radius) +{ + //return SmoothingKernelPoly6(dst, radius); + return SpikyKernelPow2(dst, radius); +} + +float NearDensityKernel(float dst, float radius) +{ + return SpikyKernelPow3(dst, radius); +} + +float DensityDerivative(float dst, float radius) +{ + return DerivativeSpikyPow2(dst, radius); +} + +float NearDensityDerivative(float dst, float radius) +{ + return DerivativeSpikyPow3(dst, radius); +} + diff --git a/Assets/Scripts/Sim 3D/Compute/FluidMaths3D.hlsl.meta b/Assets/Scripts/Sim 3D/Compute/FluidMaths3D.hlsl.meta new file mode 100644 index 0000000..2cdceac --- /dev/null +++ b/Assets/Scripts/Sim 3D/Compute/FluidMaths3D.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 75a23083591d785478d81b0b53b735a6 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Compute/FluidSim3D.compute b/Assets/Scripts/Sim 3D/Compute/FluidSim3D.compute new file mode 100644 index 0000000..c6324ab --- /dev/null +++ b/Assets/Scripts/Sim 3D/Compute/FluidSim3D.compute @@ -0,0 +1,280 @@ +#pragma kernel ExternalForces +#pragma kernel UpdateSpatialHash +#pragma kernel CalculateDensities +#pragma kernel CalculatePressureForce +#pragma kernel CalculateViscosity +#pragma kernel UpdatePositions + +// Includes +#include "./FluidMaths3D.hlsl" +#include "./SpatialHash3D.hlsl" + +static const int NumThreads = 64; + +// Buffers +RWStructuredBuffer Positions; +RWStructuredBuffer PredictedPositions; +RWStructuredBuffer Velocities; +RWStructuredBuffer Densities; // Density, Near Density +RWStructuredBuffer SpatialIndices; // used for spatial hashing +RWStructuredBuffer SpatialOffsets; // used for spatial hashing + +// Settings +const uint numParticles; +const float gravity; +const float deltaTime; +const float collisionDamping; +const float smoothingRadius; +const float targetDensity; +const float pressureMultiplier; +const float nearPressureMultiplier; +const float viscosityStrength; +const float edgeForce; +const float edgeForceDst; +const float3 boundsSize; +const float3 centre; + +const float4x4 localToWorld; +const float4x4 worldToLocal; + +const float2 interactionInputPoint; +const float interactionInputStrength; +const float interactionInputRadius; + +float PressureFromDensity(float density) +{ + return (density - targetDensity) * pressureMultiplier; +} + +float NearPressureFromDensity(float nearDensity) +{ + return nearDensity * nearPressureMultiplier; +} + +void ResolveCollisions(uint particleIndex) +{ + // Transform position/velocity to the local space of the bounding box (scale not included) + float3 posLocal = mul(worldToLocal, float4(Positions[particleIndex], 1)).xyz; + float3 velocityLocal = mul(worldToLocal, float4(Velocities[particleIndex], 0)).xyz; + + // Calculate distance from box on each axis (negative values are inside box) + const float3 halfSize = 0.5; + const float3 edgeDst = halfSize - abs(posLocal); + + // Resolve collisions + if (edgeDst.x <= 0) + { + posLocal.x = halfSize.x * sign(posLocal.x); + velocityLocal.x *= -1 * collisionDamping; + } + if (edgeDst.y <= 0) + { + posLocal.y = halfSize.y * sign(posLocal.y); + velocityLocal.y *= -1 * collisionDamping; + } + if (edgeDst.z <= 0) + { + posLocal.z = halfSize.z * sign(posLocal.z); + velocityLocal.z *= -1 * collisionDamping; + } + + // Transform resolved position/velocity back to world space + Positions[particleIndex] = mul(localToWorld, float4(posLocal, 1)).xyz; + Velocities[particleIndex] = mul(localToWorld, float4(velocityLocal, 0)).xyz; + +} + +[numthreads(NumThreads,1,1)] +void ExternalForces (uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + // External forces (gravity) + Velocities[id.x] += float3(0, gravity, 0) * deltaTime; + + // Predict + PredictedPositions[id.x] = Positions[id.x] + Velocities[id.x] * 1 / 120.0; +} + +[numthreads(NumThreads,1,1)] +void UpdateSpatialHash (uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + // Reset offsets + SpatialOffsets[id.x] = numParticles; + // Update index buffer + uint index = id.x; + int3 cell = GetCell3D(PredictedPositions[index], smoothingRadius); + uint hash = HashCell3D(cell); + uint key = KeyFromHash(hash, numParticles); + SpatialIndices[id.x] = uint3(index, hash, key); +} + +[numthreads(NumThreads,1,1)] +void CalculateDensities (uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + float3 pos = PredictedPositions[id.x]; + int3 originCell = GetCell3D(pos, smoothingRadius); + float sqrRadius = smoothingRadius * smoothingRadius; + float density = 0; + float nearDensity = 0; + + // Neighbour search + for (int i = 0; i < 27; i ++) + { + uint hash = HashCell3D(originCell + offsets3D[i]); + uint key = KeyFromHash(hash, numParticles); + uint currIndex = SpatialOffsets[key]; + + while (currIndex < numParticles) + { + uint3 indexData = SpatialIndices[currIndex]; + currIndex ++; + // Exit if no longer looking at correct bin + if (indexData[2] != key) break; + // Skip if hash does not match + if (indexData[1] != hash) continue; + + uint neighbourIndex = indexData[0]; + float3 neighbourPos = PredictedPositions[neighbourIndex]; + float3 offsetToNeighbour = neighbourPos - pos; + float sqrDstToNeighbour = dot(offsetToNeighbour, offsetToNeighbour); + + // Skip if not within radius + if (sqrDstToNeighbour > sqrRadius) continue; + + // Calculate density and near density + float dst = sqrt(sqrDstToNeighbour); + density += DensityKernel(dst, smoothingRadius); + nearDensity += NearDensityKernel(dst, smoothingRadius); + } + } + + Densities[id.x] = float2(density, nearDensity); +} + +[numthreads(NumThreads,1,1)] +void CalculatePressureForce (uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + // Calculate pressure + float density = Densities[id.x][0]; + float densityNear = Densities[id.x][1]; + float pressure = PressureFromDensity(density); + float nearPressure = NearPressureFromDensity(densityNear); + float3 pressureForce = 0; + + float3 pos = PredictedPositions[id.x]; + int3 originCell = GetCell3D(pos, smoothingRadius); + float sqrRadius = smoothingRadius * smoothingRadius; + + // Neighbour search + for (int i = 0; i < 27; i ++) + { + uint hash = HashCell3D(originCell + offsets3D[i]); + uint key = KeyFromHash(hash, numParticles); + uint currIndex = SpatialOffsets[key]; + + while (currIndex < numParticles) + { + uint3 indexData = SpatialIndices[currIndex]; + currIndex ++; + // Exit if no longer looking at correct bin + if (indexData[2] != key) break; + // Skip if hash does not match + if (indexData[1] != hash) continue; + + uint neighbourIndex = indexData[0]; + // Skip if looking at self + if (neighbourIndex == id.x) continue; + + float3 neighbourPos = PredictedPositions[neighbourIndex]; + float3 offsetToNeighbour = neighbourPos - pos; + float sqrDstToNeighbour = dot(offsetToNeighbour, offsetToNeighbour); + + // Skip if not within radius + if (sqrDstToNeighbour > sqrRadius) continue; + + // Calculate pressure force + float densityNeighbour = Densities[neighbourIndex][0]; + float nearDensityNeighbour = Densities[neighbourIndex][1]; + float neighbourPressure = PressureFromDensity(densityNeighbour); + float neighbourPressureNear = NearPressureFromDensity(nearDensityNeighbour); + + float sharedPressure = (pressure + neighbourPressure) / 2; + float sharedNearPressure = (nearPressure + neighbourPressureNear) / 2; + + float dst = sqrt(sqrDstToNeighbour); + float3 dir = dst > 0 ? offsetToNeighbour / dst : float3(0, 1, 0); + + pressureForce += dir * DensityDerivative(dst, smoothingRadius) * sharedPressure / densityNeighbour; + pressureForce += dir * NearDensityDerivative(dst, smoothingRadius) * sharedNearPressure / nearDensityNeighbour; + } + } + + float3 acceleration = pressureForce / density; + Velocities[id.x] += acceleration * deltaTime; +} + + +[numthreads(NumThreads,1,1)] +void CalculateViscosity (uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + float3 pos = PredictedPositions[id.x]; + int3 originCell = GetCell3D(pos, smoothingRadius); + float sqrRadius = smoothingRadius * smoothingRadius; + + float3 viscosityForce = 0; + float3 velocity = Velocities[id.x]; + + // Neighbour search + for (int i = 0; i < 27; i ++) + { + uint hash = HashCell3D(originCell + offsets3D[i]); + uint key = KeyFromHash(hash, numParticles); + uint currIndex = SpatialOffsets[key]; + + while (currIndex < numParticles) + { + uint3 indexData = SpatialIndices[currIndex]; + currIndex ++; + // Exit if no longer looking at correct bin + if (indexData[2] != key) break; + // Skip if hash does not match + if (indexData[1] != hash) continue; + + uint neighbourIndex = indexData[0]; + // Skip if looking at self + if (neighbourIndex == id.x) continue; + + float3 neighbourPos = PredictedPositions[neighbourIndex]; + float3 offsetToNeighbour = neighbourPos - pos; + float sqrDstToNeighbour = dot(offsetToNeighbour, offsetToNeighbour); + + // Skip if not within radius + if (sqrDstToNeighbour > sqrRadius) continue; + + // Calculate viscosity + float dst = sqrt(sqrDstToNeighbour); + float3 neighbourVelocity = Velocities[neighbourIndex]; + viscosityForce += (neighbourVelocity - velocity) * SmoothingKernelPoly6(dst, smoothingRadius); + } + + Velocities[id.x] += viscosityForce * viscosityStrength * deltaTime; + } +} + +[numthreads(NumThreads, 1, 1)] +void UpdatePositions(uint3 id : SV_DispatchThreadID) +{ + if (id.x >= numParticles) return; + + Positions[id.x] += Velocities[id.x] * deltaTime; + ResolveCollisions(id.x); +} \ No newline at end of file diff --git a/Assets/Scripts/Sim 3D/Compute/FluidSim3D.compute.meta b/Assets/Scripts/Sim 3D/Compute/FluidSim3D.compute.meta new file mode 100644 index 0000000..97758e2 --- /dev/null +++ b/Assets/Scripts/Sim 3D/Compute/FluidSim3D.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9443696acfd0ebe4fb503b56d952256c +ComputeShaderImporter: + externalObjects: {} + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Compute/SpatialHash3D.hlsl b/Assets/Scripts/Sim 3D/Compute/SpatialHash3D.hlsl new file mode 100644 index 0000000..3299e27 --- /dev/null +++ b/Assets/Scripts/Sim 3D/Compute/SpatialHash3D.hlsl @@ -0,0 +1,53 @@ +static const int3 offsets3D[27] = +{ + int3(-1, -1, -1), + int3(-1, -1, 0), + int3(-1, -1, 1), + int3(-1, 0, -1), + int3(-1, 0, 0), + int3(-1, 0, 1), + int3(-1, 1, -1), + int3(-1, 1, 0), + int3(-1, 1, 1), + int3(0, -1, -1), + int3(0, -1, 0), + int3(0, -1, 1), + int3(0, 0, -1), + int3(0, 0, 0), + int3(0, 0, 1), + int3(0, 1, -1), + int3(0, 1, 0), + int3(0, 1, 1), + int3(1, -1, -1), + int3(1, -1, 0), + int3(1, -1, 1), + int3(1, 0, -1), + int3(1, 0, 0), + int3(1, 0, 1), + int3(1, 1, -1), + int3(1, 1, 0), + int3(1, 1, 1) +}; + +// Constants used for hashing +static const uint hashK1 = 15823; +static const uint hashK2 = 9737333; +static const uint hashK3 = 440817757; + +// Convert floating point position into an integer cell coordinate +int3 GetCell3D(float3 position, float radius) +{ + return (int3)floor(position / radius); +} + +// Hash cell coordinate to a single unsigned integer +uint HashCell3D(int3 cell) +{ + cell = (uint3) cell; + return (cell.x * hashK1) + (cell.y * hashK2) + (cell.z * hashK3); +} + +uint KeyFromHash(uint hash, uint tableSize) +{ + return hash % tableSize; +} diff --git a/Assets/Scripts/Sim 3D/Compute/SpatialHash3D.hlsl.meta b/Assets/Scripts/Sim 3D/Compute/SpatialHash3D.hlsl.meta new file mode 100644 index 0000000..b0e79b7 --- /dev/null +++ b/Assets/Scripts/Sim 3D/Compute/SpatialHash3D.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ae252084b97b70f4f91124f8f5fdfaf1 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Display.meta b/Assets/Scripts/Sim 3D/Display.meta new file mode 100644 index 0000000..baa3b79 --- /dev/null +++ b/Assets/Scripts/Sim 3D/Display.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 11398a05bc1ecdb4fafe28a4d895ddee +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Display/Particle3D.shader b/Assets/Scripts/Sim 3D/Display/Particle3D.shader new file mode 100644 index 0000000..f9eb460 --- /dev/null +++ b/Assets/Scripts/Sim 3D/Display/Particle3D.shader @@ -0,0 +1,69 @@ +Shader "Instanced/Particle3D" { + Properties { + + } + SubShader { + + Tags {"Queue"="Geometry" } + + Pass { + + CGPROGRAM + + #pragma vertex vert + #pragma fragment frag + #pragma target 4.5 + + #include "UnityCG.cginc" + + StructuredBuffer Positions; + StructuredBuffer Velocities; + Texture2D ColourMap; + SamplerState linear_clamp_sampler; + float velocityMax; + + float scale; + float3 colour; + + float4x4 localToWorld; + + struct v2f + { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + float3 colour : TEXCOORD1; + float3 normal : NORMAL; + }; + + v2f vert (appdata_full v, uint instanceID : SV_InstanceID) + { + + float3 centreWorld = Positions[instanceID]; + float3 worldVertPos = centreWorld + mul(unity_ObjectToWorld, v.vertex * scale); + float3 objectVertPos = mul(unity_WorldToObject, float4(worldVertPos.xyz, 1)); + v2f o; + o.uv = v.texcoord; + o.normal = v.normal; + + o.pos = UnityObjectToClipPos(objectVertPos); + + float speed = length(Velocities[instanceID]); + float speedT = saturate(speed / velocityMax); + float colT = speedT; + o.colour = ColourMap.SampleLevel(linear_clamp_sampler, float2(colT, 0.5), 0); + + return o; + } + + float4 frag (v2f i) : SV_Target + { + float shading = saturate(dot(_WorldSpaceLightPos0.xyz, i.normal)); + shading = (shading + 0.6) / 1.4; + //return float4(i.normal * 0.5 + 0.5, 1); + return float4(i.colour * shading, 1); + } + + ENDCG + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Sim 3D/Display/Particle3D.shader.meta b/Assets/Scripts/Sim 3D/Display/Particle3D.shader.meta new file mode 100644 index 0000000..d48e4ce --- /dev/null +++ b/Assets/Scripts/Sim 3D/Display/Particle3D.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bebe529033c51cb4f99d667ea48fa0c7 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Display/ParticleDisplay3D.cs b/Assets/Scripts/Sim 3D/Display/ParticleDisplay3D.cs new file mode 100644 index 0000000..f0fa7ec --- /dev/null +++ b/Assets/Scripts/Sim 3D/Display/ParticleDisplay3D.cs @@ -0,0 +1,72 @@ +using UnityEngine; + +public class ParticleDisplay3D : MonoBehaviour +{ + + public Shader shader; + public float scale; + Mesh mesh; + public Color col; + Material mat; + + ComputeBuffer argsBuffer; + Bounds bounds; + + public Gradient colourMap; + public int gradientResolution; + public float velocityDisplayMax; + Texture2D gradientTexture; + bool needsUpdate; + + public int meshResolution; + public int debug_MeshTriCount; + + public void Init(Simulation3D sim) + { + mat = new Material(shader); + mat.SetBuffer("Positions", sim.positionBuffer); + mat.SetBuffer("Velocities", sim.velocityBuffer); + + mesh = SebStuff.SphereGenerator.GenerateSphereMesh(meshResolution); + debug_MeshTriCount = mesh.triangles.Length / 3; + argsBuffer = ComputeHelper.CreateArgsBuffer(mesh, sim.positionBuffer.count); + bounds = new Bounds(Vector3.zero, Vector3.one * 10000); + } + + void LateUpdate() + { + + UpdateSettings(); + Graphics.DrawMeshInstancedIndirect(mesh, 0, mat, bounds, argsBuffer); + } + + void UpdateSettings() + { + if (needsUpdate) + { + needsUpdate = false; + ParticleDisplay2D.TextureFromGradient(ref gradientTexture, gradientResolution, colourMap); + mat.SetTexture("ColourMap", gradientTexture); + } + mat.SetFloat("scale", scale); + mat.SetColor("colour", col); + mat.SetFloat("velocityMax", velocityDisplayMax); + + Vector3 s = transform.localScale; + transform.localScale = Vector3.one; + var localToWorld = transform.localToWorldMatrix; + transform.localScale = s; + + mat.SetMatrix("localToWorld", localToWorld); + } + + private void OnValidate() + { + needsUpdate = true; + } + + void OnDestroy() + { + ComputeHelper.Release(argsBuffer); + } +} diff --git a/Assets/Scripts/Sim 3D/Display/ParticleDisplay3D.cs.meta b/Assets/Scripts/Sim 3D/Display/ParticleDisplay3D.cs.meta new file mode 100644 index 0000000..2e6f110 --- /dev/null +++ b/Assets/Scripts/Sim 3D/Display/ParticleDisplay3D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdfe3008efbf29745879ab1d40574478 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Display/ParticleShaded3D.shader b/Assets/Scripts/Sim 3D/Display/ParticleShaded3D.shader new file mode 100644 index 0000000..753a3c7 --- /dev/null +++ b/Assets/Scripts/Sim 3D/Display/ParticleShaded3D.shader @@ -0,0 +1,56 @@ +Shader "Instanced/ParticleShaded3D" { + Properties { + _MainTex ("Albedo (RGB)", 2D) = "white" {} + _Glossiness ("Smoothness", Range(0,1)) = 0.5 + _Metallic ("Metallic", Range(0,1)) = 0.0 + } + SubShader { + Tags { "RenderType"="Opaque" } + LOD 200 + + CGPROGRAM + #pragma surface surf Standard addshadow fullforwardshadows + #pragma multi_compile_instancing + #pragma instancing_options procedural:setup + + sampler2D _MainTex; + + struct Input { + float2 uv_MainTex; + }; + + #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED + StructuredBuffer Positions; + #endif + + float scale; + float4 colour; + + void setup() + { + #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED + float3 pos = Positions[unity_InstanceID]; + + unity_ObjectToWorld._11_21_31_41 = float4(scale, 0, 0, 0); + unity_ObjectToWorld._12_22_32_42 = float4(0, scale, 0, 0); + unity_ObjectToWorld._13_23_33_43 = float4(0, 0, scale, 0); + unity_ObjectToWorld._14_24_34_44 = float4(pos, 1); + unity_WorldToObject = unity_ObjectToWorld; + unity_WorldToObject._14_24_34 *= -1; + unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33; + #endif + } + + half _Glossiness; + half _Metallic; + + void surf (Input IN, inout SurfaceOutputStandard o) { + o.Albedo = colour; + o.Metallic = 0; + o.Smoothness = 0; + o.Alpha = 1; + } + ENDCG + } + FallBack "Diffuse" +} \ No newline at end of file diff --git a/Assets/Scripts/Sim 3D/Display/ParticleShaded3D.shader.meta b/Assets/Scripts/Sim 3D/Display/ParticleShaded3D.shader.meta new file mode 100644 index 0000000..e3adf4c --- /dev/null +++ b/Assets/Scripts/Sim 3D/Display/ParticleShaded3D.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 638bb1bdb9b8e374e8a5cbcd595e3973 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Display/SphereGenerator.cs b/Assets/Scripts/Sim 3D/Display/SphereGenerator.cs new file mode 100644 index 0000000..1c0b969 --- /dev/null +++ b/Assets/Scripts/Sim 3D/Display/SphereGenerator.cs @@ -0,0 +1,172 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace SebStuff +{ + public static class SphereGenerator + { + // Indices of the vertex pairs that make up each of the initial 12 edges + static readonly int[] vertexPairs = { 0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2, 3, 3, 4, 4, 1, 5, 1, 5, 2, 5, 3, 5, 4 }; + // Indices of the edge triplets that make up the initial 8 faces + static readonly int[] edgeTriplets = { 0, 1, 4, 1, 2, 5, 2, 3, 6, 3, 0, 7, 8, 9, 4, 9, 10, 5, 10, 11, 6, 11, 8, 7 }; + // The six initial vertices + static readonly Vector3[] baseVertices = { Vector3.up, Vector3.left, Vector3.back, Vector3.right, Vector3.forward, Vector3.down }; + + + public static Mesh GenerateSphereMesh(int resolution) + { + Mesh mesh = new Mesh(); + int numDivisions = Mathf.Max(0, resolution); + int numVertsPerFace = ((numDivisions + 3) * (numDivisions + 3) - (numDivisions + 3)) / 2; + int numVerts = numVertsPerFace * 8 - (numDivisions + 2) * 12 + 6; + int numTrisPerFace = (numDivisions + 1) * (numDivisions + 1); + + var vertices = new FixedSizeList(numVerts); + var triangles = new FixedSizeList(numTrisPerFace * 8 * 3); + + vertices.AddRange(baseVertices); + + // Create 12 edges, with n vertices added along them (n = numDivisions) + Edge[] edges = new Edge[12]; + for (int i = 0; i < vertexPairs.Length; i += 2) + { + Vector3 startVertex = vertices.items[vertexPairs[i]]; + Vector3 endVertex = vertices.items[vertexPairs[i + 1]]; + + int[] edgeVertexIndices = new int[numDivisions + 2]; + edgeVertexIndices[0] = vertexPairs[i]; + + // Add vertices along edge + for (int divisionIndex = 0; divisionIndex < numDivisions; divisionIndex++) + { + float t = (divisionIndex + 1f) / (numDivisions + 1f); + edgeVertexIndices[divisionIndex + 1] = vertices.nextIndex; + vertices.Add(Vector3.Slerp(startVertex, endVertex, t)); + } + edgeVertexIndices[numDivisions + 1] = vertexPairs[i + 1]; + int edgeIndex = i / 2; + edges[edgeIndex] = new Edge(edgeVertexIndices); + } + + // Create faces + for (int i = 0; i < edgeTriplets.Length; i += 3) + { + int faceIndex = i / 3; + bool reverse = faceIndex >= 4; + CreateFace(edges[edgeTriplets[i]], edges[edgeTriplets[i + 1]], edges[edgeTriplets[i + 2]], reverse); + } + + mesh.SetVertices(vertices.items); + mesh.SetTriangles(triangles.items, 0, true); + mesh.RecalculateNormals(); + return mesh; + + void CreateFace(Edge sideA, Edge sideB, Edge bottom, bool reverse) + { + int numPointsInEdge = sideA.vertexIndices.Length; + var vertexMap = new FixedSizeList(numVertsPerFace); + vertexMap.Add(sideA.vertexIndices[0]); // top of triangle + + for (int i = 1; i < numPointsInEdge - 1; i++) + { + // Side A vertex + vertexMap.Add(sideA.vertexIndices[i]); + + // Add vertices between sideA and sideB + Vector3 sideAVertex = vertices.items[sideA.vertexIndices[i]]; + Vector3 sideBVertex = vertices.items[sideB.vertexIndices[i]]; + int numInnerPoints = i - 1; + for (int j = 0; j < numInnerPoints; j++) + { + float t = (j + 1f) / (numInnerPoints + 1f); + vertexMap.Add(vertices.nextIndex); + vertices.Add(Vector3.Slerp(sideAVertex, sideBVertex, t)); + } + + // Side B vertex + vertexMap.Add(sideB.vertexIndices[i]); + } + + // Add bottom edge vertices + for (int i = 0; i < numPointsInEdge; i++) + { + vertexMap.Add(bottom.vertexIndices[i]); + } + + // Triangulate + int numRows = numDivisions + 1; + for (int row = 0; row < numRows; row++) + { + // vertices down left edge follow quadratic sequence: 0, 1, 3, 6, 10, 15... + // the nth term can be calculated with: (n^2 - n)/2 + int topVertex = ((row + 1) * (row + 1) - row - 1) / 2; + int bottomVertex = ((row + 2) * (row + 2) - row - 2) / 2; + + int numTrianglesInRow = 1 + 2 * row; + for (int column = 0; column < numTrianglesInRow; column++) + { + int v0, v1, v2; + + if (column % 2 == 0) + { + v0 = topVertex; + v1 = bottomVertex + 1; + v2 = bottomVertex; + topVertex++; + bottomVertex++; + } + else + { + v0 = topVertex; + v1 = bottomVertex; + v2 = topVertex - 1; + } + + triangles.Add(vertexMap.items[v0]); + triangles.Add(vertexMap.items[(reverse) ? v2 : v1]); + triangles.Add(vertexMap.items[(reverse) ? v1 : v2]); + } + } + + } + } + + // Convenience classes: + public class Edge + { + public int[] vertexIndices; + + public Edge(int[] vertexIndices) + { + this.vertexIndices = vertexIndices; + } + } + + public class FixedSizeList + { + public T[] items; + public int nextIndex; + + public FixedSizeList(int size) + { + items = new T[size]; + } + + public void Add(T item) + { + items[nextIndex] = item; + nextIndex++; + } + + public void AddRange(IEnumerable items) + { + foreach (var item in items) + { + Add(item); + } + } + } + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Sim 3D/Display/SphereGenerator.cs.meta b/Assets/Scripts/Sim 3D/Display/SphereGenerator.cs.meta new file mode 100644 index 0000000..fc39afd --- /dev/null +++ b/Assets/Scripts/Sim 3D/Display/SphereGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ffb7f559c2e72e4499e86da9cff6ab6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Simulation3D.cs b/Assets/Scripts/Sim 3D/Simulation3D.cs new file mode 100644 index 0000000..98930fd --- /dev/null +++ b/Assets/Scripts/Sim 3D/Simulation3D.cs @@ -0,0 +1,210 @@ +using UnityEngine; +using Unity.Mathematics; + +public class Simulation3D : MonoBehaviour +{ + public event System.Action SimulationStepCompleted; + + [Header("Settings")] + public float timeScale = 1; + public bool fixedTimeStep; + public int iterationsPerFrame; + public float gravity = -10; + [Range(0, 1)] public float collisionDamping = 0.05f; + public float smoothingRadius = 0.2f; + public float targetDensity; + public float pressureMultiplier; + public float nearPressureMultiplier; + public float viscosityStrength; + + [Header("References")] + public ComputeShader compute; + public Spawner3D spawner; + public ParticleDisplay3D display; + public Transform floorDisplay; + + // Buffers + public ComputeBuffer positionBuffer { get; private set; } + public ComputeBuffer velocityBuffer { get; private set; } + public ComputeBuffer densityBuffer { get; private set; } + public ComputeBuffer predictedPositionsBuffer; + ComputeBuffer spatialIndices; + ComputeBuffer spatialOffsets; + + // Kernel IDs + const int externalForcesKernel = 0; + const int spatialHashKernel = 1; + const int densityKernel = 2; + const int pressureKernel = 3; + const int viscosityKernel = 4; + const int updatePositionsKernel = 5; + + GPUSort gpuSort; + + // State + bool isPaused; + bool pauseNextFrame; + Spawner3D.SpawnData spawnData; + + void Start() + { + Debug.Log("Controls: Space = Play/Pause, R = Reset"); + Debug.Log("Use transform tool in scene to scale/rotate simulation bounding box."); + + float deltaTime = 1 / 60f; + Time.fixedDeltaTime = deltaTime; + + spawnData = spawner.GetSpawnData(); + + // Create buffers + int numParticles = spawnData.points.Length; + positionBuffer = ComputeHelper.CreateStructuredBuffer(numParticles); + predictedPositionsBuffer = ComputeHelper.CreateStructuredBuffer(numParticles); + velocityBuffer = ComputeHelper.CreateStructuredBuffer(numParticles); + densityBuffer = ComputeHelper.CreateStructuredBuffer(numParticles); + spatialIndices = ComputeHelper.CreateStructuredBuffer(numParticles); + spatialOffsets = ComputeHelper.CreateStructuredBuffer(numParticles); + + // Set buffer data + SetInitialBufferData(spawnData); + + // Init compute + ComputeHelper.SetBuffer(compute, positionBuffer, "Positions", externalForcesKernel, updatePositionsKernel); + ComputeHelper.SetBuffer(compute, predictedPositionsBuffer, "PredictedPositions", externalForcesKernel, spatialHashKernel, densityKernel, pressureKernel, viscosityKernel, updatePositionsKernel); + ComputeHelper.SetBuffer(compute, spatialIndices, "SpatialIndices", spatialHashKernel, densityKernel, pressureKernel, viscosityKernel); + ComputeHelper.SetBuffer(compute, spatialOffsets, "SpatialOffsets", spatialHashKernel, densityKernel, pressureKernel, viscosityKernel); + ComputeHelper.SetBuffer(compute, densityBuffer, "Densities", densityKernel, pressureKernel, viscosityKernel); + ComputeHelper.SetBuffer(compute, velocityBuffer, "Velocities", externalForcesKernel, pressureKernel, viscosityKernel, updatePositionsKernel); + + compute.SetInt("numParticles", positionBuffer.count); + + gpuSort = new(); + gpuSort.SetBuffers(spatialIndices, spatialOffsets); + + + // Init display + display.Init(this); + } + + void FixedUpdate() + { + // Run simulation if in fixed timestep mode + if (fixedTimeStep) + { + RunSimulationFrame(Time.fixedDeltaTime); + } + } + + void Update() + { + // Run simulation if not in fixed timestep mode + // (skip running for first few frames as timestep can be a lot higher than usual) + if (!fixedTimeStep && Time.frameCount > 10) + { + RunSimulationFrame(Time.deltaTime); + } + + if (pauseNextFrame) + { + isPaused = true; + pauseNextFrame = false; + } + floorDisplay.transform.localScale = new Vector3(1, 1 / transform.localScale.y * 0.1f, 1); + + HandleInput(); + } + + void RunSimulationFrame(float frameTime) + { + if (!isPaused) + { + float timeStep = frameTime / iterationsPerFrame * timeScale; + + UpdateSettings(timeStep); + + for (int i = 0; i < iterationsPerFrame; i++) + { + RunSimulationStep(); + SimulationStepCompleted?.Invoke(); + } + } + } + + void RunSimulationStep() + { + ComputeHelper.Dispatch(compute, positionBuffer.count, kernelIndex: externalForcesKernel); + ComputeHelper.Dispatch(compute, positionBuffer.count, kernelIndex: spatialHashKernel); + gpuSort.SortAndCalculateOffsets(); + ComputeHelper.Dispatch(compute, positionBuffer.count, kernelIndex: densityKernel); + ComputeHelper.Dispatch(compute, positionBuffer.count, kernelIndex: pressureKernel); + ComputeHelper.Dispatch(compute, positionBuffer.count, kernelIndex: viscosityKernel); + ComputeHelper.Dispatch(compute, positionBuffer.count, kernelIndex: updatePositionsKernel); + + } + + void UpdateSettings(float deltaTime) + { + Vector3 simBoundsSize = transform.localScale; + Vector3 simBoundsCentre = transform.position; + + compute.SetFloat("deltaTime", deltaTime); + compute.SetFloat("gravity", gravity); + compute.SetFloat("collisionDamping", collisionDamping); + compute.SetFloat("smoothingRadius", smoothingRadius); + compute.SetFloat("targetDensity", targetDensity); + compute.SetFloat("pressureMultiplier", pressureMultiplier); + compute.SetFloat("nearPressureMultiplier", nearPressureMultiplier); + compute.SetFloat("viscosityStrength", viscosityStrength); + compute.SetVector("boundsSize", simBoundsSize); + compute.SetVector("centre", simBoundsCentre); + + compute.SetMatrix("localToWorld", transform.localToWorldMatrix); + compute.SetMatrix("worldToLocal", transform.worldToLocalMatrix); + } + + void SetInitialBufferData(Spawner3D.SpawnData spawnData) + { + float3[] allPoints = new float3[spawnData.points.Length]; + System.Array.Copy(spawnData.points, allPoints, spawnData.points.Length); + + positionBuffer.SetData(allPoints); + predictedPositionsBuffer.SetData(allPoints); + velocityBuffer.SetData(spawnData.velocities); + } + + void HandleInput() + { + if (Input.GetKeyDown(KeyCode.Space)) + { + isPaused = !isPaused; + } + + if (Input.GetKeyDown(KeyCode.RightArrow)) + { + isPaused = false; + pauseNextFrame = true; + } + + if (Input.GetKeyDown(KeyCode.R)) + { + isPaused = true; + SetInitialBufferData(spawnData); + } + } + + void OnDestroy() + { + ComputeHelper.Release(positionBuffer, predictedPositionsBuffer, velocityBuffer, densityBuffer, spatialIndices, spatialOffsets); + } + + void OnDrawGizmos() + { + // Draw Bounds + var m = Gizmos.matrix; + Gizmos.matrix = transform.localToWorldMatrix; + Gizmos.color = new Color(0, 1, 0, 0.5f); + Gizmos.DrawWireCube(Vector3.zero, Vector3.one); + Gizmos.matrix = m; + + } +} diff --git a/Assets/Scripts/Sim 3D/Simulation3D.cs.meta b/Assets/Scripts/Sim 3D/Simulation3D.cs.meta new file mode 100644 index 0000000..82b685c --- /dev/null +++ b/Assets/Scripts/Sim 3D/Simulation3D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8b3b79f98be3f34e8fefade4cef2ade +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Sim 3D/Spawner3D.cs b/Assets/Scripts/Sim 3D/Spawner3D.cs new file mode 100644 index 0000000..e573c09 --- /dev/null +++ b/Assets/Scripts/Sim 3D/Spawner3D.cs @@ -0,0 +1,67 @@ +using Unity.Mathematics; +using UnityEngine; + +public class Spawner3D : MonoBehaviour +{ + public int numParticlesPerAxis; + public Vector3 centre; + public float size; + public float3 initialVel; + public float jitterStrength; + public bool showSpawnBounds; + + [Header("Info")] + public int debug_numParticles; + + public SpawnData GetSpawnData() + { + int numPoints = numParticlesPerAxis * numParticlesPerAxis * numParticlesPerAxis; + float3[] points = new float3[numPoints]; + float3[] velocities = new float3[numPoints]; + + int i = 0; + + for (int x = 0; x < numParticlesPerAxis; x++) + { + for (int y = 0; y < numParticlesPerAxis; y++) + { + for (int z = 0; z < numParticlesPerAxis; z++) + { + float tx = x / (numParticlesPerAxis - 1f); + float ty = y / (numParticlesPerAxis - 1f); + float tz = z / (numParticlesPerAxis - 1f); + + float px = (tx - 0.5f) * size + centre.x; + float py = (ty - 0.5f) * size + centre.y; + float pz = (tz - 0.5f) * size + centre.z; + float3 jitter = UnityEngine.Random.insideUnitSphere * jitterStrength; + points[i] = new float3(px, py, pz) + jitter; + velocities[i] = initialVel; + i++; + } + } + } + + return new SpawnData() { points = points, velocities = velocities }; + } + + public struct SpawnData + { + public float3[] points; + public float3[] velocities; + } + + void OnValidate() + { + debug_numParticles = numParticlesPerAxis * numParticlesPerAxis * numParticlesPerAxis; + } + + void OnDrawGizmos() + { + if (showSpawnBounds && !Application.isPlaying) + { + Gizmos.color = new Color(1, 1, 0, 0.5f); + Gizmos.DrawWireCube(centre, Vector3.one * size); + } + } +} diff --git a/Assets/Scripts/Sim 3D/Spawner3D.cs.meta b/Assets/Scripts/Sim 3D/Spawner3D.cs.meta new file mode 100644 index 0000000..1394dee --- /dev/null +++ b/Assets/Scripts/Sim 3D/Spawner3D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f99a384512b94654fbeb7c06c43f81ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/manifest.json b/Packages/manifest.json new file mode 100644 index 0000000..5e89a75 --- /dev/null +++ b/Packages/manifest.json @@ -0,0 +1,41 @@ +{ + "dependencies": { + "com.unity.ide.rider": "3.0.24", + "com.unity.ide.visualstudio": "2.0.20", + "com.unity.ide.vscode": "1.2.5", + "com.unity.inputsystem": "1.6.3", + "com.unity.mathematics": "1.2.6", + "com.unity.ugui": "1.0.0", + "com.unity.modules.ai": "1.0.0", + "com.unity.modules.androidjni": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.cloth": "1.0.0", + "com.unity.modules.director": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.screencapture": "1.0.0", + "com.unity.modules.terrain": "1.0.0", + "com.unity.modules.terrainphysics": "1.0.0", + "com.unity.modules.tilemap": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.umbra": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.unitywebrequesttexture": "1.0.0", + "com.unity.modules.unitywebrequestwww": "1.0.0", + "com.unity.modules.vehicles": "1.0.0", + "com.unity.modules.video": "1.0.0", + "com.unity.modules.vr": "1.0.0", + "com.unity.modules.wind": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } +} diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json new file mode 100644 index 0000000..4d49800 --- /dev/null +++ b/Packages/packages-lock.json @@ -0,0 +1,315 @@ +{ + "dependencies": { + "com.unity.ext.nunit": { + "version": "1.0.6", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.ide.rider": { + "version": "3.0.24", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ext.nunit": "1.0.6" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ide.visualstudio": { + "version": "2.0.20", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.1.9" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ide.vscode": { + "version": "1.2.5", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.inputsystem": { + "version": "1.6.3", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.modules.uielements": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.mathematics": { + "version": "1.2.6", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.test-framework": { + "version": "1.1.33", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.ext.nunit": "1.0.6", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ugui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0" + } + }, + "com.unity.modules.ai": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.androidjni": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.animation": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.assetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.audio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.cloth": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.director": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.animation": "1.0.0" + } + }, + "com.unity.modules.imageconversion": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.imgui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.jsonserialize": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.particlesystem": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics2d": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.screencapture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.subsystems": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.terrain": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.terrainphysics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.terrain": "1.0.0" + } + }, + "com.unity.modules.tilemap": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics2d": "1.0.0" + } + }, + "com.unity.modules.ui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.uielements": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.umbra": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unityanalytics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.unitywebrequest": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unitywebrequestassetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestaudio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.audio": "1.0.0" + } + }, + "com.unity.modules.unitywebrequesttexture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestwww": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.vehicles": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.video": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.vr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } + }, + "com.unity.modules.wind": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.xr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.subsystems": "1.0.0" + } + } + } +} diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000..07ebfb0 --- /dev/null +++ b/ProjectSettings/AudioManager.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 + m_RequestedDSPBufferSize: 1024 diff --git a/ProjectSettings/ClusterInputManager.asset b/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000..e7886b2 --- /dev/null +++ b/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000..cdc1f3e --- /dev/null +++ b/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 0 + m_ReuseCollisionCallbacks: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 + m_FrictionType: 0 + m_EnableEnhancedDeterminism: 0 + m_EnableUnifiedHeightmaps: 1 + m_DefaultMaxAngluarSpeed: 7 diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 0000000..0147887 --- /dev/null +++ b/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: [] + m_configObjects: {} diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset new file mode 100644 index 0000000..6789e4e --- /dev/null +++ b/ProjectSettings/EditorSettings.asset @@ -0,0 +1,47 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 0 + m_DefaultBehaviorMode: 0 + m_PrefabRegularEnvironment: {fileID: 0} + m_PrefabUIEnvironment: {fileID: 0} + m_SpritePackerMode: 0 + m_SpritePackerCacheSize: 10 + m_SpritePackerPaddingPower: 1 + m_Bc7TextureCompressor: 0 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref + m_ProjectGenerationRootNamespace: + m_EnableTextureStreamingInEditMode: 1 + m_EnableTextureStreamingInPlayMode: 1 + m_EnableEditorAsyncCPUTextureLoading: 0 + m_AsyncShaderCompilation: 1 + m_PrefabModeAllowAutoSave: 1 + m_EnterPlayModeOptionsEnabled: 1 + m_EnterPlayModeOptions: 3 + m_GameObjectNamingDigits: 1 + m_GameObjectNamingScheme: 0 + m_AssetNamingUsesSpace: 1 + m_InspectorUseIMGUIDefaultInspector: 0 + m_UseLegacyProbeSampleCount: 0 + m_SerializeInlineMappingsOnOneLine: 1 + m_DisableCookiesInLightmapper: 0 + m_AssetPipelineMode: 1 + m_RefreshImportMode: 0 + m_CacheServerMode: 0 + m_CacheServerEndpoint: + m_CacheServerNamespacePrefix: default + m_CacheServerEnableDownload: 1 + m_CacheServerEnableUpload: 1 + m_CacheServerEnableAuth: 0 + m_CacheServerEnableTls: 0 + m_CacheServerValidationMode: 2 + m_CacheServerDownloadBatchSize: 128 + m_EnableEnlightenBakedGI: 0 diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000..43369e3 --- /dev/null +++ b/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,63 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 13 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 + m_LogWhenShaderIsCompiled: 0 + m_AllowEnlightenSupportForUpgradedProject: 0 diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset new file mode 100644 index 0000000..17c8f53 --- /dev/null +++ b/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/ProjectSettings/MemorySettings.asset b/ProjectSettings/MemorySettings.asset new file mode 100644 index 0000000..5b5face --- /dev/null +++ b/ProjectSettings/MemorySettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!387306366 &1 +MemorySettings: + m_ObjectHideFlags: 0 + m_EditorMemorySettings: + m_MainAllocatorBlockSize: -1 + m_ThreadAllocatorBlockSize: -1 + m_MainGfxBlockSize: -1 + m_ThreadGfxBlockSize: -1 + m_CacheBlockSize: -1 + m_TypetreeBlockSize: -1 + m_ProfilerBlockSize: -1 + m_ProfilerEditorBlockSize: -1 + m_BucketAllocatorGranularity: -1 + m_BucketAllocatorBucketsCount: -1 + m_BucketAllocatorBlockSize: -1 + m_BucketAllocatorBlockCount: -1 + m_ProfilerBucketAllocatorGranularity: -1 + m_ProfilerBucketAllocatorBucketsCount: -1 + m_ProfilerBucketAllocatorBlockSize: -1 + m_ProfilerBucketAllocatorBlockCount: -1 + m_TempAllocatorSizeMain: -1 + m_JobTempAllocatorBlockSize: -1 + m_BackgroundJobTempAllocatorBlockSize: -1 + m_JobTempAllocatorReducedBlockSize: -1 + m_TempAllocatorSizeGIBakingWorker: -1 + m_TempAllocatorSizeNavMeshWorker: -1 + m_TempAllocatorSizeAudioWorker: -1 + m_TempAllocatorSizeCloudWorker: -1 + m_TempAllocatorSizeGfx: -1 + m_TempAllocatorSizeJobWorker: -1 + m_TempAllocatorSizeBackgroundWorker: -1 + m_TempAllocatorSizePreloadManager: -1 + m_PlatformMemorySettings: {} diff --git a/ProjectSettings/NavMeshAreas.asset b/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 0000000..3b0b7c3 --- /dev/null +++ b/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/ProjectSettings/PackageManagerSettings.asset b/ProjectSettings/PackageManagerSettings.asset new file mode 100644 index 0000000..be4a797 --- /dev/null +++ b/ProjectSettings/PackageManagerSettings.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 61 + 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: 13964, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_EnablePreviewPackages: 0 + m_EnablePackageDependencies: 0 + m_AdvancedSettingsExpanded: 1 + m_ScopedRegistriesSettingsExpanded: 1 + oneTimeWarningShown: 0 + m_Registries: + - m_Id: main + m_Name: + m_Url: https://packages.unity.com + m_Scopes: [] + m_IsDefault: 1 + m_Capabilities: 7 + m_UserSelectedRegistryName: + m_UserAddingNewScopedRegistry: 0 + m_RegistryInfoDraft: + m_ErrorMessage: + m_Original: + m_Id: + m_Name: + m_Url: + m_Scopes: [] + m_IsDefault: 0 + m_Capabilities: 0 + m_Modified: 0 + m_Name: + m_Url: + m_Scopes: + - + m_SelectedScopeIndex: 0 diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000..47880b1 --- /dev/null +++ b/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,56 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 4 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_JobOptions: + serializedVersion: 2 + useMultithreading: 0 + useConsistencySorting: 0 + m_InterpolationPosesPerJob: 100 + m_NewContactsPerJob: 30 + m_CollideContactsPerJob: 100 + m_ClearFlagsPerJob: 200 + m_ClearBodyForcesPerJob: 200 + m_SyncDiscreteFixturesPerJob: 50 + m_SyncContinuousFixturesPerJob: 50 + m_FindNearestContactsPerJob: 100 + m_UpdateTriggerContactsPerJob: 100 + m_IslandSolverCostThreshold: 100 + m_IslandSolverBodyCostScale: 1 + m_IslandSolverContactCostScale: 10 + m_IslandSolverJointCostScale: 10 + m_IslandSolverBodiesPerJob: 50 + m_IslandSolverContactsPerJob: 50 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_CallbacksOnDisable: 1 + m_ReuseCollisionCallbacks: 1 + m_AutoSyncTransforms: 0 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/ProjectSettings/PresetManager.asset b/ProjectSettings/PresetManager.asset new file mode 100644 index 0000000..67a94da --- /dev/null +++ b/ProjectSettings/PresetManager.asset @@ -0,0 +1,7 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_DefaultPresets: {} diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset new file mode 100644 index 0000000..2259077 --- /dev/null +++ b/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,741 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 26 + productGUID: 63f20037fbe8f1449830b9bf8e1ebd6c + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: DefaultCompany + productName: Water 2D + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1024 + defaultScreenHeight: 768 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_SpriteBatchVertexThreshold: 300 + m_MTRendering: 1 + mipStripping: 0 + numberOfMipsStripped: 0 + numberOfMipsStrippedPerMipmapLimitGroup: {} + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosUseCustomAppBackgroundBehavior: 0 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 1 + androidUseSwappy: 1 + androidBlitType: 0 + androidResizableWindow: 0 + androidDefaultWindowWidth: 1920 + androidDefaultWindowHeight: 1080 + androidMinimumWindowWidth: 400 + androidMinimumWindowHeight: 300 + androidFullscreenMode: 1 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + dedicatedServerOptimizations: 0 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + useFlipModelSwapchain: 1 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 1 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOneEnableTypeOptimization: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + switchQueueControlMemory: 16384 + switchQueueComputeMemory: 262144 + switchNVNShaderPoolsGranularity: 33554432 + switchNVNDefaultPoolsGranularity: 16777216 + switchNVNOtherPoolsGranularity: 16777216 + switchGpuScratchPoolGranularity: 2097152 + switchAllowGpuScratchShrinking: 0 + switchNVNMaxPublicTextureIDCount: 0 + switchNVNMaxPublicSamplerIDCount: 0 + switchNVNGraphicsFirmwareMemory: 32 + switchMaxWorkerMultiple: 8 + stadiaPresentMode: 0 + stadiaTargetFramerate: 0 + vulkanNumSwapchainBuffers: 3 + vulkanEnableSetSRGBWrite: 0 + vulkanEnablePreTransform: 0 + vulkanEnableLateAcquireNextImage: 0 + vulkanEnableCommandBufferRecycling: 1 + loadStoreDebugModeEnabled: 0 + bundleVersion: 0.1 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 1 + xboxOneEnable7thCore: 1 + vrSettings: + enable360StereoCapture: 0 + isWsaHolographicRemotingEnabled: 0 + enableFrameTimingStats: 0 + enableOpenGLProfilerGPURecorders: 1 + useHDRDisplay: 0 + hdrBitDepth: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + resetResolutionOnWindowResize: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: {} + buildNumber: + Standalone: 0 + VisionOS: 0 + iPhone: 0 + tvOS: 0 + overrideDefaultApplicationIdentifier: 0 + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 22 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 1 + strictShaderVariantMatching: 0 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 988 + iOSTargetOSVersionString: 12.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 12.0 + VisionOSSdkVersion: 0 + VisionOSTargetOSVersionString: 1.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSLaunchScreenCustomStoryboardPath: + iOSLaunchScreeniPadCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + macOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + iosCopyPluginsCodeInsteadOfSymlink: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + VisionOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + VisionOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + iOSAutomaticallyDetectAndAddCapabilities: 1 + appleEnableProMotion: 0 + shaderPrecisionModel: 0 + clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea + templatePackageId: com.unity.template.3d@5.0.4 + templateDefaultScene: Assets/Scenes/SampleScene.unity + useCustomMainManifest: 0 + useCustomLauncherManifest: 0 + useCustomMainGradleTemplate: 0 + useCustomLauncherGradleManifest: 0 + useCustomBaseGradleTemplate: 0 + useCustomGradlePropertiesTemplate: 0 + useCustomGradleSettingsTemplate: 0 + useCustomProguardFile: 0 + AndroidTargetArchitectures: 1 + AndroidTargetDevices: 0 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidEnableArmv9SecurityFeatures: 0 + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 0 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + androidUseCustomKeystore: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + chromeosInputEmulation: 1 + AndroidMinifyRelease: 0 + AndroidMinifyDebug: 0 + AndroidValidateAppBundleSize: 1 + AndroidAppBundleSizeToValidate: 150 + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: [] + m_BuildTargetBatching: + - m_BuildTarget: Standalone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: tvOS + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: Android + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: iPhone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: WebGL + m_StaticBatching: 0 + m_DynamicBatching: 0 + m_BuildTargetShaderSettings: [] + m_BuildTargetGraphicsJobs: + - m_BuildTarget: MacStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: Switch + m_GraphicsJobs: 1 + - m_BuildTarget: MetroSupport + m_GraphicsJobs: 1 + - m_BuildTarget: AppleTVSupport + m_GraphicsJobs: 0 + - m_BuildTarget: BJMSupport + m_GraphicsJobs: 1 + - m_BuildTarget: LinuxStandaloneSupport + m_GraphicsJobs: 1 + - m_BuildTarget: PS4Player + m_GraphicsJobs: 1 + - m_BuildTarget: iOSSupport + m_GraphicsJobs: 0 + - m_BuildTarget: WindowsStandaloneSupport + m_GraphicsJobs: 1 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobs: 1 + - m_BuildTarget: LuminSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AndroidPlayer + m_GraphicsJobs: 0 + - m_BuildTarget: WebGLSupport + m_GraphicsJobs: 0 + m_BuildTargetGraphicsJobMode: + - m_BuildTarget: PS4Player + m_GraphicsJobMode: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobMode: 0 + m_BuildTargetGraphicsAPIs: + - m_BuildTarget: AndroidPlayer + m_APIs: 150000000b000000 + m_Automatic: 1 + - m_BuildTarget: iOSSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: AppleTVSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: WebGLSupport + m_APIs: 0b000000 + m_Automatic: 1 + m_BuildTargetVRSettings: + - m_BuildTarget: Standalone + m_Enabled: 0 + m_Devices: + - Oculus + - OpenVR + m_DefaultShaderChunkSizeInMB: 16 + m_DefaultShaderChunkCount: 0 + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + openGLRequireES32: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: [] + m_BuildTargetGroupHDRCubemapEncodingQuality: [] + m_BuildTargetGroupLightmapSettings: [] + m_BuildTargetGroupLoadStoreDebugModeSettings: [] + m_BuildTargetNormalMapEncoding: [] + m_BuildTargetDefaultTextureCompressionFormat: [] + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + bluetoothUsageDescription: + macOSTargetOSVersion: 10.13.0 + switchNMETAOverride: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchUseGOLDLinker: 0 + switchLTOSetting: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchCompilerFlags: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchTitleNames_15: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchPublisherNames_15: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchIcons_15: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchSmallIcons_15: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchRatingsInt_12: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSystemResourceMemory: 16777216 + switchSupportedNpadStyles: 22 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 0 + switchSupportedNpadCount: 8 + switchEnableTouchScreen: 1 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + switchUseNewStyleFilepaths: 0 + switchUseLegacyFmodPriorities: 0 + switchUseMicroSleepForYield: 1 + switchEnableRamDiskSupport: 0 + switchMicroSleepForYieldTime: 25 + switchRamDiskSpaceSize: 12 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4ExtraSceSysFile: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + playerPrefsMaxSize: 32768 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4UseLowGarlicFragmentationMode: 1 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4CompatibilityPS5: 0 + ps4AllowPS5Detection: 0 + ps4GPU800MHz: 1 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + ps4attribVROutputEnabled: 0 + monoEnv: + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + blurSplashScreenBackground: 1 + spritePackerPolicy: + webGLMemorySize: 16 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLShowDiagnostics: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLWasmArithmeticExceptions: 0 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + webGLDecompressionFallback: 0 + webGLInitialMemorySize: 32 + webGLMaximumMemorySize: 2048 + webGLMemoryGrowthMode: 2 + webGLMemoryLinearGrowthStep: 16 + webGLMemoryGeometricGrowthStep: 0.2 + webGLMemoryGeometricGrowthCap: 96 + webGLPowerPreference: 2 + scriptingDefineSymbols: {} + additionalCompilerArguments: {} + platformArchitecture: {} + scriptingBackend: {} + il2cppCompilerConfiguration: {} + il2cppCodeGeneration: {} + managedStrippingLevel: + EmbeddedLinux: 1 + GameCoreScarlett: 1 + GameCoreXboxOne: 1 + Nintendo Switch: 1 + PS4: 1 + PS5: 1 + QNX: 1 + Stadia: 1 + VisionOS: 1 + WebGL: 1 + Windows Store Apps: 1 + XboxOne: 1 + iPhone: 1 + tvOS: 1 + incrementalIl2cppBuild: {} + suppressCommonWarnings: 1 + allowUnsafeCode: 0 + useDeterministicCompilation: 1 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + gcIncremental: 1 + gcWBarrierValidation: 0 + apiCompatibilityLevelPerPlatform: {} + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: Template_3D + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: Template_3D + wsaImages: {} + metroTileShortName: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroTargetDeviceFamilies: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + vcxProjDefaultLanguage: + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnhancedXboxCompatibilityMode: 0 + XboxOneEnableGPUVariability: 1 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + XboxOneOverrideIdentityName: + XboxOneOverrideIdentityPublisher: + vrEditorSettings: {} + cloudServicesEnabled: + UNet: 1 + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_SignPackage: 1 + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + hmiPlayerDataPath: + hmiForceSRGBBlit: 1 + embeddedLinuxEnableGamepadInput: 1 + hmiLogStartupTiming: 0 + hmiCpuConfiguration: + apiCompatibilityLevel: 6 + activeInputHandler: 2 + windowsGamepadBackendHint: 0 + cloudProjectId: + framebufferDepthMemorylessMode: 0 + qualitySettingsNames: [] + projectName: + organizationId: + cloudEnabled: 0 + legacyClampBlendShapeWeights: 0 + hmiLoadingImage: {fileID: 0} + platformRequiresReadableAssets: 0 + virtualTexturingSupportEnabled: 0 + insecureHttpOption: 0 diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..9785246 --- /dev/null +++ b/ProjectSettings/ProjectVersion.txt @@ -0,0 +1,2 @@ +m_EditorVersion: 2022.3.8f1 +m_EditorVersionWithRevision: 2022.3.8f1 (b5eafc012955) diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset new file mode 100644 index 0000000..d271391 --- /dev/null +++ b/ProjectSettings/QualitySettings.asset @@ -0,0 +1,59 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 0 + m_QualitySettings: + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 2 + shadowResolution: 3 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + skinWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + customRenderPipeline: {fileID: 0} + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 0 + Lumin: 0 + Nintendo 3DS: 0 + Nintendo Switch: 0 + PS4: 0 + PSP2: 0 + Server: 0 + Stadia: 0 + Standalone: 0 + WebGL: 0 + Windows Store Apps: 0 + XboxOne: 0 + iPhone: 0 + tvOS: 0 diff --git a/ProjectSettings/SceneTemplateSettings.json b/ProjectSettings/SceneTemplateSettings.json new file mode 100644 index 0000000..6f3e60f --- /dev/null +++ b/ProjectSettings/SceneTemplateSettings.json @@ -0,0 +1,167 @@ +{ + "templatePinStates": [], + "dependencyTypeInfos": [ + { + "userAdded": false, + "type": "UnityEngine.AnimationClip", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.Animations.AnimatorController", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.AnimatorOverrideController", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.Audio.AudioMixerController", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.ComputeShader", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Cubemap", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.GameObject", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.LightingDataAsset", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": false + }, + { + "userAdded": false, + "type": "UnityEngine.LightingSettings", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Material", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.MonoScript", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.PhysicMaterial", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.PhysicsMaterial2D", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.PostProcessing.PostProcessResources", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.VolumeProfile", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.SceneAsset", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": false + }, + { + "userAdded": false, + "type": "UnityEngine.Shader", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.ShaderVariantCollection", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Texture", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Texture2D", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Timeline.TimelineAsset", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + } + ], + "defaultDependencyTypeInfo": { + "userAdded": false, + "type": "", + "ignore": false, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + "newSceneOverride": 0 +} \ No newline at end of file diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset new file mode 100644 index 0000000..1c92a78 --- /dev/null +++ b/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/ProjectSettings/TimeManager.asset b/ProjectSettings/TimeManager.asset new file mode 100644 index 0000000..558a017 --- /dev/null +++ b/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.33333334 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/ProjectSettings/UnityConnectSettings.asset b/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 0000000..6125b30 --- /dev/null +++ b/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 1 + m_Enabled: 0 + m_TestMode: 0 + m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events + m_EventUrl: https://cdp.cloud.unity3d.com/v1/events + m_ConfigUrl: https://config.uca.cloud.unity3d.com + m_DashboardUrl: https://dashboard.unity3d.com + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com + m_Enabled: 0 + m_LogBufferSize: 10 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 0 + m_TestMode: 0 + m_InitializeOnStartup: 1 + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/ProjectSettings/VFXManager.asset b/ProjectSettings/VFXManager.asset new file mode 100644 index 0000000..3a95c98 --- /dev/null +++ b/ProjectSettings/VFXManager.asset @@ -0,0 +1,12 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!937362698 &1 +VFXManager: + m_ObjectHideFlags: 0 + m_IndirectShader: {fileID: 0} + m_CopyBufferShader: {fileID: 0} + m_SortShader: {fileID: 0} + m_StripUpdateShader: {fileID: 0} + m_RenderPipeSettingsPath: + m_FixedTimeStep: 0.016666668 + m_MaxDeltaTime: 0.05 diff --git a/ProjectSettings/VersionControlSettings.asset b/ProjectSettings/VersionControlSettings.asset new file mode 100644 index 0000000..dca2881 --- /dev/null +++ b/ProjectSettings/VersionControlSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!890905787 &1 +VersionControlSettings: + m_ObjectHideFlags: 0 + m_Mode: Visible Meta Files + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/ProjectSettings/XRSettings.asset b/ProjectSettings/XRSettings.asset new file mode 100644 index 0000000..482590c --- /dev/null +++ b/ProjectSettings/XRSettings.asset @@ -0,0 +1,10 @@ +{ + "m_SettingKeys": [ + "VR Device Disabled", + "VR Device User Alert" + ], + "m_SettingValues": [ + "False", + "False" + ] +} \ No newline at end of file