├── .gitignore ├── Assets ├── Examples.meta ├── Examples │ ├── 0-sum-numbers-sse3.meta │ ├── 0-sum-numbers-sse3 │ │ ├── SumNumbers_SSE3.cs │ │ ├── SumNumbers_SSE3.cs.meta │ │ ├── SumNumbers_SSE3_Scene.unity │ │ └── SumNumbers_SSE3_Scene.unity.meta │ ├── 1-count-small-numbers-sse2.meta │ ├── 1-count-small-numbers-sse2 │ │ ├── CountSmallNumbers_SSE2.cs │ │ ├── CountSmallNumbers_SSE2.cs.meta │ │ ├── CountSmallNumbers_SSE2_Scene.unity │ │ └── CountSmallNumbers_SSE2_Scene.unity.meta │ ├── 2-sum-small-numbers-sse3.meta │ └── 2-sum-small-numbers-sse3 │ │ ├── SumSmallNumbers_SSE3.cs │ │ ├── SumSmallNumbers_SSE3.cs.meta │ │ ├── SumSmallNumbers_SSE3_Scene.unity │ │ └── SumSmallNumbers_SSE3_Scene.unity.meta ├── Exercises.meta └── Exercises │ ├── 0-sphere-collisions.meta │ ├── 0-sphere-collisions │ ├── SphereCollisions.cs │ ├── SphereCollisions.cs.meta │ ├── SphereCollisions_Scene.unity │ └── SphereCollisions_Scene.unity.meta │ ├── 1-math-grabbag.meta │ ├── 1-math-grabbag │ ├── Editor.meta │ ├── Editor │ │ ├── SimdMathTests.cs │ │ └── SimdMathTests.cs.meta │ ├── SimdMath.cs │ └── SimdMath.cs.meta │ ├── 2-mandelbrot-render.meta │ ├── 2-mandelbrot-render │ ├── MandelbrotMaterial.mat │ ├── MandelbrotMaterial.mat.meta │ ├── MandelbrotRender.cs │ ├── MandelbrotRender.cs.meta │ ├── MandelbrotRender_Scene.unity │ └── MandelbrotRender_Scene.unity.meta │ ├── 3-culling.meta │ ├── 3-culling │ ├── CubeMaterial.mat │ ├── CubeMaterial.mat.meta │ ├── Culling.cs │ ├── Culling.cs.meta │ ├── Culling_Scene.unity │ ├── Culling_Scene.unity.meta │ ├── SphereMaterial.mat │ └── SphereMaterial.mat.meta │ ├── 4-triangle-picking.meta │ ├── 4-triangle-picking │ ├── Grenadier Model.fbx │ ├── Grenadier Model.fbx.meta │ ├── IntersectionMarker.mat │ ├── IntersectionMarker.mat.meta │ ├── TrianglePicking.cs │ ├── TrianglePicking.cs.meta │ ├── TrianglePicking_Scene.unity │ └── TrianglePicking_Scene.unity.meta │ ├── 5-raytracer.meta │ └── 5-raytracer │ ├── Raytracer.cs │ ├── Raytracer.cs.meta │ ├── RaytracerMaterial.mat │ ├── RaytracerMaterial.mat.meta │ ├── Raytracer_Scene.unity │ └── Raytracer_Scene.unity.meta ├── LICENSE.md ├── Packages ├── manifest.json └── packages-lock.json ├── ProjectSettings ├── AudioManager.asset ├── BurstAotSettings_Android.json ├── ClusterInputManager.asset ├── CommonBurstAotSettings.json ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── PackageManagerSettings.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset ├── UnityConnectSettings.asset ├── VFXManager.asset ├── VersionControlSettings.asset └── XRSettings.asset └── ReadMe.md /.gitignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | Build 3 | Builds 4 | Library 5 | [Ll]ogs 6 | [Tt]emp 7 | obj 8 | obj.meta 9 | 10 | .bin 11 | .download 12 | .[Ee]ditor 13 | .UnityLauncher.Editor 14 | .vs 15 | .vscode 16 | 17 | .DS_Store 18 | *.app 19 | *.csproj 20 | *.csproj.user 21 | *.DotSettings 22 | *.gen.csproj.meta 23 | *.idea 24 | *.pyc 25 | *.sln 26 | *.suo 27 | *.swp 28 | *.user 29 | *.userprefs 30 | *.VC.* 31 | 32 | *~master* 33 | *~HEAD* 34 | 35 | UserSettings -------------------------------------------------------------------------------- /Assets/Examples.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 784579d4c1a8f4c4db3f115dc866cc11 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Examples/0-sum-numbers-sse3.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 24da78f1175ca4543877b04a44d2b92f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Examples/0-sum-numbers-sse3/SumNumbers_SSE3.cs: -------------------------------------------------------------------------------- 1 | // Demonstrates how to use SSE to compute the sum of an array of floats. 2 | 3 | using System; 4 | using Unity.Burst; 5 | using UnityEngine; 6 | 7 | using Unity.Burst.Intrinsics; 8 | using Unity.Profiling; 9 | using UnityEngine.Assertions; 10 | using static Unity.Burst.Intrinsics.X86; 11 | // Get all SSE intrinsics in scope 12 | using static Unity.Burst.Intrinsics.X86.Sse; 13 | using static Unity.Burst.Intrinsics.Arm.Neon; 14 | using Random = UnityEngine.Random; 15 | 16 | [BurstCompile] 17 | public unsafe class SumNumbers_SSE3 : MonoBehaviour 18 | { 19 | delegate float F(float* arr, int count); 20 | F m_SumNumbers; 21 | F m_SumNumbersSimd; 22 | 23 | float[] m_Data; 24 | 25 | void Start() 26 | { 27 | m_SumNumbers = BurstCompiler.CompileFunctionPointer(ComputeSum).Invoke; 28 | m_SumNumbersSimd = BurstCompiler.CompileFunctionPointer(ComputeSumSimd).Invoke; 29 | 30 | m_Data = new float[1024 * 1024 * 16]; 31 | for (int i = 0; i < m_Data.Length; i++) 32 | m_Data[i] = Random.value; 33 | } 34 | 35 | ProfilerMarker m_SumNumbersMarker = new ProfilerMarker(nameof(ComputeSum)); 36 | ProfilerMarker m_SumNumbersSimdMarker = new ProfilerMarker(nameof(ComputeSumSimd)); 37 | 38 | void Update() 39 | { 40 | fixed (float* arr = m_Data) 41 | { 42 | m_SumNumbersMarker.Begin(); 43 | float r1 = m_SumNumbers(arr, m_Data.Length); 44 | m_SumNumbersMarker.End(); 45 | 46 | m_SumNumbersSimdMarker.Begin(); 47 | float r2 = m_SumNumbersSimd(arr, m_Data.Length); 48 | m_SumNumbersSimdMarker.End(); 49 | 50 | // Highly scientific way to detect errors in the implementation 51 | Debug.Assert(Mathf.Abs(r2 - r1) <= 500, $"{nameof(ComputeSumSimd)} returned an unreasonable result."); 52 | Debug.Log("Sum: " + r1); 53 | Debug.Log("Sum SIMD: " + r2); 54 | } 55 | } 56 | 57 | [BurstCompile(CompileSynchronously = true)] 58 | static float ComputeSum(float* arr, int count) 59 | { 60 | float sum = 0; 61 | for (int i = 0; i < count; i++) 62 | sum += arr[i]; 63 | return sum; 64 | } 65 | 66 | [BurstCompile(CompileSynchronously = true)] 67 | static float ComputeSumSimd(float* arr, int count) 68 | { 69 | // We're just going to assume that the length of the data is a multiple of 4, otherwise we'd have to handle the 70 | // other cases. It's not hard, but tedious. 71 | Assert.IsTrue(count % 4 == 0); 72 | 73 | if (Ssse3.IsSsse3Supported) 74 | { 75 | // To sum up all values in the array, we split the array into 4 subarrays and store their sums in the variable 76 | // `sum` below. 77 | v128 sum = new v128(0f); 78 | for (int i = 0; i < count; i += 4) 79 | { 80 | // Load 4 floats from memory. 81 | v128 reg = loadu_ps(arr + i); 82 | sum = add_ps(sum, reg); 83 | } 84 | 85 | // At this point, we have the sums of 4 subarrays in `sum` and we still need to merge them. SSE3 has a helpful 86 | // instruction for this: 87 | sum = Sse3.hadd_ps(sum, sum); 88 | // Now the first and third lane hold the sum of the first two subarrays and the second and fourth lane contain 89 | // the sum of the last two subarrays. 90 | sum = Sse3.hadd_ps(sum, sum); 91 | // Finally, all four lanes hold the same value (the sum of all subarrays) and we can return the first value 92 | // as a float. 93 | return cvtss_f32(sum); 94 | 95 | // or alternatively, simply write: 96 | // return sum.Float0 + sum.Float1 + sum.Float2 + sum.Float3; 97 | } 98 | else if (IsNeonSupported) 99 | { 100 | // Same as above: 4 subarrays to accumulate the sum 101 | v128 sum = new v128(0f); 102 | for (int i = 0; i < count; i += 4) 103 | { 104 | // Load 4 floats from memory. 105 | v128 reg = vld1q_f32(arr + i); 106 | sum = vaddq_f32(sum, reg); 107 | } 108 | return vaddvq_f32(sum); 109 | } 110 | else 111 | { 112 | // Managed fallback, equivalent to ComputeSum() 113 | float sum = 0; 114 | for (int i = 0; i < count; i++) 115 | sum += arr[i]; 116 | return sum; 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Assets/Examples/0-sum-numbers-sse3/SumNumbers_SSE3.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0c89a3446bf9f9249aa35287d35b9e45 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Examples/0-sum-numbers-sse3/SumNumbers_SSE3_Scene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &38536614 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 38536617} 133 | - component: {fileID: 38536616} 134 | - component: {fileID: 38536615} 135 | m_Layer: 0 136 | m_Name: Main Camera 137 | m_TagString: MainCamera 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 0 141 | m_IsActive: 1 142 | --- !u!81 &38536615 143 | AudioListener: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 38536614} 149 | m_Enabled: 1 150 | --- !u!20 &38536616 151 | Camera: 152 | m_ObjectHideFlags: 0 153 | m_CorrespondingSourceObject: {fileID: 0} 154 | m_PrefabInstance: {fileID: 0} 155 | m_PrefabAsset: {fileID: 0} 156 | m_GameObject: {fileID: 38536614} 157 | m_Enabled: 1 158 | serializedVersion: 2 159 | m_ClearFlags: 1 160 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 161 | m_projectionMatrixMode: 1 162 | m_GateFitMode: 2 163 | m_FOVAxisMode: 0 164 | m_SensorSize: {x: 36, y: 24} 165 | m_LensShift: {x: 0, y: 0} 166 | m_FocalLength: 50 167 | m_NormalizedViewPortRect: 168 | serializedVersion: 2 169 | x: 0 170 | y: 0 171 | width: 1 172 | height: 1 173 | near clip plane: 0.3 174 | far clip plane: 1000 175 | field of view: 60 176 | orthographic: 0 177 | orthographic size: 5 178 | m_Depth: -1 179 | m_CullingMask: 180 | serializedVersion: 2 181 | m_Bits: 4294967295 182 | m_RenderingPath: -1 183 | m_TargetTexture: {fileID: 0} 184 | m_TargetDisplay: 0 185 | m_TargetEye: 3 186 | m_HDR: 1 187 | m_AllowMSAA: 1 188 | m_AllowDynamicResolution: 0 189 | m_ForceIntoRT: 0 190 | m_OcclusionCulling: 1 191 | m_StereoConvergence: 10 192 | m_StereoSeparation: 0.022 193 | --- !u!4 &38536617 194 | Transform: 195 | m_ObjectHideFlags: 0 196 | m_CorrespondingSourceObject: {fileID: 0} 197 | m_PrefabInstance: {fileID: 0} 198 | m_PrefabAsset: {fileID: 0} 199 | m_GameObject: {fileID: 38536614} 200 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 201 | m_LocalPosition: {x: 0, y: 1, z: -10} 202 | m_LocalScale: {x: 1, y: 1, z: 1} 203 | m_Children: [] 204 | m_Father: {fileID: 0} 205 | m_RootOrder: 0 206 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 207 | --- !u!1 &1367786512 208 | GameObject: 209 | m_ObjectHideFlags: 0 210 | m_CorrespondingSourceObject: {fileID: 0} 211 | m_PrefabInstance: {fileID: 0} 212 | m_PrefabAsset: {fileID: 0} 213 | serializedVersion: 6 214 | m_Component: 215 | - component: {fileID: 1367786514} 216 | - component: {fileID: 1367786513} 217 | m_Layer: 0 218 | m_Name: Bootstrap 219 | m_TagString: Untagged 220 | m_Icon: {fileID: 0} 221 | m_NavMeshLayer: 0 222 | m_StaticEditorFlags: 0 223 | m_IsActive: 1 224 | --- !u!114 &1367786513 225 | MonoBehaviour: 226 | m_ObjectHideFlags: 0 227 | m_CorrespondingSourceObject: {fileID: 0} 228 | m_PrefabInstance: {fileID: 0} 229 | m_PrefabAsset: {fileID: 0} 230 | m_GameObject: {fileID: 1367786512} 231 | m_Enabled: 1 232 | m_EditorHideFlags: 0 233 | m_Script: {fileID: 11500000, guid: 0c89a3446bf9f9249aa35287d35b9e45, type: 3} 234 | m_Name: 235 | m_EditorClassIdentifier: 236 | --- !u!4 &1367786514 237 | Transform: 238 | m_ObjectHideFlags: 0 239 | m_CorrespondingSourceObject: {fileID: 0} 240 | m_PrefabInstance: {fileID: 0} 241 | m_PrefabAsset: {fileID: 0} 242 | m_GameObject: {fileID: 1367786512} 243 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 244 | m_LocalPosition: {x: 0, y: 0, z: 0} 245 | m_LocalScale: {x: 1, y: 1, z: 1} 246 | m_Children: [] 247 | m_Father: {fileID: 0} 248 | m_RootOrder: 1 249 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 250 | -------------------------------------------------------------------------------- /Assets/Examples/0-sum-numbers-sse3/SumNumbers_SSE3_Scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c5e80c7f43456c241a8ab44f68dd5faa 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Examples/1-count-small-numbers-sse2.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 706125d534316f54ebddeace9691e544 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Examples/1-count-small-numbers-sse2/CountSmallNumbers_SSE2.cs: -------------------------------------------------------------------------------- 1 | // Demonstrates how to use SSE to count the number of floats below a certain threshold in an array. 2 | 3 | using System; 4 | using Unity.Burst; 5 | using UnityEngine; 6 | 7 | using Unity.Burst.Intrinsics; 8 | using Unity.Profiling; 9 | using UnityEngine.Assertions; 10 | using static Unity.Burst.Intrinsics.X86; 11 | using static Unity.Burst.Intrinsics.X86.Sse; 12 | using static Unity.Burst.Intrinsics.X86.Sse2; 13 | using static Unity.Burst.Intrinsics.Arm.Neon; 14 | using Random = UnityEngine.Random; 15 | 16 | [BurstCompile] 17 | public unsafe class CountSmallNumbers_SSE2 : MonoBehaviour 18 | { 19 | delegate int F(float* arr, int count, float threshold); 20 | F m_CountSmallNumbers; 21 | F m_CountSmallNumbersSimd; 22 | 23 | float[] m_Data; 24 | 25 | void Start() 26 | { 27 | m_CountSmallNumbers = BurstCompiler.CompileFunctionPointer(CountSmallNumbers).Invoke; 28 | m_CountSmallNumbersSimd = BurstCompiler.CompileFunctionPointer(CountSmallNumbersSimd).Invoke; 29 | 30 | m_Data = new float[1024 * 1024 * 16]; 31 | for (int i = 0; i < m_Data.Length; i++) 32 | m_Data[i] = Random.value; 33 | } 34 | 35 | ProfilerMarker m_CountSmallNumbersMarker = new ProfilerMarker(nameof(CountSmallNumbers)); 36 | ProfilerMarker m_CountSmallNumbersSimdMarker = new ProfilerMarker(nameof(CountSmallNumbersSimd)); 37 | 38 | void Update() 39 | { 40 | fixed (float* arr = m_Data) 41 | { 42 | const float threshold = 0.45f; 43 | m_CountSmallNumbersMarker.Begin(); 44 | int r1 = m_CountSmallNumbers(arr, m_Data.Length, threshold); 45 | m_CountSmallNumbersMarker.End(); 46 | 47 | m_CountSmallNumbersSimdMarker.Begin(); 48 | int r2 = m_CountSmallNumbersSimd(arr, m_Data.Length, threshold); 49 | m_CountSmallNumbersSimdMarker.End(); 50 | 51 | Debug.Assert(r1 == r2, $"{nameof(CountSmallNumbersSimd)} returned an unreasonable result."); 52 | Debug.Log("Count: " + r1); 53 | Debug.Log("Count SIMD: " + r2); 54 | } 55 | } 56 | 57 | [BurstCompile(CompileSynchronously = true)] 58 | static int CountSmallNumbers(float* arr, int count, float threshold) 59 | { 60 | int c = 0; 61 | for (int i = 0; i < count; i++) 62 | c += arr[i] < threshold ? 1 : 0; 63 | return c; 64 | } 65 | 66 | [BurstCompile(CompileSynchronously = true)] 67 | static int CountSmallNumbersSimd(float* arr, int count, float threshold) 68 | { 69 | // We're just going to assume that the length of the data is a multiple of 4, otherwise we'd have to handle the 70 | // other cases. It's not hard, but tedious. 71 | Assert.IsTrue(count % 4 == 0); 72 | 73 | // Create a 128bit vector that has all its lanes set to `threshold`. 74 | v128 th = new v128(threshold); 75 | if (IsSse2Supported) 76 | { 77 | v128 accum = new v128(); 78 | for (int i = 0; i < count; i += 4) 79 | { 80 | // Load 4 floats from memory. 81 | v128 reg = loadu_ps(arr + i); 82 | 83 | // Compare the loaded data against the threshold. If the value in a lane is smaller than the threshold, the 84 | // lane will be set to 0xFFFFFFFF (all-one bitmask), otherwise to 0x0. 85 | v128 cmpResult = cmplt_ps(reg, th); 86 | 87 | // Subtract the compare result (thus, adding since we're subtracting -1) into 4 parallel accumulators 88 | accum = sub_epi32(accum, cmpResult); 89 | } 90 | return accum.SInt0 + accum.SInt1 + accum.SInt2 + accum.SInt3; 91 | } 92 | else if (IsNeonSupported) 93 | { 94 | v128 accum = new v128(); 95 | for (int i = 0; i < count; i += 4) 96 | { 97 | // Load 4 floats from memory. 98 | v128 reg = vld1q_f32(arr + i); 99 | 100 | // Compare the loaded data against the threshold. If the value in a lane is smaller than the threshold, the 101 | // lane will be set to 0xFFFFFFFF (all-one bitmask), otherwise to 0x0. 102 | v128 cmpResult = vcltq_f32(reg, th); 103 | 104 | // Subtract the compare result (thus, adding since we're subtracting -1) into 4 parallel accumulators 105 | accum = vsubq_s32(accum, cmpResult); 106 | } 107 | return vaddvq_s32(accum); 108 | } 109 | else 110 | { 111 | // Managed fallback, equivalent to CountSmallNumbers() 112 | int c = 0; 113 | for (int i = 0; i < count; i++) 114 | c += arr[i] < threshold ? 1 : 0; 115 | return c; 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Assets/Examples/1-count-small-numbers-sse2/CountSmallNumbers_SSE2.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da643c308dfc9ab4ca23ac246c52f525 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Examples/1-count-small-numbers-sse2/CountSmallNumbers_SSE2_Scene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &38536614 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 38536617} 133 | - component: {fileID: 38536616} 134 | - component: {fileID: 38536615} 135 | m_Layer: 0 136 | m_Name: Main Camera 137 | m_TagString: MainCamera 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 0 141 | m_IsActive: 1 142 | --- !u!81 &38536615 143 | AudioListener: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 38536614} 149 | m_Enabled: 1 150 | --- !u!20 &38536616 151 | Camera: 152 | m_ObjectHideFlags: 0 153 | m_CorrespondingSourceObject: {fileID: 0} 154 | m_PrefabInstance: {fileID: 0} 155 | m_PrefabAsset: {fileID: 0} 156 | m_GameObject: {fileID: 38536614} 157 | m_Enabled: 1 158 | serializedVersion: 2 159 | m_ClearFlags: 1 160 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 161 | m_projectionMatrixMode: 1 162 | m_GateFitMode: 2 163 | m_FOVAxisMode: 0 164 | m_SensorSize: {x: 36, y: 24} 165 | m_LensShift: {x: 0, y: 0} 166 | m_FocalLength: 50 167 | m_NormalizedViewPortRect: 168 | serializedVersion: 2 169 | x: 0 170 | y: 0 171 | width: 1 172 | height: 1 173 | near clip plane: 0.3 174 | far clip plane: 1000 175 | field of view: 60 176 | orthographic: 0 177 | orthographic size: 5 178 | m_Depth: -1 179 | m_CullingMask: 180 | serializedVersion: 2 181 | m_Bits: 4294967295 182 | m_RenderingPath: -1 183 | m_TargetTexture: {fileID: 0} 184 | m_TargetDisplay: 0 185 | m_TargetEye: 3 186 | m_HDR: 1 187 | m_AllowMSAA: 1 188 | m_AllowDynamicResolution: 0 189 | m_ForceIntoRT: 0 190 | m_OcclusionCulling: 1 191 | m_StereoConvergence: 10 192 | m_StereoSeparation: 0.022 193 | --- !u!4 &38536617 194 | Transform: 195 | m_ObjectHideFlags: 0 196 | m_CorrespondingSourceObject: {fileID: 0} 197 | m_PrefabInstance: {fileID: 0} 198 | m_PrefabAsset: {fileID: 0} 199 | m_GameObject: {fileID: 38536614} 200 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 201 | m_LocalPosition: {x: 0, y: 1, z: -10} 202 | m_LocalScale: {x: 1, y: 1, z: 1} 203 | m_Children: [] 204 | m_Father: {fileID: 0} 205 | m_RootOrder: 0 206 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 207 | --- !u!1 &1367786512 208 | GameObject: 209 | m_ObjectHideFlags: 0 210 | m_CorrespondingSourceObject: {fileID: 0} 211 | m_PrefabInstance: {fileID: 0} 212 | m_PrefabAsset: {fileID: 0} 213 | serializedVersion: 6 214 | m_Component: 215 | - component: {fileID: 1367786514} 216 | - component: {fileID: 1367786513} 217 | m_Layer: 0 218 | m_Name: Bootstrap 219 | m_TagString: Untagged 220 | m_Icon: {fileID: 0} 221 | m_NavMeshLayer: 0 222 | m_StaticEditorFlags: 0 223 | m_IsActive: 1 224 | --- !u!114 &1367786513 225 | MonoBehaviour: 226 | m_ObjectHideFlags: 0 227 | m_CorrespondingSourceObject: {fileID: 0} 228 | m_PrefabInstance: {fileID: 0} 229 | m_PrefabAsset: {fileID: 0} 230 | m_GameObject: {fileID: 1367786512} 231 | m_Enabled: 1 232 | m_EditorHideFlags: 0 233 | m_Script: {fileID: 11500000, guid: da643c308dfc9ab4ca23ac246c52f525, type: 3} 234 | m_Name: 235 | m_EditorClassIdentifier: 236 | --- !u!4 &1367786514 237 | Transform: 238 | m_ObjectHideFlags: 0 239 | m_CorrespondingSourceObject: {fileID: 0} 240 | m_PrefabInstance: {fileID: 0} 241 | m_PrefabAsset: {fileID: 0} 242 | m_GameObject: {fileID: 1367786512} 243 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 244 | m_LocalPosition: {x: 0, y: 0, z: 0} 245 | m_LocalScale: {x: 1, y: 1, z: 1} 246 | m_Children: [] 247 | m_Father: {fileID: 0} 248 | m_RootOrder: 1 249 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 250 | -------------------------------------------------------------------------------- /Assets/Examples/1-count-small-numbers-sse2/CountSmallNumbers_SSE2_Scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3a0e1f1737267604199a127079b14e29 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Examples/2-sum-small-numbers-sse3.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ae5b980b47064340b4608b814372f3f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Examples/2-sum-small-numbers-sse3/SumSmallNumbers_SSE3.cs: -------------------------------------------------------------------------------- 1 | // Demonstrates how to use SSE to compute the sum of all numbers below a threshold in an array of floats. 2 | 3 | using System; 4 | using Unity.Burst; 5 | using UnityEngine; 6 | 7 | using Unity.Burst.Intrinsics; 8 | using Unity.Profiling; 9 | using UnityEngine.Assertions; 10 | using static Unity.Burst.Intrinsics.X86; 11 | using static Unity.Burst.Intrinsics.X86.Sse; 12 | using static Unity.Burst.Intrinsics.Arm.Neon; 13 | using Random = UnityEngine.Random; 14 | 15 | [BurstCompile] 16 | public unsafe class SumSmallNumbers_SSE3 : MonoBehaviour 17 | { 18 | delegate float F(float* arr, int count, float threshold); 19 | F m_SumNumbers; 20 | F m_SumNumbersSimd; 21 | 22 | float[] m_Data; 23 | 24 | void Start() 25 | { 26 | m_SumNumbers = BurstCompiler.CompileFunctionPointer(ComputeSum).Invoke; 27 | m_SumNumbersSimd = BurstCompiler.CompileFunctionPointer(ComputeSumSimd).Invoke; 28 | 29 | m_Data = new float[1024 * 1024 * 16]; 30 | for (int i = 0; i < m_Data.Length; i++) 31 | m_Data[i] = Random.value; 32 | } 33 | 34 | ProfilerMarker m_SumNumbersMarker = new ProfilerMarker(nameof(ComputeSum)); 35 | ProfilerMarker m_SumNumbersSimdMarker = new ProfilerMarker(nameof(ComputeSumSimd)); 36 | 37 | void Update() 38 | { 39 | fixed (float* arr = m_Data) 40 | { 41 | const float threshold = 0.75f; 42 | m_SumNumbersMarker.Begin(); 43 | float r1 = m_SumNumbers(arr, m_Data.Length, threshold); 44 | m_SumNumbersMarker.End(); 45 | 46 | m_SumNumbersSimdMarker.Begin(); 47 | float r2 = m_SumNumbersSimd(arr, m_Data.Length, threshold); 48 | m_SumNumbersSimdMarker.End(); 49 | 50 | // Highly scientific way to detect errors in the implementation 51 | Debug.Assert(Mathf.Abs(r2 - r1) <= 400, $"{nameof(ComputeSumSimd)} returned an unreasonable result."); 52 | Debug.Log("Sum: " + r1); 53 | Debug.Log("Sum SIMD: " + r2); 54 | } 55 | } 56 | 57 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 58 | static float ComputeSum(float* arr, int count, float threshold) 59 | { 60 | float sum = 0; 61 | for (int i = 0; i < count; i++) 62 | { 63 | if (arr[i] < threshold) 64 | sum += arr[i]; 65 | } 66 | 67 | return sum; 68 | } 69 | 70 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 71 | static float ComputeSumSimd(float* arr, int count, float threshold) 72 | { 73 | // We're just going to assume that the length of the data is a multiple of 4, otherwise we'd have to handle the 74 | // other cases. It's not hard, but tedious. 75 | Assert.IsTrue(count % 4 == 0); 76 | 77 | if (Ssse3.IsSsse3Supported) 78 | { 79 | // To sum up all values in the array, we split the array into 4 subarrays and store their sums in the variable 80 | // `sum` below. 81 | v128 sum = new v128(0f); 82 | v128 th = new v128(threshold); 83 | for (int i = 0; i < count; i += 4) 84 | { 85 | // Load 4 floats from memory. 86 | v128 reg = loadu_ps(arr + i); 87 | 88 | // Compare the loaded data against the threshold. If the value in a lane is smaller than the threshold, the 89 | // lane will be set to 0xFFFFFFFF (all-one bitmask), otherwise to 0x0. 90 | v128 mask = cmplt_ps(reg, th); 91 | 92 | // Compute the binary-and with the mask to set all numbers above the threshold to zero. 93 | sum = add_ps(sum, and_ps(reg, mask)); 94 | } 95 | 96 | return sum.Float0 + sum.Float1 + sum.Float2 + sum.Float3; 97 | } 98 | else if (IsNeonSupported) 99 | { 100 | // To sum up all values in the array, we split the array into 4 subarrays and store their sums in the variable 101 | // `sum` below. 102 | v128 sum = new v128(0f); 103 | v128 th = new v128(threshold); 104 | for (int i = 0; i < count; i += 4) 105 | { 106 | // Load 4 floats from memory. 107 | v128 reg = vld1q_f32(arr + i); 108 | 109 | // Compare the loaded data against the threshold. If the value in a lane is smaller than the threshold, the 110 | // lane will be set to 0xFFFFFFFF (all-one bitmask), otherwise to 0x0. 111 | v128 mask = vcltq_f32(reg, th); 112 | 113 | // Compute the binary-and with the mask to set all numbers above the threshold to zero. 114 | sum = vaddq_f32(sum, vandq_s32(reg, mask)); 115 | } 116 | 117 | return vaddvq_f32(sum); 118 | } 119 | else 120 | { 121 | // Managed fallback, equivalent to ComputeSum() 122 | float sum = 0; 123 | for (int i = 0; i < count; i++) 124 | { 125 | if (arr[i] < threshold) 126 | sum += arr[i]; 127 | } 128 | 129 | return sum; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /Assets/Examples/2-sum-small-numbers-sse3/SumSmallNumbers_SSE3.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9f8abe75f01c71f43baaf3eaa933e17f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Examples/2-sum-small-numbers-sse3/SumSmallNumbers_SSE3_Scene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &38536614 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 38536617} 133 | - component: {fileID: 38536616} 134 | - component: {fileID: 38536615} 135 | m_Layer: 0 136 | m_Name: Main Camera 137 | m_TagString: MainCamera 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 0 141 | m_IsActive: 1 142 | --- !u!81 &38536615 143 | AudioListener: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 38536614} 149 | m_Enabled: 1 150 | --- !u!20 &38536616 151 | Camera: 152 | m_ObjectHideFlags: 0 153 | m_CorrespondingSourceObject: {fileID: 0} 154 | m_PrefabInstance: {fileID: 0} 155 | m_PrefabAsset: {fileID: 0} 156 | m_GameObject: {fileID: 38536614} 157 | m_Enabled: 1 158 | serializedVersion: 2 159 | m_ClearFlags: 1 160 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 161 | m_projectionMatrixMode: 1 162 | m_GateFitMode: 2 163 | m_FOVAxisMode: 0 164 | m_SensorSize: {x: 36, y: 24} 165 | m_LensShift: {x: 0, y: 0} 166 | m_FocalLength: 50 167 | m_NormalizedViewPortRect: 168 | serializedVersion: 2 169 | x: 0 170 | y: 0 171 | width: 1 172 | height: 1 173 | near clip plane: 0.3 174 | far clip plane: 1000 175 | field of view: 60 176 | orthographic: 0 177 | orthographic size: 5 178 | m_Depth: -1 179 | m_CullingMask: 180 | serializedVersion: 2 181 | m_Bits: 4294967295 182 | m_RenderingPath: -1 183 | m_TargetTexture: {fileID: 0} 184 | m_TargetDisplay: 0 185 | m_TargetEye: 3 186 | m_HDR: 1 187 | m_AllowMSAA: 1 188 | m_AllowDynamicResolution: 0 189 | m_ForceIntoRT: 0 190 | m_OcclusionCulling: 1 191 | m_StereoConvergence: 10 192 | m_StereoSeparation: 0.022 193 | --- !u!4 &38536617 194 | Transform: 195 | m_ObjectHideFlags: 0 196 | m_CorrespondingSourceObject: {fileID: 0} 197 | m_PrefabInstance: {fileID: 0} 198 | m_PrefabAsset: {fileID: 0} 199 | m_GameObject: {fileID: 38536614} 200 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 201 | m_LocalPosition: {x: 0, y: 1, z: -10} 202 | m_LocalScale: {x: 1, y: 1, z: 1} 203 | m_Children: [] 204 | m_Father: {fileID: 0} 205 | m_RootOrder: 0 206 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 207 | --- !u!1 &1367786512 208 | GameObject: 209 | m_ObjectHideFlags: 0 210 | m_CorrespondingSourceObject: {fileID: 0} 211 | m_PrefabInstance: {fileID: 0} 212 | m_PrefabAsset: {fileID: 0} 213 | serializedVersion: 6 214 | m_Component: 215 | - component: {fileID: 1367786514} 216 | - component: {fileID: 1367786513} 217 | m_Layer: 0 218 | m_Name: Bootstrap 219 | m_TagString: Untagged 220 | m_Icon: {fileID: 0} 221 | m_NavMeshLayer: 0 222 | m_StaticEditorFlags: 0 223 | m_IsActive: 1 224 | --- !u!114 &1367786513 225 | MonoBehaviour: 226 | m_ObjectHideFlags: 0 227 | m_CorrespondingSourceObject: {fileID: 0} 228 | m_PrefabInstance: {fileID: 0} 229 | m_PrefabAsset: {fileID: 0} 230 | m_GameObject: {fileID: 1367786512} 231 | m_Enabled: 1 232 | m_EditorHideFlags: 0 233 | m_Script: {fileID: 11500000, guid: 9f8abe75f01c71f43baaf3eaa933e17f, type: 3} 234 | m_Name: 235 | m_EditorClassIdentifier: 236 | --- !u!4 &1367786514 237 | Transform: 238 | m_ObjectHideFlags: 0 239 | m_CorrespondingSourceObject: {fileID: 0} 240 | m_PrefabInstance: {fileID: 0} 241 | m_PrefabAsset: {fileID: 0} 242 | m_GameObject: {fileID: 1367786512} 243 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 244 | m_LocalPosition: {x: 0, y: 0, z: 0} 245 | m_LocalScale: {x: 1, y: 1, z: 1} 246 | m_Children: [] 247 | m_Father: {fileID: 0} 248 | m_RootOrder: 1 249 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 250 | -------------------------------------------------------------------------------- /Assets/Examples/2-sum-small-numbers-sse3/SumSmallNumbers_SSE3_Scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7436cfc3f94c7a049916907d26930266 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Exercises.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 047899113504ece43952f9a8a3761b21 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/0-sphere-collisions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3a833217f89827f4a86670d8b64c30ae 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/0-sphere-collisions/SphereCollisions.cs: -------------------------------------------------------------------------------- 1 | // Given a list of spheres and another sphere, compute the index of the first sphere that overlaps with the additional 2 | // sphere, and the number of intersections in total. 3 | // Feel free to change the data around to whatever format is the most suitable for doing SIMD. 4 | using Unity.Burst; 5 | using Unity.Mathematics; 6 | using Unity.Profiling; 7 | using UnityEngine; 8 | using UnityEngine.Assertions; 9 | using Random = UnityEngine.Random; 10 | 11 | [BurstCompile] 12 | public unsafe class SphereCollisions : MonoBehaviour 13 | { 14 | delegate int SphereVsSpheres(Sphere* spheres, int numSpheres, float3* sphere, float radius, out int numIntersections); 15 | delegate int SphereVsSpheresSimd(Sphere* spheres, int numSpheres, float3* sphere, float radius, out int numIntersections); 16 | 17 | SphereVsSpheres m_SphereVsSpheres; 18 | SphereVsSpheresSimd m_SphereVsSpheresSimd; 19 | 20 | bool m_UseSimd; 21 | 22 | ProfilerMarker m_SphereVsSpheresMarker = new ProfilerMarker("SphereVsSpheres"); 23 | ProfilerMarker m_SphereVsSpheresSimdMarker = new ProfilerMarker("SphereVsSpheresSimd"); 24 | 25 | Sphere[] m_Spheres; 26 | 27 | struct Sphere 28 | { 29 | public float3 Position; 30 | public float Radius; 31 | } 32 | 33 | void Start() 34 | { 35 | m_SphereVsSpheres = BurstCompiler.CompileFunctionPointer(DoSphereVsSpheres).Invoke; 36 | m_SphereVsSpheresSimd = BurstCompiler.CompileFunctionPointer(DoSphereVsSpheresSimd).Invoke; 37 | m_Spheres = new Sphere[4096]; 38 | } 39 | 40 | void Update() 41 | { 42 | for (int i = 0; i < m_Spheres.Length; i++) 43 | { 44 | m_Spheres[i] = new Sphere 45 | { 46 | Position = new float3(Random.value, Random.value, Random.value), 47 | Radius = Random.value * .01f 48 | }; 49 | } 50 | 51 | float3 center = new float3(Random.value, Random.value, Random.value); 52 | float radius = Random.value * .01f; 53 | 54 | int firstOverlap, numIntersections; 55 | fixed (Sphere* spheres = m_Spheres) 56 | { 57 | m_SphereVsSpheresMarker.Begin(); 58 | firstOverlap = m_SphereVsSpheres(spheres, m_Spheres.Length, ¢er, radius, out numIntersections); 59 | m_SphereVsSpheresMarker.End(); 60 | } 61 | 62 | int firstOverlapSimd, numIntersectionsSimd; 63 | fixed (Sphere* spheres = m_Spheres) 64 | { 65 | m_SphereVsSpheresSimdMarker.Begin(); 66 | firstOverlapSimd = m_SphereVsSpheresSimd(spheres, m_Spheres.Length, ¢er, radius, out numIntersectionsSimd); 67 | m_SphereVsSpheresSimdMarker.End(); 68 | } 69 | Assert.AreEqual(firstOverlap, firstOverlapSimd, "The index of the first overlap must be the same!"); 70 | Assert.AreEqual(numIntersections, numIntersectionsSimd, "The number of intersections must be the same!"); 71 | } 72 | 73 | /// 74 | /// Computes the index of the first sphere that overlaps with the given sphere. 75 | /// 76 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 77 | static int DoSphereVsSpheres(Sphere* spheres, int numSpheres, float3* centerPtr, float radius, out int numIntersections) 78 | { 79 | float3 center = *centerPtr; 80 | int first = numSpheres; 81 | int n = 0; 82 | for (int i = 0; i < numSpheres; i++) 83 | { 84 | float r = spheres[i].Radius + radius; 85 | if (math.distancesq(spheres[i].Position, center) < r * r) 86 | { 87 | if (i < first) 88 | first = i; 89 | n++; 90 | } 91 | } 92 | 93 | numIntersections = n; 94 | 95 | return first == numSpheres ? -1 : first; 96 | } 97 | 98 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 99 | static int DoSphereVsSpheresSimd(Sphere* spheres, int numSpheres, float3* center, float radius, out int numIntersections) 100 | { 101 | // YOUR SIMD CODE HERE 102 | numIntersections = 0; 103 | return -1; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Assets/Exercises/0-sphere-collisions/SphereCollisions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0ee52ac19c1a8c448e5f3bc0a240606 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Exercises/0-sphere-collisions/SphereCollisions_Scene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &593600312 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 593600315} 133 | - component: {fileID: 593600314} 134 | - component: {fileID: 593600313} 135 | m_Layer: 0 136 | m_Name: Main Camera 137 | m_TagString: MainCamera 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 0 141 | m_IsActive: 1 142 | --- !u!81 &593600313 143 | AudioListener: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 593600312} 149 | m_Enabled: 1 150 | --- !u!20 &593600314 151 | Camera: 152 | m_ObjectHideFlags: 0 153 | m_CorrespondingSourceObject: {fileID: 0} 154 | m_PrefabInstance: {fileID: 0} 155 | m_PrefabAsset: {fileID: 0} 156 | m_GameObject: {fileID: 593600312} 157 | m_Enabled: 1 158 | serializedVersion: 2 159 | m_ClearFlags: 1 160 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 161 | m_projectionMatrixMode: 1 162 | m_GateFitMode: 2 163 | m_FOVAxisMode: 0 164 | m_SensorSize: {x: 36, y: 24} 165 | m_LensShift: {x: 0, y: 0} 166 | m_FocalLength: 50 167 | m_NormalizedViewPortRect: 168 | serializedVersion: 2 169 | x: 0 170 | y: 0 171 | width: 1 172 | height: 1 173 | near clip plane: 0.3 174 | far clip plane: 1000 175 | field of view: 60 176 | orthographic: 0 177 | orthographic size: 5 178 | m_Depth: -1 179 | m_CullingMask: 180 | serializedVersion: 2 181 | m_Bits: 4294967295 182 | m_RenderingPath: -1 183 | m_TargetTexture: {fileID: 0} 184 | m_TargetDisplay: 0 185 | m_TargetEye: 3 186 | m_HDR: 1 187 | m_AllowMSAA: 1 188 | m_AllowDynamicResolution: 0 189 | m_ForceIntoRT: 0 190 | m_OcclusionCulling: 1 191 | m_StereoConvergence: 10 192 | m_StereoSeparation: 0.022 193 | --- !u!4 &593600315 194 | Transform: 195 | m_ObjectHideFlags: 0 196 | m_CorrespondingSourceObject: {fileID: 0} 197 | m_PrefabInstance: {fileID: 0} 198 | m_PrefabAsset: {fileID: 0} 199 | m_GameObject: {fileID: 593600312} 200 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 201 | m_LocalPosition: {x: 0, y: 1, z: -10} 202 | m_LocalScale: {x: 1, y: 1, z: 1} 203 | m_Children: [] 204 | m_Father: {fileID: 0} 205 | m_RootOrder: 0 206 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 207 | --- !u!1 &817859655 208 | GameObject: 209 | m_ObjectHideFlags: 0 210 | m_CorrespondingSourceObject: {fileID: 0} 211 | m_PrefabInstance: {fileID: 0} 212 | m_PrefabAsset: {fileID: 0} 213 | serializedVersion: 6 214 | m_Component: 215 | - component: {fileID: 817859656} 216 | - component: {fileID: 817859657} 217 | m_Layer: 0 218 | m_Name: Bootstrap 219 | m_TagString: Untagged 220 | m_Icon: {fileID: 0} 221 | m_NavMeshLayer: 0 222 | m_StaticEditorFlags: 0 223 | m_IsActive: 1 224 | --- !u!4 &817859656 225 | Transform: 226 | m_ObjectHideFlags: 0 227 | m_CorrespondingSourceObject: {fileID: 0} 228 | m_PrefabInstance: {fileID: 0} 229 | m_PrefabAsset: {fileID: 0} 230 | m_GameObject: {fileID: 817859655} 231 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 232 | m_LocalPosition: {x: 0, y: 0, z: 0} 233 | m_LocalScale: {x: 1, y: 1, z: 1} 234 | m_Children: [] 235 | m_Father: {fileID: 0} 236 | m_RootOrder: 1 237 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 238 | --- !u!114 &817859657 239 | MonoBehaviour: 240 | m_ObjectHideFlags: 0 241 | m_CorrespondingSourceObject: {fileID: 0} 242 | m_PrefabInstance: {fileID: 0} 243 | m_PrefabAsset: {fileID: 0} 244 | m_GameObject: {fileID: 817859655} 245 | m_Enabled: 1 246 | m_EditorHideFlags: 0 247 | m_Script: {fileID: 11500000, guid: c0ee52ac19c1a8c448e5f3bc0a240606, type: 3} 248 | m_Name: 249 | m_EditorClassIdentifier: 250 | -------------------------------------------------------------------------------- /Assets/Exercises/0-sphere-collisions/SphereCollisions_Scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98f7240df72302646a1903793e63054d 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Exercises/1-math-grabbag.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 07f7971fabf9aeb41ae2099047a69b90 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/1-math-grabbag/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba707b02bdba8ef47a54ebe09f6cd986 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/1-math-grabbag/Editor/SimdMathTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Unity.Burst; 3 | using Unity.Mathematics; 4 | using Random = UnityEngine.Random; 5 | 6 | [BurstCompile] 7 | public unsafe class SimdMathTests 8 | { 9 | delegate void FilterSmallNumbers(float* input, int length, float* output, out int numCopied); 10 | delegate void MatrixVectorMultiply(float4x4* matrixPtr, float4* vectors, int numVectors); 11 | delegate void RunningSum(int* arr, int length); 12 | 13 | static void FilterSmallNumbersTestCase(uint seed, int length, FilterSmallNumbers scalar, FilterSmallNumbers simd) 14 | { 15 | var rng = new Unity.Mathematics.Random(seed); 16 | var inputs = new float[length]; 17 | var outputsScalar = new float[length]; 18 | var outputsSimd = new float[length]; 19 | for (int i = 0; i < length; i++) 20 | inputs[i] = rng.NextFloat() * 3; 21 | 22 | int outLengthScalar, outLengthSimd; 23 | fixed (float* inputPtr = inputs) 24 | { 25 | fixed (float* outputPtr = outputsScalar) 26 | scalar(inputPtr, length, outputPtr, out outLengthScalar); 27 | fixed (float* outputPtr = outputsSimd) 28 | simd(inputPtr, length, outputPtr, out outLengthSimd); 29 | } 30 | 31 | Assert.AreEqual(outLengthScalar, outLengthSimd, $"SIMD version failed with seed {seed} with input length {length}: Different number of results"); 32 | for (int i = 0; i < outLengthScalar; i++) 33 | { 34 | Assert.AreEqual(outputsScalar[i], outputsSimd[i], $"SIMD version failed with seed {seed} with input length {length}: Different output at index {i}"); 35 | } 36 | } 37 | 38 | [Test] 39 | public static void FilterSmallNumbersWorksWith16() 40 | { 41 | var scalar = BurstCompiler.CompileFunctionPointer(SimdMath.FilterSmallNumbers).Invoke; 42 | var simd = BurstCompiler.CompileFunctionPointer(SimdMath.FilterSmallNumbersSIMD).Invoke; 43 | 44 | for (int testCase = 0; testCase < 100; testCase++) 45 | { 46 | Random.InitState(testCase); 47 | int length = Random.Range(5, 20) * 16; 48 | uint seed = 3628273133 * ((uint)testCase + 1); 49 | FilterSmallNumbersTestCase(seed, length, scalar, simd); 50 | } 51 | } 52 | 53 | [Test] 54 | public static void FilterSmallNumbersWorksWithOddLengths() 55 | { 56 | var scalar = BurstCompiler.CompileFunctionPointer(SimdMath.FilterSmallNumbers).Invoke; 57 | var simd = BurstCompiler.CompileFunctionPointer(SimdMath.FilterSmallNumbersSIMD).Invoke; 58 | 59 | for (int testCase = 0; testCase < 100; testCase++) 60 | { 61 | Random.InitState(testCase); 62 | int length = Random.Range(5 * 16, 20 * 16); 63 | uint seed = 3628273133 * ((uint)testCase + 1); 64 | FilterSmallNumbersTestCase(seed, length, scalar, simd); 65 | } 66 | } 67 | 68 | static void MatrixVectorMultiplyTestCase(uint seed, int length, MatrixVectorMultiply scalar, MatrixVectorMultiply simd) 69 | { 70 | Unity.Mathematics.Random rng = new Unity.Mathematics.Random(seed); 71 | var matrix = new float4x4(rng.NextFloat4(), rng.NextFloat4(), rng.NextFloat4(), rng.NextFloat4()); 72 | var vectorsScalar = new float4[length]; 73 | var vectorsSimd = new float4[length]; 74 | for (int i = 0; i < length; i++) 75 | vectorsScalar[i] = vectorsSimd[i] = rng.NextFloat4(); 76 | 77 | fixed (float4* outputPtr = vectorsScalar) 78 | scalar(&matrix, outputPtr, length); 79 | fixed (float4* outputPtr = vectorsSimd) 80 | simd(&matrix, outputPtr, length); 81 | 82 | for (int i = 0; i < length; i++) 83 | { 84 | bool almostEqual = math.all( 85 | math.abs(vectorsScalar[i] - vectorsSimd[i]) < new float4(0.01f) 86 | ); 87 | Assert.IsTrue(almostEqual, $"SIMD version failed with seed {seed} with input length {length}: Different output at index {i}"); 88 | } 89 | } 90 | 91 | [Test] 92 | public static void MatrixVectorMultiplyWorksWith16() 93 | { 94 | var scalar = BurstCompiler.CompileFunctionPointer(SimdMath.MatrixVectorMultiply).Invoke; 95 | var simd = BurstCompiler.CompileFunctionPointer(SimdMath.MatrixVectorMultiplySIMD).Invoke; 96 | 97 | for (int testCase = 0; testCase < 100; testCase++) 98 | { 99 | Random.InitState(testCase); 100 | int length = Random.Range(5, 20) * 16; 101 | uint seed = 3628273133 * ((uint)testCase + 1); 102 | MatrixVectorMultiplyTestCase(seed, length, scalar, simd); 103 | } 104 | } 105 | 106 | [Test] 107 | public static void MatrixVectorMultiplyWorksWithOddLengths() 108 | { 109 | var scalar = BurstCompiler.CompileFunctionPointer(SimdMath.MatrixVectorMultiply).Invoke; 110 | var simd = BurstCompiler.CompileFunctionPointer(SimdMath.MatrixVectorMultiplySIMD).Invoke; 111 | 112 | for (int testCase = 0; testCase < 100; testCase++) 113 | { 114 | Random.InitState(testCase); 115 | int length = Random.Range(5 * 16, 20 * 16); 116 | uint seed = 3628273133 * ((uint)testCase + 1); 117 | MatrixVectorMultiplyTestCase(seed, length, scalar, simd); 118 | } 119 | } 120 | 121 | static void RunningSumTestCase(uint seed, int length, RunningSum scalar, RunningSum simd) 122 | { 123 | Unity.Mathematics.Random rng = new Unity.Mathematics.Random(seed); 124 | var arrayScalar = new int[length]; 125 | var arraySimd = new int[length]; 126 | for (int i = 0; i < length; i++) 127 | arrayScalar[i] = arraySimd[i] = rng.NextInt(); 128 | 129 | fixed (int* outputPtr = arrayScalar) 130 | scalar(outputPtr, length); 131 | fixed (int* outputPtr = arraySimd) 132 | simd(outputPtr, length); 133 | 134 | for (int i = 0; i < length; i++) 135 | { 136 | Assert.AreEqual(arrayScalar[i], arraySimd[i], $"SIMD version failed with seed {seed} with input length {length}: Different output at index {i}"); 137 | } 138 | } 139 | 140 | [Test] 141 | public static void RunningSumWorksWith16() 142 | { 143 | var scalar = BurstCompiler.CompileFunctionPointer(SimdMath.RunningSum).Invoke; 144 | var simd = BurstCompiler.CompileFunctionPointer(SimdMath.RunningSumSIMD).Invoke; 145 | 146 | for (int testCase = 0; testCase < 100; testCase++) 147 | { 148 | Random.InitState(testCase); 149 | int length = Random.Range(5, 20) * 16; 150 | uint seed = 3628273133 * ((uint)testCase + 1); 151 | RunningSumTestCase(seed, length, scalar, simd); 152 | } 153 | } 154 | 155 | [Test] 156 | public static void RunningSumWorksWithOddLengths() 157 | { 158 | var scalar = BurstCompiler.CompileFunctionPointer(SimdMath.RunningSum).Invoke; 159 | var simd = BurstCompiler.CompileFunctionPointer(SimdMath.RunningSumSIMD).Invoke; 160 | 161 | for (int testCase = 0; testCase < 100; testCase++) 162 | { 163 | Random.InitState(testCase); 164 | int length = Random.Range(5 * 16, 20 * 16); 165 | uint seed = 3628273133 * ((uint)testCase + 1); 166 | RunningSumTestCase(seed, length, scalar, simd); 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /Assets/Exercises/1-math-grabbag/Editor/SimdMathTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 08caeabac15c1154f8edd7a8882c480e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Exercises/1-math-grabbag/SimdMath.cs: -------------------------------------------------------------------------------- 1 | // This file contains a bunch of smaller exercises, each with a scalar implementation and a stub for 2 | // you to start implementing your SIMD version. 3 | // 4 | // In these exercises, you are not expected to change the layout of the input data. 5 | // 6 | // Check out the tests in SimdMathTests to check your implementations. 7 | 8 | using Unity.Burst; 9 | using Unity.Mathematics; 10 | using UnityEngine; 11 | 12 | [BurstCompile] 13 | public static unsafe class SimdMath 14 | { 15 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 16 | public static void MatrixVectorMultiply(float4x4* matrixPtr, float4* vectors, int numVectors) 17 | { 18 | float4x4 matrix = *matrixPtr; 19 | for (int i = 0; i < numVectors; i++) 20 | vectors[i] = math.mul(matrix, vectors[i]); 21 | } 22 | 23 | /// 24 | /// Multiply all vectors in-place with the given matrix and store them back. 25 | /// 26 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 27 | public static void MatrixVectorMultiplySIMD(float4x4* matrixPtr, float4* vectors, int numVectors) 28 | { 29 | // YOUR SIMD CODE HERE 30 | } 31 | 32 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 33 | public static void RunningSum(int* arr, int length) 34 | { 35 | int sum = 0; 36 | for (int i = 0; i < length; i++) 37 | { 38 | sum += arr[i]; 39 | arr[i] = sum; 40 | } 41 | } 42 | 43 | /// 44 | /// Compute a running sum and write it back to the input array, so the i-th entry contains the 45 | /// sum of all elements up-to and including itself. 46 | /// 47 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 48 | public static void RunningSumSIMD(int* arr, int length) 49 | { 50 | // YOUR SIMD CODE HERE 51 | } 52 | 53 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 54 | public static void FilterSmallNumbers(float* input, int n, float* output, out int numCopied) 55 | { 56 | int copied = 0; 57 | for (int i = 0; i < n; i++) 58 | { 59 | if (*input < 1) 60 | { 61 | *output = *input; 62 | output++; 63 | copied++; 64 | } 65 | 66 | input++; 67 | } 68 | numCopied = copied; 69 | } 70 | 71 | /// 72 | /// Copy all numbers smaller 1 from the input to the output. The output is big enough to hold all of the input. 73 | /// Do not change the order of the numbers in the output. 74 | /// 75 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 76 | public static void FilterSmallNumbersSIMD(float* input, int n, float* output, out int numCopied) 77 | { 78 | // YOUR SIMD CODE HERE 79 | numCopied = 0; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Assets/Exercises/1-math-grabbag/SimdMath.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 29b14013d903ccb4dbdee8f06545da06 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Exercises/2-mandelbrot-render.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f1d023c9d66428a45b233479d1e9093b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/2-mandelbrot-render/MandelbrotMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: MandelbrotMaterial 11 | m_Shader: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 1, g: 1, b: 1, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Assets/Exercises/2-mandelbrot-render/MandelbrotMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aa4bae83afe885348a5441871b7b7872 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/2-mandelbrot-render/MandelbrotRender.cs: -------------------------------------------------------------------------------- 1 | // Port a renderer for the Mandelbrot fractal to SIMD! 2 | // The Mandelbrot fractal can be computed as follows: 3 | // 1. Take a subset of the complex plane (e.g. all float2 between (-1, -1) and (1, 1)) 4 | // 2. Map each pixel of your image to its corresponding point in that subset of the plane 5 | // 3. For each such point c, iterate the function z => z * z + c with z = (0, 0) as the initial value 6 | // and * as complex multiplication. 7 | // 4. Count the number of iterations it takes until dot(z, z) >= 4. 8 | // 5. Color the pixel in proportion to the number of steps taken. 9 | 10 | using Unity.Burst; 11 | using Unity.Collections.LowLevel.Unsafe; 12 | using Unity.Mathematics; 13 | using Unity.Profiling; 14 | using UnityEngine; 15 | 16 | [BurstCompile] 17 | public unsafe class MandelbrotRender : MonoBehaviour 18 | { 19 | public Material TargetMaterial; 20 | 21 | delegate void Render(float* pixels, float minX, float minY, float maxX, float maxY); 22 | 23 | Render m_RenderMandelbrot; 24 | Render m_RenderMandelbrotSimd; 25 | 26 | const int k_Height = 512; 27 | const int k_Width = 512; 28 | const int k_MaxSteps = 64; 29 | bool m_UseSimd; 30 | Texture2D m_Texture; 31 | 32 | static float2 s_Center = new float2(-0.7106f, 0.246575f); 33 | static float2 s_Min = new float2(-1.5f, -1.5f); 34 | static float2 s_Max = new float2(1, 1.5f); 35 | 36 | float m_Zoom = 1.0f; 37 | 38 | ProfilerMarker m_RenderMandelbrotMarker = new ProfilerMarker("RenderMandelbrot"); 39 | 40 | void Start() 41 | { 42 | m_Texture = new Texture2D(k_Width, k_Height, TextureFormat.RFloat, true, true); 43 | TargetMaterial.mainTexture = m_Texture; 44 | 45 | m_RenderMandelbrot = BurstCompiler.CompileFunctionPointer(RenderMandelbrot).Invoke; 46 | m_RenderMandelbrotSimd = BurstCompiler.CompileFunctionPointer(RenderMandelbrotSimd).Invoke; 47 | } 48 | 49 | void Update() 50 | { 51 | var pixels = m_Texture.GetRawTextureData(); 52 | if (Input.GetKeyDown(KeyCode.Space)) 53 | { 54 | m_UseSimd = !m_UseSimd; 55 | UnsafeUtility.MemClear(pixels.GetUnsafePtr(), pixels.Length * sizeof(float)); 56 | Debug.Log("SIMD is " + (m_UseSimd ? "on" : "off")); 57 | } 58 | else 59 | { 60 | m_RenderMandelbrotMarker.Begin(); 61 | 62 | m_Zoom *= 0.995f; 63 | var min = s_Min * m_Zoom + s_Center; 64 | var max = s_Max * m_Zoom + s_Center; 65 | if (m_UseSimd) 66 | m_RenderMandelbrotSimd((float*)pixels.GetUnsafePtr(), min.x, min.y, max.x, max.y); 67 | else 68 | m_RenderMandelbrot((float*)pixels.GetUnsafePtr(), min.x, min.y, max.x, max.y); 69 | m_RenderMandelbrotMarker.End(); 70 | } 71 | m_Texture.Apply(); 72 | } 73 | 74 | /// 75 | /// Colors the given pixels by the number of iterations that the corresponding point needs until to escape. 76 | /// 77 | /// Represents each pixel as a float that will be used as the red-channel. 78 | /// The minimum x value of the viewport in the complex plane. 79 | /// The minimum y value of the viewport in the complex plane. 80 | /// The maximum x value of the viewport in the complex plane. 81 | /// The maximum y value of the viewport in the complex plane. 82 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 83 | static void RenderMandelbrot(float* pixels, float minX, float minY, float maxX, float maxY) 84 | { 85 | float2 min = new float2(minX, minY); 86 | float2 max = new float2(maxX, maxY); 87 | float2 delta = (max - min) / new float2(k_Width, k_Height); 88 | const float t = 1f / k_MaxSteps; 89 | 90 | for (int y = 0; y < k_Height; y++) 91 | { 92 | for (int x = 0; x < k_Width; x++) 93 | { 94 | // This loop-body iterates 95 | // z => z * z + c 96 | // until |z| >= 2, with * denoting multiplication of complex numbers. 97 | // We don't actually use complex multiplication, but simplify it to what you 98 | // see below 99 | var c = min + new float2(x, y) * delta; 100 | var z = new float2(0, 0); 101 | 102 | int step = 0; 103 | for (; step < k_MaxSteps; step++) 104 | { 105 | var sq = z * z; 106 | if (math.lengthsq(sq) > 4) 107 | break; 108 | z = new float2(sq.x - sq.y, 2 * z.x * z.y) + c; 109 | } 110 | 111 | pixels[y * k_Width + x] = t * step; 112 | } 113 | } 114 | } 115 | 116 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 117 | static void RenderMandelbrotSimd(float* pixels, float minX, float minY, float maxX, float maxY) 118 | { 119 | // YOUR SIMD CODE HERE 120 | // You can assume that height/width is set to a constant that is divisible by 16 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Assets/Exercises/2-mandelbrot-render/MandelbrotRender.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 91ddda2b7120f624bab2440417c6d498 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Exercises/2-mandelbrot-render/MandelbrotRender_Scene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &672588258 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 672588260} 133 | - component: {fileID: 672588259} 134 | m_Layer: 0 135 | m_Name: Bootstrap 136 | m_TagString: Untagged 137 | m_Icon: {fileID: 0} 138 | m_NavMeshLayer: 0 139 | m_StaticEditorFlags: 0 140 | m_IsActive: 1 141 | --- !u!114 &672588259 142 | MonoBehaviour: 143 | m_ObjectHideFlags: 0 144 | m_CorrespondingSourceObject: {fileID: 0} 145 | m_PrefabInstance: {fileID: 0} 146 | m_PrefabAsset: {fileID: 0} 147 | m_GameObject: {fileID: 672588258} 148 | m_Enabled: 1 149 | m_EditorHideFlags: 0 150 | m_Script: {fileID: 11500000, guid: 91ddda2b7120f624bab2440417c6d498, type: 3} 151 | m_Name: 152 | m_EditorClassIdentifier: 153 | TargetMaterial: {fileID: 2100000, guid: aa4bae83afe885348a5441871b7b7872, type: 2} 154 | --- !u!4 &672588260 155 | Transform: 156 | m_ObjectHideFlags: 0 157 | m_CorrespondingSourceObject: {fileID: 0} 158 | m_PrefabInstance: {fileID: 0} 159 | m_PrefabAsset: {fileID: 0} 160 | m_GameObject: {fileID: 672588258} 161 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 162 | m_LocalPosition: {x: 0, y: 0, z: 0} 163 | m_LocalScale: {x: 1, y: 1, z: 1} 164 | m_Children: [] 165 | m_Father: {fileID: 0} 166 | m_RootOrder: 2 167 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 168 | --- !u!1 &1090215382 169 | GameObject: 170 | m_ObjectHideFlags: 0 171 | m_CorrespondingSourceObject: {fileID: 0} 172 | m_PrefabInstance: {fileID: 0} 173 | m_PrefabAsset: {fileID: 0} 174 | serializedVersion: 6 175 | m_Component: 176 | - component: {fileID: 1090215385} 177 | - component: {fileID: 1090215384} 178 | - component: {fileID: 1090215383} 179 | m_Layer: 0 180 | m_Name: Quad 181 | m_TagString: Untagged 182 | m_Icon: {fileID: 0} 183 | m_NavMeshLayer: 0 184 | m_StaticEditorFlags: 0 185 | m_IsActive: 1 186 | --- !u!23 &1090215383 187 | MeshRenderer: 188 | m_ObjectHideFlags: 0 189 | m_CorrespondingSourceObject: {fileID: 0} 190 | m_PrefabInstance: {fileID: 0} 191 | m_PrefabAsset: {fileID: 0} 192 | m_GameObject: {fileID: 1090215382} 193 | m_Enabled: 1 194 | m_CastShadows: 0 195 | m_ReceiveShadows: 0 196 | m_DynamicOccludee: 0 197 | m_MotionVectors: 2 198 | m_LightProbeUsage: 0 199 | m_ReflectionProbeUsage: 0 200 | m_RayTracingMode: 2 201 | m_RenderingLayerMask: 1 202 | m_RendererPriority: 0 203 | m_Materials: 204 | - {fileID: 2100000, guid: aa4bae83afe885348a5441871b7b7872, type: 2} 205 | m_StaticBatchInfo: 206 | firstSubMesh: 0 207 | subMeshCount: 0 208 | m_StaticBatchRoot: {fileID: 0} 209 | m_ProbeAnchor: {fileID: 0} 210 | m_LightProbeVolumeOverride: {fileID: 0} 211 | m_ScaleInLightmap: 1 212 | m_ReceiveGI: 1 213 | m_PreserveUVs: 0 214 | m_IgnoreNormalsForChartDetection: 0 215 | m_ImportantGI: 0 216 | m_StitchLightmapSeams: 1 217 | m_SelectedEditorRenderState: 3 218 | m_MinimumChartSize: 4 219 | m_AutoUVMaxDistance: 0.5 220 | m_AutoUVMaxAngle: 89 221 | m_LightmapParameters: {fileID: 0} 222 | m_SortingLayerID: 0 223 | m_SortingLayer: 0 224 | m_SortingOrder: 0 225 | --- !u!33 &1090215384 226 | MeshFilter: 227 | m_ObjectHideFlags: 0 228 | m_CorrespondingSourceObject: {fileID: 0} 229 | m_PrefabInstance: {fileID: 0} 230 | m_PrefabAsset: {fileID: 0} 231 | m_GameObject: {fileID: 1090215382} 232 | m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} 233 | --- !u!4 &1090215385 234 | Transform: 235 | m_ObjectHideFlags: 0 236 | m_CorrespondingSourceObject: {fileID: 0} 237 | m_PrefabInstance: {fileID: 0} 238 | m_PrefabAsset: {fileID: 0} 239 | m_GameObject: {fileID: 1090215382} 240 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 241 | m_LocalPosition: {x: 0, y: 0, z: 0} 242 | m_LocalScale: {x: 8, y: 8, z: 1} 243 | m_Children: [] 244 | m_Father: {fileID: 0} 245 | m_RootOrder: 1 246 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 247 | --- !u!1 &2097868333 248 | GameObject: 249 | m_ObjectHideFlags: 0 250 | m_CorrespondingSourceObject: {fileID: 0} 251 | m_PrefabInstance: {fileID: 0} 252 | m_PrefabAsset: {fileID: 0} 253 | serializedVersion: 6 254 | m_Component: 255 | - component: {fileID: 2097868336} 256 | - component: {fileID: 2097868335} 257 | - component: {fileID: 2097868334} 258 | m_Layer: 0 259 | m_Name: Main Camera 260 | m_TagString: MainCamera 261 | m_Icon: {fileID: 0} 262 | m_NavMeshLayer: 0 263 | m_StaticEditorFlags: 0 264 | m_IsActive: 1 265 | --- !u!81 &2097868334 266 | AudioListener: 267 | m_ObjectHideFlags: 0 268 | m_CorrespondingSourceObject: {fileID: 0} 269 | m_PrefabInstance: {fileID: 0} 270 | m_PrefabAsset: {fileID: 0} 271 | m_GameObject: {fileID: 2097868333} 272 | m_Enabled: 1 273 | --- !u!20 &2097868335 274 | Camera: 275 | m_ObjectHideFlags: 0 276 | m_CorrespondingSourceObject: {fileID: 0} 277 | m_PrefabInstance: {fileID: 0} 278 | m_PrefabAsset: {fileID: 0} 279 | m_GameObject: {fileID: 2097868333} 280 | m_Enabled: 1 281 | serializedVersion: 2 282 | m_ClearFlags: 2 283 | m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0} 284 | m_projectionMatrixMode: 1 285 | m_GateFitMode: 2 286 | m_FOVAxisMode: 0 287 | m_SensorSize: {x: 36, y: 24} 288 | m_LensShift: {x: 0, y: 0} 289 | m_FocalLength: 50 290 | m_NormalizedViewPortRect: 291 | serializedVersion: 2 292 | x: 0 293 | y: 0 294 | width: 1 295 | height: 1 296 | near clip plane: 0.3 297 | far clip plane: 1000 298 | field of view: 60 299 | orthographic: 1 300 | orthographic size: 5 301 | m_Depth: -1 302 | m_CullingMask: 303 | serializedVersion: 2 304 | m_Bits: 4294967295 305 | m_RenderingPath: -1 306 | m_TargetTexture: {fileID: 0} 307 | m_TargetDisplay: 0 308 | m_TargetEye: 3 309 | m_HDR: 1 310 | m_AllowMSAA: 1 311 | m_AllowDynamicResolution: 0 312 | m_ForceIntoRT: 0 313 | m_OcclusionCulling: 1 314 | m_StereoConvergence: 10 315 | m_StereoSeparation: 0.022 316 | --- !u!4 &2097868336 317 | Transform: 318 | m_ObjectHideFlags: 0 319 | m_CorrespondingSourceObject: {fileID: 0} 320 | m_PrefabInstance: {fileID: 0} 321 | m_PrefabAsset: {fileID: 0} 322 | m_GameObject: {fileID: 2097868333} 323 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 324 | m_LocalPosition: {x: 0, y: 0, z: -10} 325 | m_LocalScale: {x: 1, y: 1, z: 1} 326 | m_Children: [] 327 | m_Father: {fileID: 0} 328 | m_RootOrder: 0 329 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 330 | -------------------------------------------------------------------------------- /Assets/Exercises/2-mandelbrot-render/MandelbrotRender_Scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b325aba8246db84fa36bbaaf8018dea 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Exercises/3-culling.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 06ca0e17c7d801a408bdaf86f5ec05f9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/3-culling/CubeMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: CubeMaterial 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 1 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.754717, g: 0, b: 0, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Assets/Exercises/3-culling/CubeMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 64702e7939183ed49a18fb41ea90fe58 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/3-culling/Culling.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 81bd2288872b0ef4aba7a8e8b40947b4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Exercises/3-culling/Culling_Scene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &78090406 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 78090407} 133 | - component: {fileID: 78090408} 134 | m_Layer: 0 135 | m_Name: Bootstrap 136 | m_TagString: Untagged 137 | m_Icon: {fileID: 0} 138 | m_NavMeshLayer: 0 139 | m_StaticEditorFlags: 0 140 | m_IsActive: 1 141 | --- !u!4 &78090407 142 | Transform: 143 | m_ObjectHideFlags: 0 144 | m_CorrespondingSourceObject: {fileID: 0} 145 | m_PrefabInstance: {fileID: 0} 146 | m_PrefabAsset: {fileID: 0} 147 | m_GameObject: {fileID: 78090406} 148 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 149 | m_LocalPosition: {x: 0, y: 0, z: 0} 150 | m_LocalScale: {x: 1, y: 1, z: 1} 151 | m_Children: [] 152 | m_Father: {fileID: 0} 153 | m_RootOrder: 1 154 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 155 | --- !u!114 &78090408 156 | MonoBehaviour: 157 | m_ObjectHideFlags: 0 158 | m_CorrespondingSourceObject: {fileID: 0} 159 | m_PrefabInstance: {fileID: 0} 160 | m_PrefabAsset: {fileID: 0} 161 | m_GameObject: {fileID: 78090406} 162 | m_Enabled: 1 163 | m_EditorHideFlags: 0 164 | m_Script: {fileID: 11500000, guid: 81bd2288872b0ef4aba7a8e8b40947b4, type: 3} 165 | m_Name: 166 | m_EditorClassIdentifier: 167 | SphereMesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} 168 | CubeMesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 169 | SphereMaterial: {fileID: 2100000, guid: 8893fff6172c7c947b50beac399a7942, type: 2} 170 | CubeMaterial: {fileID: 2100000, guid: 64702e7939183ed49a18fb41ea90fe58, type: 2} 171 | --- !u!1 &97166270 172 | GameObject: 173 | m_ObjectHideFlags: 0 174 | m_CorrespondingSourceObject: {fileID: 0} 175 | m_PrefabInstance: {fileID: 0} 176 | m_PrefabAsset: {fileID: 0} 177 | serializedVersion: 6 178 | m_Component: 179 | - component: {fileID: 97166273} 180 | - component: {fileID: 97166272} 181 | - component: {fileID: 97166271} 182 | m_Layer: 0 183 | m_Name: Main Camera 184 | m_TagString: MainCamera 185 | m_Icon: {fileID: 0} 186 | m_NavMeshLayer: 0 187 | m_StaticEditorFlags: 0 188 | m_IsActive: 1 189 | --- !u!81 &97166271 190 | AudioListener: 191 | m_ObjectHideFlags: 0 192 | m_CorrespondingSourceObject: {fileID: 0} 193 | m_PrefabInstance: {fileID: 0} 194 | m_PrefabAsset: {fileID: 0} 195 | m_GameObject: {fileID: 97166270} 196 | m_Enabled: 1 197 | --- !u!20 &97166272 198 | Camera: 199 | m_ObjectHideFlags: 0 200 | m_CorrespondingSourceObject: {fileID: 0} 201 | m_PrefabInstance: {fileID: 0} 202 | m_PrefabAsset: {fileID: 0} 203 | m_GameObject: {fileID: 97166270} 204 | m_Enabled: 1 205 | serializedVersion: 2 206 | m_ClearFlags: 1 207 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 208 | m_projectionMatrixMode: 1 209 | m_GateFitMode: 2 210 | m_FOVAxisMode: 0 211 | m_SensorSize: {x: 36, y: 24} 212 | m_LensShift: {x: 0, y: 0} 213 | m_FocalLength: 50 214 | m_NormalizedViewPortRect: 215 | serializedVersion: 2 216 | x: 0 217 | y: 0 218 | width: 1 219 | height: 1 220 | near clip plane: 0.3 221 | far clip plane: 1000 222 | field of view: 60 223 | orthographic: 0 224 | orthographic size: 5 225 | m_Depth: -1 226 | m_CullingMask: 227 | serializedVersion: 2 228 | m_Bits: 4294967295 229 | m_RenderingPath: -1 230 | m_TargetTexture: {fileID: 0} 231 | m_TargetDisplay: 0 232 | m_TargetEye: 3 233 | m_HDR: 1 234 | m_AllowMSAA: 1 235 | m_AllowDynamicResolution: 0 236 | m_ForceIntoRT: 0 237 | m_OcclusionCulling: 1 238 | m_StereoConvergence: 10 239 | m_StereoSeparation: 0.022 240 | --- !u!4 &97166273 241 | Transform: 242 | m_ObjectHideFlags: 0 243 | m_CorrespondingSourceObject: {fileID: 0} 244 | m_PrefabInstance: {fileID: 0} 245 | m_PrefabAsset: {fileID: 0} 246 | m_GameObject: {fileID: 97166270} 247 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 248 | m_LocalPosition: {x: 0, y: 1, z: -10} 249 | m_LocalScale: {x: 1, y: 1, z: 1} 250 | m_Children: [] 251 | m_Father: {fileID: 0} 252 | m_RootOrder: 0 253 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 254 | --- !u!1 &1577988524 255 | GameObject: 256 | m_ObjectHideFlags: 0 257 | m_CorrespondingSourceObject: {fileID: 0} 258 | m_PrefabInstance: {fileID: 0} 259 | m_PrefabAsset: {fileID: 0} 260 | serializedVersion: 6 261 | m_Component: 262 | - component: {fileID: 1577988526} 263 | - component: {fileID: 1577988525} 264 | m_Layer: 0 265 | m_Name: Directional Light 266 | m_TagString: Untagged 267 | m_Icon: {fileID: 0} 268 | m_NavMeshLayer: 0 269 | m_StaticEditorFlags: 0 270 | m_IsActive: 1 271 | --- !u!108 &1577988525 272 | Light: 273 | m_ObjectHideFlags: 0 274 | m_CorrespondingSourceObject: {fileID: 0} 275 | m_PrefabInstance: {fileID: 0} 276 | m_PrefabAsset: {fileID: 0} 277 | m_GameObject: {fileID: 1577988524} 278 | m_Enabled: 1 279 | serializedVersion: 10 280 | m_Type: 1 281 | m_Shape: 0 282 | m_Color: {r: 1, g: 1, b: 1, a: 1} 283 | m_Intensity: 1 284 | m_Range: 10 285 | m_SpotAngle: 30 286 | m_InnerSpotAngle: 21.80208 287 | m_CookieSize: 10 288 | m_Shadows: 289 | m_Type: 0 290 | m_Resolution: -1 291 | m_CustomResolution: -1 292 | m_Strength: 1 293 | m_Bias: 0.05 294 | m_NormalBias: 0.4 295 | m_NearPlane: 0.2 296 | m_CullingMatrixOverride: 297 | e00: 1 298 | e01: 0 299 | e02: 0 300 | e03: 0 301 | e10: 0 302 | e11: 1 303 | e12: 0 304 | e13: 0 305 | e20: 0 306 | e21: 0 307 | e22: 1 308 | e23: 0 309 | e30: 0 310 | e31: 0 311 | e32: 0 312 | e33: 1 313 | m_UseCullingMatrixOverride: 0 314 | m_Cookie: {fileID: 0} 315 | m_DrawHalo: 0 316 | m_Flare: {fileID: 0} 317 | m_RenderMode: 0 318 | m_CullingMask: 319 | serializedVersion: 2 320 | m_Bits: 4294967295 321 | m_RenderingLayerMask: 1 322 | m_Lightmapping: 4 323 | m_LightShadowCasterMode: 0 324 | m_AreaSize: {x: 1, y: 1} 325 | m_BounceIntensity: 1 326 | m_ColorTemperature: 6570 327 | m_UseColorTemperature: 0 328 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 329 | m_UseBoundingSphereOverride: 0 330 | m_ShadowRadius: 0 331 | m_ShadowAngle: 0 332 | --- !u!4 &1577988526 333 | Transform: 334 | m_ObjectHideFlags: 0 335 | m_CorrespondingSourceObject: {fileID: 0} 336 | m_PrefabInstance: {fileID: 0} 337 | m_PrefabAsset: {fileID: 0} 338 | m_GameObject: {fileID: 1577988524} 339 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 340 | m_LocalPosition: {x: 0, y: 0, z: 0} 341 | m_LocalScale: {x: 1, y: 1, z: 1} 342 | m_Children: [] 343 | m_Father: {fileID: 0} 344 | m_RootOrder: 2 345 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 346 | -------------------------------------------------------------------------------- /Assets/Exercises/3-culling/Culling_Scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5f6ff38efbd3ce845bba4dd7dbb956d1 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Exercises/3-culling/SphereMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: SphereMaterial 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 1 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.2062567, g: 0.24709554, b: 0.9716981, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Assets/Exercises/3-culling/SphereMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8893fff6172c7c947b50beac399a7942 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/4-triangle-picking.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d07fd01ab05a1394380505c46ecb0eea 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/4-triangle-picking/Grenadier Model.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sschoener/burst-simd-exercises/1b2c49ce72de8d904c5c1d20b971a09787780186/Assets/Exercises/4-triangle-picking/Grenadier Model.fbx -------------------------------------------------------------------------------- /Assets/Exercises/4-triangle-picking/Grenadier Model.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 709feb92c07b2504a87ce2c39cbf67c7 3 | ModelImporter: 4 | serializedVersion: 19300 5 | internalIDToNameTable: [] 6 | externalObjects: {} 7 | materials: 8 | materialImportMode: 1 9 | materialName: 0 10 | materialSearch: 1 11 | materialLocation: 1 12 | animations: 13 | legacyGenerateAnimations: 4 14 | bakeSimulation: 0 15 | resampleCurves: 1 16 | optimizeGameObjects: 0 17 | motionNodeName: 18 | rigImportErrors: 19 | rigImportWarnings: 20 | animationImportErrors: 21 | animationImportWarnings: 22 | animationRetargetingWarnings: 23 | animationDoRetargetingWarnings: 0 24 | importAnimatedCustomProperties: 0 25 | importConstraints: 0 26 | animationCompression: 1 27 | animationRotationError: 0.5 28 | animationPositionError: 0.5 29 | animationScaleError: 0.5 30 | animationWrapMode: 0 31 | extraExposedTransformPaths: [] 32 | extraUserProperties: [] 33 | clipAnimations: [] 34 | isReadable: 1 35 | meshes: 36 | lODScreenPercentages: [] 37 | globalScale: 1 38 | meshCompression: 0 39 | addColliders: 0 40 | useSRGBMaterialColor: 1 41 | sortHierarchyByName: 1 42 | importVisibility: 1 43 | importBlendShapes: 1 44 | importCameras: 1 45 | importLights: 1 46 | swapUVChannels: 0 47 | generateSecondaryUV: 0 48 | useFileUnits: 1 49 | keepQuads: 0 50 | weldVertices: 1 51 | preserveHierarchy: 0 52 | skinWeightsMode: 0 53 | maxBonesPerVertex: 4 54 | minBoneWeight: 0.001 55 | meshOptimizationFlags: -1 56 | indexFormat: 0 57 | secondaryUVAngleDistortion: 8 58 | secondaryUVAreaDistortion: 15.000001 59 | secondaryUVHardAngle: 88 60 | secondaryUVPackMargin: 4 61 | useFileScale: 1 62 | tangentSpace: 63 | normalSmoothAngle: 60 64 | normalImportMode: 0 65 | tangentImportMode: 3 66 | normalCalculationMode: 4 67 | legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 68 | blendShapeNormalImportMode: 1 69 | normalSmoothingSource: 0 70 | referencedClips: [] 71 | importAnimation: 1 72 | humanDescription: 73 | serializedVersion: 3 74 | human: [] 75 | skeleton: [] 76 | armTwist: 0.5 77 | foreArmTwist: 0.5 78 | upperLegTwist: 0.5 79 | legTwist: 0.5 80 | armStretch: 0.05 81 | legStretch: 0.05 82 | feetSpacing: 0 83 | globalScale: 1 84 | rootMotionBoneName: 85 | hasTranslationDoF: 0 86 | hasExtraRoot: 0 87 | skeletonHasParents: 1 88 | lastHumanDescriptionAvatarSource: {instanceID: 0} 89 | autoGenerateAvatarMappingIfUnspecified: 1 90 | animationType: 2 91 | humanoidOversampling: 1 92 | avatarSetup: 0 93 | additionalBone: 0 94 | userData: 95 | assetBundleName: 96 | assetBundleVariant: 97 | -------------------------------------------------------------------------------- /Assets/Exercises/4-triangle-picking/IntersectionMarker.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: IntersectionMarker 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 1, g: 0, b: 0, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Assets/Exercises/4-triangle-picking/IntersectionMarker.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9a8768d7c0dc6644795648111e37565c 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/4-triangle-picking/TrianglePicking.cs: -------------------------------------------------------------------------------- 1 | // Implement ray-triangle intersection using SIMD. 2 | // Pay special attention to how you load vertices using the indices (maybe try AVX2 gather instructions?). 3 | 4 | using System; 5 | using Unity.Burst; 6 | using Unity.Collections; 7 | using Unity.Collections.LowLevel.Unsafe; 8 | using Unity.Mathematics; 9 | using Unity.Profiling; 10 | using UnityEngine; 11 | using UnityEngine.Assertions; 12 | 13 | [BurstCompile] 14 | public unsafe class TrianglePicking : MonoBehaviour 15 | { 16 | public Mesh Mesh; 17 | public Transform MeshTransform; 18 | public Transform IntersectionMarker; 19 | 20 | Camera m_Camera; 21 | 22 | NativeArray m_Vertices; 23 | NativeArray m_Indices; 24 | 25 | delegate float FindIntersection(float3* vertices, int* indices, int numTriangles, RayData* ray); 26 | delegate float FindIntersectionSimd(float3* vertices, int* indices, int numTriangles, RayData* ray); 27 | 28 | delegate void TransformVertices(float3* vertices, int numVertices, float4x4* matrix); 29 | 30 | FindIntersection m_FindIntersection; 31 | FindIntersectionSimd m_FindIntersectionSimd; 32 | TransformVertices m_TransformVertices; 33 | 34 | ProfilerMarker m_FindIntersectionMarker = new ProfilerMarker("FindIntersection"); 35 | ProfilerMarker m_FindIntersectionSimdMarker = new ProfilerMarker("FindIntersectionSimd"); 36 | 37 | void Start() 38 | { 39 | m_Camera = Camera.main; 40 | Debug.Assert(Mesh.GetTopology(1) == MeshTopology.Triangles); 41 | 42 | var vertices = Mesh.vertices; 43 | m_Vertices = new NativeArray(vertices.Length, Allocator.Persistent); 44 | m_Vertices.Reinterpret().CopyFrom(vertices); 45 | m_Indices = new NativeArray(Mesh.triangles, Allocator.Persistent); 46 | 47 | m_FindIntersection = BurstCompiler.CompileFunctionPointer(FindTriangleIntersection).Invoke; 48 | m_FindIntersectionSimd = BurstCompiler.CompileFunctionPointer(FindTriangleIntersectionSimd).Invoke; 49 | m_TransformVertices = BurstCompiler.CompileFunctionPointer(UpdateVertices).Invoke; 50 | 51 | float4x4 localToWorld = MeshTransform.localToWorldMatrix; 52 | m_TransformVertices((float3*)m_Vertices.GetUnsafePtr(), m_Vertices.Length, &localToWorld); 53 | } 54 | 55 | void OnDestroy() 56 | { 57 | m_Vertices.Dispose(); 58 | m_Indices.Dispose(); 59 | } 60 | 61 | struct RayData 62 | { 63 | public float3 Origin; 64 | public float3 Direction; 65 | } 66 | 67 | void Update() 68 | { 69 | var unityRay = m_Camera.ScreenPointToRay(Input.mousePosition); 70 | var ray = new RayData 71 | { 72 | Direction = unityRay.direction, 73 | Origin = unityRay.origin 74 | }; 75 | float3* vertices = (float3*)m_Vertices.GetUnsafeReadOnlyPtr(); 76 | int* indices = (int*)m_Indices.GetUnsafeReadOnlyPtr(); 77 | 78 | m_FindIntersectionMarker.Begin(); 79 | var rayIntersectionT = m_FindIntersection(vertices, indices, m_Indices.Length / 3, &ray); 80 | m_FindIntersectionMarker.End(); 81 | 82 | m_FindIntersectionSimdMarker.Begin(); 83 | var rayIntersectionTSimd = m_FindIntersectionSimd(vertices, indices, m_Indices.Length / 3, &ray); 84 | m_FindIntersectionSimdMarker.End(); 85 | 86 | float3 intersection = ray.Origin + rayIntersectionT * ray.Direction; 87 | bool hasIntersection = !float.IsNaN(rayIntersectionT) && !float.IsInfinity(rayIntersectionT); 88 | bool hasIntersectionSimd = !float.IsNaN(rayIntersectionTSimd) && !float.IsInfinity(rayIntersectionTSimd); 89 | 90 | if (hasIntersection) 91 | IntersectionMarker.transform.position = intersection; 92 | IntersectionMarker.gameObject.SetActive(hasIntersection); 93 | 94 | Assert.AreEqual(hasIntersection, hasIntersectionSimd, "SIMD code doesn't agree with reference as to whether there is an intersection."); 95 | if (hasIntersection && hasIntersectionSimd) 96 | Assert.AreApproximatelyEqual(rayIntersectionT, rayIntersectionTSimd, $"SIMD code returned intersection parameter {rayIntersectionTSimd} which is too far from actual intersection {rayIntersectionT}."); 97 | } 98 | 99 | [BurstCompile(CompileSynchronously = true)] // note the lack of Fast-math; doesn't play nicely with NaNs 100 | static float FindTriangleIntersection(float3* vertices, int* indices, int numTriangles, RayData* rayPtr) 101 | { 102 | RayData ray = *rayPtr; 103 | float minT = float.PositiveInfinity; 104 | for (int tri = 0; tri < numTriangles; tri++) 105 | { 106 | int idx0 = indices[3 * tri + 0]; 107 | int idx1 = indices[3 * tri + 1]; 108 | int idx2 = indices[3 * tri + 2]; 109 | 110 | float t = IntersectRayTriangle(ray, vertices[idx0], vertices[idx1], vertices[idx2]); 111 | minT = math.min(t, minT); 112 | } 113 | return minT; 114 | } 115 | 116 | /// 117 | /// Ray-versus-triangle intersection test suitable for ray-tracing etc. 118 | /// Port of Möller–Trumbore algorithm c++ version from: 119 | /// https://en.wikipedia.org/wiki/Möller–Trumbore_intersection_algorithm 120 | /// 121 | /// Adapted from https://answers.unity.com/questions/861719/a-fast-triangle-triangle-intersection-algorithm-fo.html 122 | /// 123 | /// The distance along the ray to the intersection if one exists, NaN if one does not. 124 | /// Le ray. 125 | /// A vertex of the triangle. 126 | /// A vertex of the triangle. 127 | /// A vertex of the triangle. 128 | static float IntersectRayTriangle(RayData ray, float3 v0, float3 v1, float3 v2) 129 | { 130 | const float epsilon = 0.000001f; 131 | float3 e1 = v1 - v0; 132 | float3 e2 = v2 - v0; 133 | 134 | float3 h = math.cross(ray.Direction, e2); 135 | float a = math.dot(e1, h); 136 | if (a > -epsilon && a < epsilon) 137 | return float.NaN; 138 | 139 | float f = 1.0f / a; 140 | float3 s = ray.Origin - v0; 141 | float u = f * math.dot(s, h); 142 | if (u < 0.0f || u > 1.0f) 143 | return float.NaN; 144 | 145 | float3 q = math.cross(s, e1); 146 | float v = f * math.dot(ray.Direction, q); 147 | if (v < 0.0f || u + v > 1.0f) 148 | return float.NaN; 149 | 150 | float t = f * math.dot(e2, q); 151 | return t > epsilon ? t : float.NaN; 152 | } 153 | 154 | /// 155 | /// Compute the minimum parameter along the input ray where the given ray intersects any of the given triangles. It 156 | /// is assumed that you do not perform backside culling. 157 | /// The return value should be greater than 0 and finite. 158 | /// 159 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 160 | static float FindTriangleIntersectionSimd(float3* vertices, int* indices, int numTriangles, RayData* ray) 161 | { 162 | // YOUR SIMD CODE HERE 163 | return float.PositiveInfinity; 164 | } 165 | 166 | [BurstCompile(CompileSynchronously = true)] 167 | static void UpdateVertices(float3* vertices, int numVertices, float4x4* matrixPtr) 168 | { 169 | float4x4 matrix = *matrixPtr; 170 | for (int v = 0; v < numVertices; v++) 171 | { 172 | vertices[v] = math.mul(matrix, new float4(vertices[v], 1)).xyz; 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /Assets/Exercises/4-triangle-picking/TrianglePicking.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7877c0e614669a04a8398aeb898a9253 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Exercises/4-triangle-picking/TrianglePicking_Scene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &320581085 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 320581088} 133 | - component: {fileID: 320581087} 134 | - component: {fileID: 320581086} 135 | m_Layer: 0 136 | m_Name: Main Camera 137 | m_TagString: MainCamera 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 0 141 | m_IsActive: 1 142 | --- !u!81 &320581086 143 | AudioListener: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 320581085} 149 | m_Enabled: 1 150 | --- !u!20 &320581087 151 | Camera: 152 | m_ObjectHideFlags: 0 153 | m_CorrespondingSourceObject: {fileID: 0} 154 | m_PrefabInstance: {fileID: 0} 155 | m_PrefabAsset: {fileID: 0} 156 | m_GameObject: {fileID: 320581085} 157 | m_Enabled: 1 158 | serializedVersion: 2 159 | m_ClearFlags: 1 160 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 161 | m_projectionMatrixMode: 1 162 | m_GateFitMode: 2 163 | m_FOVAxisMode: 0 164 | m_SensorSize: {x: 36, y: 24} 165 | m_LensShift: {x: 0, y: 0} 166 | m_FocalLength: 50 167 | m_NormalizedViewPortRect: 168 | serializedVersion: 2 169 | x: 0 170 | y: 0 171 | width: 1 172 | height: 1 173 | near clip plane: 0.3 174 | far clip plane: 1000 175 | field of view: 60 176 | orthographic: 0 177 | orthographic size: 5 178 | m_Depth: -1 179 | m_CullingMask: 180 | serializedVersion: 2 181 | m_Bits: 4294967295 182 | m_RenderingPath: -1 183 | m_TargetTexture: {fileID: 0} 184 | m_TargetDisplay: 0 185 | m_TargetEye: 3 186 | m_HDR: 1 187 | m_AllowMSAA: 1 188 | m_AllowDynamicResolution: 0 189 | m_ForceIntoRT: 0 190 | m_OcclusionCulling: 1 191 | m_StereoConvergence: 10 192 | m_StereoSeparation: 0.022 193 | --- !u!4 &320581088 194 | Transform: 195 | m_ObjectHideFlags: 0 196 | m_CorrespondingSourceObject: {fileID: 0} 197 | m_PrefabInstance: {fileID: 0} 198 | m_PrefabAsset: {fileID: 0} 199 | m_GameObject: {fileID: 320581085} 200 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 201 | m_LocalPosition: {x: 0, y: 0, z: -5} 202 | m_LocalScale: {x: 1, y: 1, z: 1} 203 | m_Children: [] 204 | m_Father: {fileID: 0} 205 | m_RootOrder: 0 206 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 207 | --- !u!1 &392214140 208 | GameObject: 209 | m_ObjectHideFlags: 0 210 | m_CorrespondingSourceObject: {fileID: 0} 211 | m_PrefabInstance: {fileID: 0} 212 | m_PrefabAsset: {fileID: 0} 213 | serializedVersion: 6 214 | m_Component: 215 | - component: {fileID: 392214143} 216 | - component: {fileID: 392214142} 217 | - component: {fileID: 392214141} 218 | m_Layer: 0 219 | m_Name: Model 220 | m_TagString: Untagged 221 | m_Icon: {fileID: 0} 222 | m_NavMeshLayer: 0 223 | m_StaticEditorFlags: 0 224 | m_IsActive: 1 225 | --- !u!23 &392214141 226 | MeshRenderer: 227 | m_ObjectHideFlags: 0 228 | m_CorrespondingSourceObject: {fileID: 0} 229 | m_PrefabInstance: {fileID: 0} 230 | m_PrefabAsset: {fileID: 0} 231 | m_GameObject: {fileID: 392214140} 232 | m_Enabled: 1 233 | m_CastShadows: 1 234 | m_ReceiveShadows: 1 235 | m_DynamicOccludee: 1 236 | m_MotionVectors: 1 237 | m_LightProbeUsage: 1 238 | m_ReflectionProbeUsage: 1 239 | m_RayTracingMode: 2 240 | m_RenderingLayerMask: 1 241 | m_RendererPriority: 0 242 | m_Materials: 243 | - {fileID: -6700819500841087837, guid: 709feb92c07b2504a87ce2c39cbf67c7, type: 3} 244 | - {fileID: -6700819500841087837, guid: 709feb92c07b2504a87ce2c39cbf67c7, type: 3} 245 | - {fileID: -6700819500841087837, guid: 709feb92c07b2504a87ce2c39cbf67c7, type: 3} 246 | m_StaticBatchInfo: 247 | firstSubMesh: 0 248 | subMeshCount: 0 249 | m_StaticBatchRoot: {fileID: 0} 250 | m_ProbeAnchor: {fileID: 0} 251 | m_LightProbeVolumeOverride: {fileID: 0} 252 | m_ScaleInLightmap: 1 253 | m_ReceiveGI: 1 254 | m_PreserveUVs: 0 255 | m_IgnoreNormalsForChartDetection: 0 256 | m_ImportantGI: 0 257 | m_StitchLightmapSeams: 1 258 | m_SelectedEditorRenderState: 3 259 | m_MinimumChartSize: 4 260 | m_AutoUVMaxDistance: 0.5 261 | m_AutoUVMaxAngle: 89 262 | m_LightmapParameters: {fileID: 0} 263 | m_SortingLayerID: 0 264 | m_SortingLayer: 0 265 | m_SortingOrder: 0 266 | --- !u!33 &392214142 267 | MeshFilter: 268 | m_ObjectHideFlags: 0 269 | m_CorrespondingSourceObject: {fileID: 0} 270 | m_PrefabInstance: {fileID: 0} 271 | m_PrefabAsset: {fileID: 0} 272 | m_GameObject: {fileID: 392214140} 273 | m_Mesh: {fileID: 512041939449692313, guid: 709feb92c07b2504a87ce2c39cbf67c7, type: 3} 274 | --- !u!4 &392214143 275 | Transform: 276 | m_ObjectHideFlags: 0 277 | m_CorrespondingSourceObject: {fileID: 0} 278 | m_PrefabInstance: {fileID: 0} 279 | m_PrefabAsset: {fileID: 0} 280 | m_GameObject: {fileID: 392214140} 281 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 282 | m_LocalPosition: {x: 0, y: -2, z: 0} 283 | m_LocalScale: {x: 1, y: 1, z: 1} 284 | m_Children: [] 285 | m_Father: {fileID: 0} 286 | m_RootOrder: 4 287 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 288 | --- !u!1 &1065286231 289 | GameObject: 290 | m_ObjectHideFlags: 0 291 | m_CorrespondingSourceObject: {fileID: 0} 292 | m_PrefabInstance: {fileID: 0} 293 | m_PrefabAsset: {fileID: 0} 294 | serializedVersion: 6 295 | m_Component: 296 | - component: {fileID: 1065286233} 297 | - component: {fileID: 1065286232} 298 | m_Layer: 0 299 | m_Name: Bootstrap 300 | m_TagString: Untagged 301 | m_Icon: {fileID: 0} 302 | m_NavMeshLayer: 0 303 | m_StaticEditorFlags: 0 304 | m_IsActive: 1 305 | --- !u!114 &1065286232 306 | MonoBehaviour: 307 | m_ObjectHideFlags: 0 308 | m_CorrespondingSourceObject: {fileID: 0} 309 | m_PrefabInstance: {fileID: 0} 310 | m_PrefabAsset: {fileID: 0} 311 | m_GameObject: {fileID: 1065286231} 312 | m_Enabled: 1 313 | m_EditorHideFlags: 0 314 | m_Script: {fileID: 11500000, guid: 7877c0e614669a04a8398aeb898a9253, type: 3} 315 | m_Name: 316 | m_EditorClassIdentifier: 317 | Mesh: {fileID: 512041939449692313, guid: 709feb92c07b2504a87ce2c39cbf67c7, type: 3} 318 | MeshTransform: {fileID: 392214143} 319 | IntersectionMarker: {fileID: 1824209889} 320 | --- !u!4 &1065286233 321 | Transform: 322 | m_ObjectHideFlags: 0 323 | m_CorrespondingSourceObject: {fileID: 0} 324 | m_PrefabInstance: {fileID: 0} 325 | m_PrefabAsset: {fileID: 0} 326 | m_GameObject: {fileID: 1065286231} 327 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 328 | m_LocalPosition: {x: 0, y: 0, z: 0} 329 | m_LocalScale: {x: 1, y: 1, z: 1} 330 | m_Children: [] 331 | m_Father: {fileID: 0} 332 | m_RootOrder: 2 333 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 334 | --- !u!1 &1824209886 335 | GameObject: 336 | m_ObjectHideFlags: 0 337 | m_CorrespondingSourceObject: {fileID: 0} 338 | m_PrefabInstance: {fileID: 0} 339 | m_PrefabAsset: {fileID: 0} 340 | serializedVersion: 6 341 | m_Component: 342 | - component: {fileID: 1824209889} 343 | - component: {fileID: 1824209888} 344 | - component: {fileID: 1824209887} 345 | m_Layer: 0 346 | m_Name: IntersectionMarker 347 | m_TagString: Untagged 348 | m_Icon: {fileID: 0} 349 | m_NavMeshLayer: 0 350 | m_StaticEditorFlags: 0 351 | m_IsActive: 1 352 | --- !u!23 &1824209887 353 | MeshRenderer: 354 | m_ObjectHideFlags: 0 355 | m_CorrespondingSourceObject: {fileID: 0} 356 | m_PrefabInstance: {fileID: 0} 357 | m_PrefabAsset: {fileID: 0} 358 | m_GameObject: {fileID: 1824209886} 359 | m_Enabled: 1 360 | m_CastShadows: 1 361 | m_ReceiveShadows: 1 362 | m_DynamicOccludee: 1 363 | m_MotionVectors: 1 364 | m_LightProbeUsage: 1 365 | m_ReflectionProbeUsage: 1 366 | m_RayTracingMode: 2 367 | m_RenderingLayerMask: 1 368 | m_RendererPriority: 0 369 | m_Materials: 370 | - {fileID: 2100000, guid: 9a8768d7c0dc6644795648111e37565c, type: 2} 371 | m_StaticBatchInfo: 372 | firstSubMesh: 0 373 | subMeshCount: 0 374 | m_StaticBatchRoot: {fileID: 0} 375 | m_ProbeAnchor: {fileID: 0} 376 | m_LightProbeVolumeOverride: {fileID: 0} 377 | m_ScaleInLightmap: 1 378 | m_ReceiveGI: 1 379 | m_PreserveUVs: 0 380 | m_IgnoreNormalsForChartDetection: 0 381 | m_ImportantGI: 0 382 | m_StitchLightmapSeams: 1 383 | m_SelectedEditorRenderState: 3 384 | m_MinimumChartSize: 4 385 | m_AutoUVMaxDistance: 0.5 386 | m_AutoUVMaxAngle: 89 387 | m_LightmapParameters: {fileID: 0} 388 | m_SortingLayerID: 0 389 | m_SortingLayer: 0 390 | m_SortingOrder: 0 391 | --- !u!33 &1824209888 392 | MeshFilter: 393 | m_ObjectHideFlags: 0 394 | m_CorrespondingSourceObject: {fileID: 0} 395 | m_PrefabInstance: {fileID: 0} 396 | m_PrefabAsset: {fileID: 0} 397 | m_GameObject: {fileID: 1824209886} 398 | m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} 399 | --- !u!4 &1824209889 400 | Transform: 401 | m_ObjectHideFlags: 0 402 | m_CorrespondingSourceObject: {fileID: 0} 403 | m_PrefabInstance: {fileID: 0} 404 | m_PrefabAsset: {fileID: 0} 405 | m_GameObject: {fileID: 1824209886} 406 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 407 | m_LocalPosition: {x: 0, y: 0, z: -1} 408 | m_LocalScale: {x: 0.1, y: 0.1, z: 0.1} 409 | m_Children: [] 410 | m_Father: {fileID: 0} 411 | m_RootOrder: 3 412 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 413 | --- !u!1 &1833938386 414 | GameObject: 415 | m_ObjectHideFlags: 0 416 | m_CorrespondingSourceObject: {fileID: 0} 417 | m_PrefabInstance: {fileID: 0} 418 | m_PrefabAsset: {fileID: 0} 419 | serializedVersion: 6 420 | m_Component: 421 | - component: {fileID: 1833938388} 422 | - component: {fileID: 1833938387} 423 | m_Layer: 0 424 | m_Name: Directional Light 425 | m_TagString: Untagged 426 | m_Icon: {fileID: 0} 427 | m_NavMeshLayer: 0 428 | m_StaticEditorFlags: 0 429 | m_IsActive: 1 430 | --- !u!108 &1833938387 431 | Light: 432 | m_ObjectHideFlags: 0 433 | m_CorrespondingSourceObject: {fileID: 0} 434 | m_PrefabInstance: {fileID: 0} 435 | m_PrefabAsset: {fileID: 0} 436 | m_GameObject: {fileID: 1833938386} 437 | m_Enabled: 1 438 | serializedVersion: 10 439 | m_Type: 1 440 | m_Shape: 0 441 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 442 | m_Intensity: 1 443 | m_Range: 10 444 | m_SpotAngle: 30 445 | m_InnerSpotAngle: 21.80208 446 | m_CookieSize: 10 447 | m_Shadows: 448 | m_Type: 0 449 | m_Resolution: -1 450 | m_CustomResolution: -1 451 | m_Strength: 0 452 | m_Bias: 0.05 453 | m_NormalBias: 0.4 454 | m_NearPlane: 0.2 455 | m_CullingMatrixOverride: 456 | e00: 1 457 | e01: 0 458 | e02: 0 459 | e03: 0 460 | e10: 0 461 | e11: 1 462 | e12: 0 463 | e13: 0 464 | e20: 0 465 | e21: 0 466 | e22: 1 467 | e23: 0 468 | e30: 0 469 | e31: 0 470 | e32: 0 471 | e33: 1 472 | m_UseCullingMatrixOverride: 0 473 | m_Cookie: {fileID: 0} 474 | m_DrawHalo: 0 475 | m_Flare: {fileID: 0} 476 | m_RenderMode: 0 477 | m_CullingMask: 478 | serializedVersion: 2 479 | m_Bits: 4294967295 480 | m_RenderingLayerMask: 1 481 | m_Lightmapping: 4 482 | m_LightShadowCasterMode: 0 483 | m_AreaSize: {x: 1, y: 1} 484 | m_BounceIntensity: 1 485 | m_ColorTemperature: 6570 486 | m_UseColorTemperature: 0 487 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 488 | m_UseBoundingSphereOverride: 0 489 | m_ShadowRadius: 0 490 | m_ShadowAngle: 0 491 | --- !u!4 &1833938388 492 | Transform: 493 | m_ObjectHideFlags: 0 494 | m_CorrespondingSourceObject: {fileID: 0} 495 | m_PrefabInstance: {fileID: 0} 496 | m_PrefabAsset: {fileID: 0} 497 | m_GameObject: {fileID: 1833938386} 498 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 499 | m_LocalPosition: {x: 0, y: 3, z: 0} 500 | m_LocalScale: {x: 1, y: 1, z: 1} 501 | m_Children: [] 502 | m_Father: {fileID: 0} 503 | m_RootOrder: 1 504 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 505 | -------------------------------------------------------------------------------- /Assets/Exercises/4-triangle-picking/TrianglePicking_Scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 25501b91962504e4a8102db8db2e4535 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Exercises/5-raytracer.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 856091b706f3b55459e0eea7f43d53b6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/5-raytracer/Raytracer.cs: -------------------------------------------------------------------------------- 1 | // This is a pathtracer inspired by https://www.kevinbeason.com/smallpt/. 2 | // Porting this to SIMD is a fun exercise, but it is not straight-forward. 3 | // A few notes: 4 | // * everything is represented as spheres (which produces artifacts that we will ignore) 5 | // * each pixel is sampled multiple times for some anti-aliasing 6 | // * we accumulate samples over many frames so you can immediately see some output 7 | // Most of the code should be straight forward, except for the parts about sampling and reflection/refraction. It's 8 | // fine to treat them as black boxes. 9 | // If you want to SIMD this code, I'd suggest trying to compute multiple rays at once. For simplicity, you might want 10 | // to get rid of all non-diffuse materials. This will already be interesting :) 11 | // 12 | // Also, note that this code was originally using double precision floating pointer numbers since representing the 13 | // walls of the Cornell Box with spheres only works with huge spheres. Using single precision float leads to plenty of 14 | // artifacts in the resulting image, but that's something we're happy to live with for the moment. 15 | 16 | using System; 17 | using Unity.Burst; 18 | using Unity.Collections.LowLevel.Unsafe; 19 | using Unity.Mathematics; 20 | using Unity.Profiling; 21 | using UnityEngine; 22 | using static Unity.Mathematics.math; 23 | using Random = Unity.Mathematics.Random; 24 | 25 | [BurstCompile] 26 | public unsafe class Raytracer : MonoBehaviour 27 | { 28 | public Material TargetMaterial; 29 | 30 | delegate void Render(float4* pixels, Sphere* spheres, int numSpheres, int step); 31 | delegate void RenderSimd(float4* pixels, Sphere* spheres, int numSpheres, int step); 32 | 33 | Render m_Raytrace; 34 | RenderSimd m_RaytraceSimd; 35 | 36 | const int k_Height = 128; 37 | const int k_Width = 128; 38 | bool m_UseSimd; 39 | Texture2D m_Texture; 40 | Sphere[] m_Spheres; 41 | int m_Step; 42 | 43 | ProfilerMarker m_RaytraceMarker = new ProfilerMarker("Raytrace"); 44 | 45 | void Start() 46 | { 47 | m_Texture = new Texture2D(k_Width, k_Height, TextureFormat.RGBAFloat, true, false); 48 | m_Texture.wrapMode = TextureWrapMode.Clamp; 49 | TargetMaterial.mainTexture = m_Texture; 50 | 51 | m_Spheres = new[] 52 | { 53 | new Sphere(1E5f, float3(1+1E5f, 40.8f, 81.6f), float3(.75f, .25f, .25f)), // left 54 | new Sphere(1E5f, float3(99-1E5f, 40.8f, 81.6f), float3(.25f, .25f, .75f)), // right 55 | new Sphere(1E5f, float3(50, 40.8f, 1E5f), float3(.75f)), // back 56 | new Sphere(1E5f, float3(50, 40.8f, 170 - 1E5f), float3(0)), // front 57 | new Sphere(1E5f, float3(50, 1E5f, 81.6f), float3(.75f)), // bottom 58 | new Sphere(1E5f, float3(50, 81 - 1E5f, 81.6f), float3(.75f)), // top 59 | new Sphere(16.5f, float3(27, 16.5f, 47), float3(.999f), Mat.Specular), // mirror 60 | new Sphere(16.5f, float3(73, 16.5f, 78), float3(.999f), Mat.Refract), // glas 61 | new Sphere(600f, float3(50, 681.6f-.27f, 81.6f), float3(0), Mat.Diffuse, float3(12)) // light 62 | }; 63 | 64 | m_Raytrace = BurstCompiler.CompileFunctionPointer(Raytrace).Invoke; 65 | m_RaytraceSimd = BurstCompiler.CompileFunctionPointer(RaytraceSimd).Invoke; 66 | } 67 | 68 | void Update() 69 | { 70 | var pixels = m_Texture.GetRawTextureData(); 71 | if (Input.GetKeyDown(KeyCode.Space)) 72 | { 73 | m_UseSimd = !m_UseSimd; 74 | m_Step = 0; 75 | UnsafeUtility.MemClear(pixels.GetUnsafePtr(), pixels.Length * sizeof(float4)); 76 | Debug.Log("SIMD is " + (m_UseSimd ? "on" : "off")); 77 | } 78 | else 79 | { 80 | m_RaytraceMarker.Begin(); 81 | 82 | float4* pixelPtr = (float4*)pixels.GetUnsafePtr(); 83 | if (m_UseSimd) 84 | { 85 | fixed (Sphere* spheres = m_Spheres) 86 | m_RaytraceSimd.Invoke(pixelPtr, spheres, m_Spheres.Length, m_Step); 87 | } 88 | else 89 | { 90 | fixed (Sphere* spheres = m_Spheres) 91 | m_Raytrace.Invoke(pixelPtr, spheres, m_Spheres.Length, m_Step); 92 | } 93 | 94 | m_Step += 1; 95 | m_RaytraceMarker.End(); 96 | } 97 | m_Texture.Apply(); 98 | } 99 | 100 | struct Ray 101 | { 102 | public Ray(float3 origin, float3 dir) 103 | { 104 | Origin = origin; 105 | Dir = dir; 106 | } 107 | public float3 Origin; 108 | public float3 Dir; 109 | public float3 At(float t) => Origin + t * Dir; 110 | } 111 | 112 | struct Sphere 113 | { 114 | public Sphere(float radius, float3 pos, float3 color, Mat material = Mat.Diffuse, float3 emission = new float3()) 115 | { 116 | Radius = radius; 117 | Position = pos; 118 | Color = color; 119 | Emission = emission; 120 | Material = material; 121 | } 122 | public float Radius; 123 | public float3 Position; 124 | public float3 Emission; 125 | public float3 Color; 126 | public Mat Material; 127 | 128 | public float Intersect(in Ray ray) 129 | { 130 | float3 op = Position - ray.Origin; 131 | float b = dot(op, ray.Dir); 132 | float det = b * b - dot(op, op) + Radius * Radius; 133 | if (det < 0) 134 | return 0; 135 | det = sqrt(det); 136 | const float eps = 1E-4f; 137 | if (b - det > eps) return b - det; 138 | if (b + det > eps) return b + det; 139 | return 0; 140 | } 141 | } 142 | 143 | enum Mat : byte { 144 | Diffuse, Specular, Refract 145 | } 146 | 147 | static bool Intersect(Sphere* spheres, int numSpheres, in Ray ray, out float t, out int id) 148 | { 149 | t = float.PositiveInfinity; 150 | id = -1; 151 | for (int i = 0; i < numSpheres; i++) 152 | { 153 | float d = spheres[i].Intersect(ray); 154 | if (d != 0 && d < t) 155 | { 156 | t = d; 157 | id = i; 158 | } 159 | } 160 | return t < float.PositiveInfinity; 161 | } 162 | 163 | static float3 Radiance(Sphere* spheres, int numSpheres, Ray r, ref Random rng) 164 | { 165 | Ray currentRay = r; 166 | float3 accColor = float3(0); 167 | float3 accReflectance = float3(1); 168 | int depth = 0; 169 | while (true) 170 | { 171 | if (!Intersect(spheres, numSpheres, currentRay, out float t, out int id)) 172 | return accColor; 173 | ref Sphere obj = ref spheres[id]; 174 | float3 intersection = currentRay.At(t); 175 | float3 normal = normalize(intersection - obj.Position); 176 | float3 nl = dot(normal, currentRay.Dir) < 0 ? normal : normal * -1; 177 | float3 f = obj.Color; 178 | accColor += accReflectance * obj.Emission; 179 | depth += 1; 180 | if (depth > 5) 181 | { 182 | float p = cmax(f); 183 | if (rng.NextFloat() < p) 184 | f = f * (1f / p); 185 | else 186 | return accColor; 187 | } 188 | accReflectance *= f; 189 | 190 | switch (obj.Material) 191 | { 192 | case Mat.Diffuse: 193 | { 194 | // ideal diffuse reflection 195 | 196 | // construct orthonormal coordinate system (w,u,v) at intersection 197 | float3 w = nl; 198 | float3 u; 199 | if (abs(w.x) > .1f) 200 | u = float3(0, 1, 0); 201 | else 202 | u = normalize(cross(float3(1, 0, 0), w)); 203 | float3 v = cross(w, u); 204 | 205 | // produce cos-weighted sample on the hemisphere 206 | float angle = 2 * PI * rng.NextFloat(); 207 | float dist = rng.NextFloat(); 208 | float distSqrt = sqrt(dist); 209 | sincos(angle, out var r1Sin, out var r1Cos); 210 | float3 dir = normalize(u * r1Cos * distSqrt + v * r1Sin * distSqrt + w * sqrt(1 - dist)); 211 | currentRay = new Ray(intersection, dir); 212 | break; 213 | } 214 | case Mat.Specular: 215 | { 216 | // ideal specular reflection 217 | currentRay = new Ray(intersection, currentRay.Dir - normal * 2 * dot(normal, currentRay.Dir)); 218 | break; 219 | } 220 | case Mat.Refract: 221 | { 222 | // ideal dielectric refraction 223 | Ray reflRay = new Ray(intersection, currentRay.Dir - normal * 2 * dot(normal, currentRay.Dir)); 224 | bool into = dot(normal, nl) > 0; 225 | const float nc = 1; 226 | const float nt = 1.5f; 227 | float nnt = into ? nc / nt : nt / nc; 228 | float ddn = dot(currentRay.Dir, nl); 229 | float cos2t = 1 - nnt * nnt * (1 - ddn * ddn); 230 | if (cos2t < 0) 231 | { 232 | // Total internal reflection 233 | currentRay = reflRay; 234 | break; 235 | } 236 | 237 | float3 transmissionDir = normalize(currentRay.Dir * nnt - normal * ((into ? 1 : -1) * (ddn * nnt + sqrt(cos2t)))); 238 | const float a = nt - nc; 239 | const float b = nt + nc; 240 | const float R0 = a * a / (b * b); 241 | float c = 1 - (into ? -ddn : dot(transmissionDir, normal)); 242 | float reflectance = R0 + (1 - R0) * c * c * c * c * c; 243 | float p = .25f + .5f * reflectance; 244 | 245 | if (rng.NextFloat() < p) 246 | { 247 | accReflectance *= reflectance / p; 248 | currentRay = reflRay; 249 | } 250 | else 251 | { 252 | accReflectance *= (1 - reflectance) / (1 - p); 253 | currentRay = new Ray(intersection, transmissionDir); 254 | } 255 | break; 256 | } 257 | } 258 | } 259 | } 260 | 261 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 262 | static void Raytrace(float4* pixels, Sphere* spheres, int numSpheres, int step) 263 | { 264 | var dim = float2(k_Width, k_Height); 265 | const int numSamples = 4; 266 | Ray cam = new Ray 267 | { 268 | Origin = float3(50, 52, 295.6f), 269 | Dir = normalize(float3(0, -0.042612f, -1)) 270 | }; 271 | 272 | float3 cx = float3(k_Width * .5135f / k_Height, 0, 0); 273 | float3 cy = normalize(cross(cx, cam.Dir)) * .5135f; 274 | for (int y = 0; y < k_Height; y++) 275 | { 276 | for (int x = 0; x < k_Width; x++) 277 | { 278 | int pixelIdx = y * k_Width + x; 279 | var rng = new Random((uint)(1500450271 * (y + 1) * (step + 1))); 280 | 281 | // subpixels 282 | for (int sy = 0; sy < 2; sy++) 283 | { 284 | for (int sx = 0; sx < 2; sx++) 285 | { 286 | float3 result = float3(0); 287 | for (int sample = 0; sample < numSamples; sample++) 288 | { 289 | float2 d; 290 | { 291 | // this sampling code makes it more probably to sample points close to the center of 292 | // the pixel. 293 | float2 r = 2 * rng.NextFloat2(); 294 | float dx = r.x < 1 ? sqrt(r.x) - 1 : 1 - sqrt(2 - r.x); 295 | float dy = r.y < 1 ? sqrt(r.y) - 1 : 1 - sqrt(2 - r.y); 296 | d = float2(dx, dy); 297 | } 298 | 299 | var s = float2(sx, sy); 300 | var f = ((s + .5f + d) / 2 + float2(x, y)) / dim - .5f; 301 | var dir = cx * f.x + cy * f.y + cam.Dir; 302 | var ray = new Ray(cam.Origin + dir * 140, normalize(dir)); 303 | result += Radiance(spheres, numSpheres, ray, ref rng); 304 | } 305 | 306 | float3 existingMass = pixels[pixelIdx].xyz * step * numSamples; 307 | int totalSamples = (step + 1) * numSamples; 308 | result = (result + existingMass) / totalSamples; 309 | pixels[pixelIdx] = float4(result, 1); 310 | } 311 | } 312 | } 313 | } 314 | } 315 | 316 | [BurstCompile(FloatMode = FloatMode.Fast, CompileSynchronously = true)] 317 | static void RaytraceSimd(float4* pixels, Sphere* spheres, int numSpheres, int step) 318 | { 319 | // YOUR SIMD CODE HERE 320 | } 321 | } 322 | -------------------------------------------------------------------------------- /Assets/Exercises/5-raytracer/Raytracer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 849bf95742b9fce4abf6afa380b3d31a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Exercises/5-raytracer/RaytracerMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: RaytracerMaterial 11 | m_Shader: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 1, g: 1, b: 1, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Assets/Exercises/5-raytracer/RaytracerMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d456772b44b2e804db747c4f08b9d6f1 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Exercises/5-raytracer/Raytracer_Scene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &672588258 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 672588260} 133 | - component: {fileID: 672588259} 134 | m_Layer: 0 135 | m_Name: Bootstrap 136 | m_TagString: Untagged 137 | m_Icon: {fileID: 0} 138 | m_NavMeshLayer: 0 139 | m_StaticEditorFlags: 0 140 | m_IsActive: 1 141 | --- !u!114 &672588259 142 | MonoBehaviour: 143 | m_ObjectHideFlags: 0 144 | m_CorrespondingSourceObject: {fileID: 0} 145 | m_PrefabInstance: {fileID: 0} 146 | m_PrefabAsset: {fileID: 0} 147 | m_GameObject: {fileID: 672588258} 148 | m_Enabled: 1 149 | m_EditorHideFlags: 0 150 | m_Script: {fileID: 11500000, guid: 849bf95742b9fce4abf6afa380b3d31a, type: 3} 151 | m_Name: 152 | m_EditorClassIdentifier: 153 | TargetMaterial: {fileID: 2100000, guid: d456772b44b2e804db747c4f08b9d6f1, type: 2} 154 | --- !u!4 &672588260 155 | Transform: 156 | m_ObjectHideFlags: 0 157 | m_CorrespondingSourceObject: {fileID: 0} 158 | m_PrefabInstance: {fileID: 0} 159 | m_PrefabAsset: {fileID: 0} 160 | m_GameObject: {fileID: 672588258} 161 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 162 | m_LocalPosition: {x: 0, y: 0, z: 0} 163 | m_LocalScale: {x: 1, y: 1, z: 1} 164 | m_Children: [] 165 | m_Father: {fileID: 0} 166 | m_RootOrder: 2 167 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 168 | --- !u!1 &1090215382 169 | GameObject: 170 | m_ObjectHideFlags: 0 171 | m_CorrespondingSourceObject: {fileID: 0} 172 | m_PrefabInstance: {fileID: 0} 173 | m_PrefabAsset: {fileID: 0} 174 | serializedVersion: 6 175 | m_Component: 176 | - component: {fileID: 1090215385} 177 | - component: {fileID: 1090215384} 178 | - component: {fileID: 1090215383} 179 | m_Layer: 0 180 | m_Name: Quad 181 | m_TagString: Untagged 182 | m_Icon: {fileID: 0} 183 | m_NavMeshLayer: 0 184 | m_StaticEditorFlags: 0 185 | m_IsActive: 1 186 | --- !u!23 &1090215383 187 | MeshRenderer: 188 | m_ObjectHideFlags: 0 189 | m_CorrespondingSourceObject: {fileID: 0} 190 | m_PrefabInstance: {fileID: 0} 191 | m_PrefabAsset: {fileID: 0} 192 | m_GameObject: {fileID: 1090215382} 193 | m_Enabled: 1 194 | m_CastShadows: 0 195 | m_ReceiveShadows: 0 196 | m_DynamicOccludee: 0 197 | m_MotionVectors: 2 198 | m_LightProbeUsage: 0 199 | m_ReflectionProbeUsage: 0 200 | m_RayTracingMode: 2 201 | m_RenderingLayerMask: 1 202 | m_RendererPriority: 0 203 | m_Materials: 204 | - {fileID: 2100000, guid: d456772b44b2e804db747c4f08b9d6f1, type: 2} 205 | m_StaticBatchInfo: 206 | firstSubMesh: 0 207 | subMeshCount: 0 208 | m_StaticBatchRoot: {fileID: 0} 209 | m_ProbeAnchor: {fileID: 0} 210 | m_LightProbeVolumeOverride: {fileID: 0} 211 | m_ScaleInLightmap: 1 212 | m_ReceiveGI: 1 213 | m_PreserveUVs: 0 214 | m_IgnoreNormalsForChartDetection: 0 215 | m_ImportantGI: 0 216 | m_StitchLightmapSeams: 1 217 | m_SelectedEditorRenderState: 3 218 | m_MinimumChartSize: 4 219 | m_AutoUVMaxDistance: 0.5 220 | m_AutoUVMaxAngle: 89 221 | m_LightmapParameters: {fileID: 0} 222 | m_SortingLayerID: 0 223 | m_SortingLayer: 0 224 | m_SortingOrder: 0 225 | --- !u!33 &1090215384 226 | MeshFilter: 227 | m_ObjectHideFlags: 0 228 | m_CorrespondingSourceObject: {fileID: 0} 229 | m_PrefabInstance: {fileID: 0} 230 | m_PrefabAsset: {fileID: 0} 231 | m_GameObject: {fileID: 1090215382} 232 | m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} 233 | --- !u!4 &1090215385 234 | Transform: 235 | m_ObjectHideFlags: 0 236 | m_CorrespondingSourceObject: {fileID: 0} 237 | m_PrefabInstance: {fileID: 0} 238 | m_PrefabAsset: {fileID: 0} 239 | m_GameObject: {fileID: 1090215382} 240 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 241 | m_LocalPosition: {x: 0, y: 0, z: 0} 242 | m_LocalScale: {x: 8, y: 8, z: 1} 243 | m_Children: [] 244 | m_Father: {fileID: 0} 245 | m_RootOrder: 1 246 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 247 | --- !u!1 &2097868333 248 | GameObject: 249 | m_ObjectHideFlags: 0 250 | m_CorrespondingSourceObject: {fileID: 0} 251 | m_PrefabInstance: {fileID: 0} 252 | m_PrefabAsset: {fileID: 0} 253 | serializedVersion: 6 254 | m_Component: 255 | - component: {fileID: 2097868336} 256 | - component: {fileID: 2097868335} 257 | - component: {fileID: 2097868334} 258 | m_Layer: 0 259 | m_Name: Main Camera 260 | m_TagString: MainCamera 261 | m_Icon: {fileID: 0} 262 | m_NavMeshLayer: 0 263 | m_StaticEditorFlags: 0 264 | m_IsActive: 1 265 | --- !u!81 &2097868334 266 | AudioListener: 267 | m_ObjectHideFlags: 0 268 | m_CorrespondingSourceObject: {fileID: 0} 269 | m_PrefabInstance: {fileID: 0} 270 | m_PrefabAsset: {fileID: 0} 271 | m_GameObject: {fileID: 2097868333} 272 | m_Enabled: 1 273 | --- !u!20 &2097868335 274 | Camera: 275 | m_ObjectHideFlags: 0 276 | m_CorrespondingSourceObject: {fileID: 0} 277 | m_PrefabInstance: {fileID: 0} 278 | m_PrefabAsset: {fileID: 0} 279 | m_GameObject: {fileID: 2097868333} 280 | m_Enabled: 1 281 | serializedVersion: 2 282 | m_ClearFlags: 2 283 | m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0} 284 | m_projectionMatrixMode: 1 285 | m_GateFitMode: 2 286 | m_FOVAxisMode: 0 287 | m_SensorSize: {x: 36, y: 24} 288 | m_LensShift: {x: 0, y: 0} 289 | m_FocalLength: 50 290 | m_NormalizedViewPortRect: 291 | serializedVersion: 2 292 | x: 0 293 | y: 0 294 | width: 1 295 | height: 1 296 | near clip plane: 0.3 297 | far clip plane: 1000 298 | field of view: 60 299 | orthographic: 1 300 | orthographic size: 5 301 | m_Depth: -1 302 | m_CullingMask: 303 | serializedVersion: 2 304 | m_Bits: 4294967295 305 | m_RenderingPath: -1 306 | m_TargetTexture: {fileID: 0} 307 | m_TargetDisplay: 0 308 | m_TargetEye: 3 309 | m_HDR: 1 310 | m_AllowMSAA: 1 311 | m_AllowDynamicResolution: 0 312 | m_ForceIntoRT: 0 313 | m_OcclusionCulling: 1 314 | m_StereoConvergence: 10 315 | m_StereoSeparation: 0.022 316 | --- !u!4 &2097868336 317 | Transform: 318 | m_ObjectHideFlags: 0 319 | m_CorrespondingSourceObject: {fileID: 0} 320 | m_PrefabInstance: {fileID: 0} 321 | m_PrefabAsset: {fileID: 0} 322 | m_GameObject: {fileID: 2097868333} 323 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 324 | m_LocalPosition: {x: 0, y: 0, z: -10} 325 | m_LocalScale: {x: 1, y: 1, z: 1} 326 | m_Children: [] 327 | m_Father: {fileID: 0} 328 | m_RootOrder: 0 329 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 330 | -------------------------------------------------------------------------------- /Assets/Exercises/5-raytracer/Raytracer_Scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6d23ec2bb90173c40805b74a80645e12 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2021 Sebastian Schöner 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.burst": "1.5.0", 4 | "com.unity.collab-proxy": "1.3.9", 5 | "com.unity.ide.rider": "2.0.7", 6 | "com.unity.ide.visualstudio": "2.0.7", 7 | "com.unity.ide.vscode": "1.2.3", 8 | "com.unity.test-framework": "1.1.22", 9 | "com.unity.textmeshpro": "3.0.1", 10 | "com.unity.timeline": "1.4.6", 11 | "com.unity.ugui": "1.0.0", 12 | "com.unity.modules.ai": "1.0.0", 13 | "com.unity.modules.androidjni": "1.0.0", 14 | "com.unity.modules.animation": "1.0.0", 15 | "com.unity.modules.assetbundle": "1.0.0", 16 | "com.unity.modules.audio": "1.0.0", 17 | "com.unity.modules.cloth": "1.0.0", 18 | "com.unity.modules.director": "1.0.0", 19 | "com.unity.modules.imageconversion": "1.0.0", 20 | "com.unity.modules.imgui": "1.0.0", 21 | "com.unity.modules.jsonserialize": "1.0.0", 22 | "com.unity.modules.particlesystem": "1.0.0", 23 | "com.unity.modules.physics": "1.0.0", 24 | "com.unity.modules.physics2d": "1.0.0", 25 | "com.unity.modules.screencapture": "1.0.0", 26 | "com.unity.modules.terrain": "1.0.0", 27 | "com.unity.modules.terrainphysics": "1.0.0", 28 | "com.unity.modules.tilemap": "1.0.0", 29 | "com.unity.modules.ui": "1.0.0", 30 | "com.unity.modules.uielements": "1.0.0", 31 | "com.unity.modules.umbra": "1.0.0", 32 | "com.unity.modules.unityanalytics": "1.0.0", 33 | "com.unity.modules.unitywebrequest": "1.0.0", 34 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 35 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 36 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 37 | "com.unity.modules.unitywebrequestwww": "1.0.0", 38 | "com.unity.modules.vehicles": "1.0.0", 39 | "com.unity.modules.video": "1.0.0", 40 | "com.unity.modules.vr": "1.0.0", 41 | "com.unity.modules.wind": "1.0.0", 42 | "com.unity.modules.xr": "1.0.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Packages/packages-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.burst": { 4 | "version": "1.5.0", 5 | "depth": 0, 6 | "source": "registry", 7 | "dependencies": { 8 | "com.unity.mathematics": "1.2.1" 9 | }, 10 | "url": "https://packages.unity.com" 11 | }, 12 | "com.unity.collab-proxy": { 13 | "version": "1.3.9", 14 | "depth": 0, 15 | "source": "registry", 16 | "dependencies": {}, 17 | "url": "https://packages.unity.com" 18 | }, 19 | "com.unity.ext.nunit": { 20 | "version": "1.0.6", 21 | "depth": 1, 22 | "source": "registry", 23 | "dependencies": {}, 24 | "url": "https://packages.unity.com" 25 | }, 26 | "com.unity.ide.rider": { 27 | "version": "2.0.7", 28 | "depth": 0, 29 | "source": "registry", 30 | "dependencies": { 31 | "com.unity.test-framework": "1.1.1" 32 | }, 33 | "url": "https://packages.unity.com" 34 | }, 35 | "com.unity.ide.visualstudio": { 36 | "version": "2.0.7", 37 | "depth": 0, 38 | "source": "registry", 39 | "dependencies": { 40 | "com.unity.test-framework": "1.1.9" 41 | }, 42 | "url": "https://packages.unity.com" 43 | }, 44 | "com.unity.ide.vscode": { 45 | "version": "1.2.3", 46 | "depth": 0, 47 | "source": "registry", 48 | "dependencies": {}, 49 | "url": "https://packages.unity.com" 50 | }, 51 | "com.unity.mathematics": { 52 | "version": "1.2.1", 53 | "depth": 1, 54 | "source": "registry", 55 | "dependencies": {}, 56 | "url": "https://packages.unity.com" 57 | }, 58 | "com.unity.test-framework": { 59 | "version": "1.1.22", 60 | "depth": 0, 61 | "source": "registry", 62 | "dependencies": { 63 | "com.unity.ext.nunit": "1.0.6", 64 | "com.unity.modules.imgui": "1.0.0", 65 | "com.unity.modules.jsonserialize": "1.0.0" 66 | }, 67 | "url": "https://packages.unity.com" 68 | }, 69 | "com.unity.textmeshpro": { 70 | "version": "3.0.1", 71 | "depth": 0, 72 | "source": "registry", 73 | "dependencies": { 74 | "com.unity.ugui": "1.0.0" 75 | }, 76 | "url": "https://packages.unity.com" 77 | }, 78 | "com.unity.timeline": { 79 | "version": "1.4.6", 80 | "depth": 0, 81 | "source": "registry", 82 | "dependencies": { 83 | "com.unity.modules.director": "1.0.0", 84 | "com.unity.modules.animation": "1.0.0", 85 | "com.unity.modules.audio": "1.0.0", 86 | "com.unity.modules.particlesystem": "1.0.0" 87 | }, 88 | "url": "https://packages.unity.com" 89 | }, 90 | "com.unity.ugui": { 91 | "version": "1.0.0", 92 | "depth": 0, 93 | "source": "builtin", 94 | "dependencies": { 95 | "com.unity.modules.ui": "1.0.0", 96 | "com.unity.modules.imgui": "1.0.0" 97 | } 98 | }, 99 | "com.unity.modules.ai": { 100 | "version": "1.0.0", 101 | "depth": 0, 102 | "source": "builtin", 103 | "dependencies": {} 104 | }, 105 | "com.unity.modules.androidjni": { 106 | "version": "1.0.0", 107 | "depth": 0, 108 | "source": "builtin", 109 | "dependencies": {} 110 | }, 111 | "com.unity.modules.animation": { 112 | "version": "1.0.0", 113 | "depth": 0, 114 | "source": "builtin", 115 | "dependencies": {} 116 | }, 117 | "com.unity.modules.assetbundle": { 118 | "version": "1.0.0", 119 | "depth": 0, 120 | "source": "builtin", 121 | "dependencies": {} 122 | }, 123 | "com.unity.modules.audio": { 124 | "version": "1.0.0", 125 | "depth": 0, 126 | "source": "builtin", 127 | "dependencies": {} 128 | }, 129 | "com.unity.modules.cloth": { 130 | "version": "1.0.0", 131 | "depth": 0, 132 | "source": "builtin", 133 | "dependencies": { 134 | "com.unity.modules.physics": "1.0.0" 135 | } 136 | }, 137 | "com.unity.modules.director": { 138 | "version": "1.0.0", 139 | "depth": 0, 140 | "source": "builtin", 141 | "dependencies": { 142 | "com.unity.modules.audio": "1.0.0", 143 | "com.unity.modules.animation": "1.0.0" 144 | } 145 | }, 146 | "com.unity.modules.imageconversion": { 147 | "version": "1.0.0", 148 | "depth": 0, 149 | "source": "builtin", 150 | "dependencies": {} 151 | }, 152 | "com.unity.modules.imgui": { 153 | "version": "1.0.0", 154 | "depth": 0, 155 | "source": "builtin", 156 | "dependencies": {} 157 | }, 158 | "com.unity.modules.jsonserialize": { 159 | "version": "1.0.0", 160 | "depth": 0, 161 | "source": "builtin", 162 | "dependencies": {} 163 | }, 164 | "com.unity.modules.particlesystem": { 165 | "version": "1.0.0", 166 | "depth": 0, 167 | "source": "builtin", 168 | "dependencies": {} 169 | }, 170 | "com.unity.modules.physics": { 171 | "version": "1.0.0", 172 | "depth": 0, 173 | "source": "builtin", 174 | "dependencies": {} 175 | }, 176 | "com.unity.modules.physics2d": { 177 | "version": "1.0.0", 178 | "depth": 0, 179 | "source": "builtin", 180 | "dependencies": {} 181 | }, 182 | "com.unity.modules.screencapture": { 183 | "version": "1.0.0", 184 | "depth": 0, 185 | "source": "builtin", 186 | "dependencies": { 187 | "com.unity.modules.imageconversion": "1.0.0" 188 | } 189 | }, 190 | "com.unity.modules.subsystems": { 191 | "version": "1.0.0", 192 | "depth": 1, 193 | "source": "builtin", 194 | "dependencies": { 195 | "com.unity.modules.jsonserialize": "1.0.0" 196 | } 197 | }, 198 | "com.unity.modules.terrain": { 199 | "version": "1.0.0", 200 | "depth": 0, 201 | "source": "builtin", 202 | "dependencies": {} 203 | }, 204 | "com.unity.modules.terrainphysics": { 205 | "version": "1.0.0", 206 | "depth": 0, 207 | "source": "builtin", 208 | "dependencies": { 209 | "com.unity.modules.physics": "1.0.0", 210 | "com.unity.modules.terrain": "1.0.0" 211 | } 212 | }, 213 | "com.unity.modules.tilemap": { 214 | "version": "1.0.0", 215 | "depth": 0, 216 | "source": "builtin", 217 | "dependencies": { 218 | "com.unity.modules.physics2d": "1.0.0" 219 | } 220 | }, 221 | "com.unity.modules.ui": { 222 | "version": "1.0.0", 223 | "depth": 0, 224 | "source": "builtin", 225 | "dependencies": {} 226 | }, 227 | "com.unity.modules.uielements": { 228 | "version": "1.0.0", 229 | "depth": 0, 230 | "source": "builtin", 231 | "dependencies": { 232 | "com.unity.modules.ui": "1.0.0", 233 | "com.unity.modules.imgui": "1.0.0", 234 | "com.unity.modules.jsonserialize": "1.0.0", 235 | "com.unity.modules.uielementsnative": "1.0.0" 236 | } 237 | }, 238 | "com.unity.modules.uielementsnative": { 239 | "version": "1.0.0", 240 | "depth": 1, 241 | "source": "builtin", 242 | "dependencies": { 243 | "com.unity.modules.ui": "1.0.0", 244 | "com.unity.modules.imgui": "1.0.0", 245 | "com.unity.modules.jsonserialize": "1.0.0" 246 | } 247 | }, 248 | "com.unity.modules.umbra": { 249 | "version": "1.0.0", 250 | "depth": 0, 251 | "source": "builtin", 252 | "dependencies": {} 253 | }, 254 | "com.unity.modules.unityanalytics": { 255 | "version": "1.0.0", 256 | "depth": 0, 257 | "source": "builtin", 258 | "dependencies": { 259 | "com.unity.modules.unitywebrequest": "1.0.0", 260 | "com.unity.modules.jsonserialize": "1.0.0" 261 | } 262 | }, 263 | "com.unity.modules.unitywebrequest": { 264 | "version": "1.0.0", 265 | "depth": 0, 266 | "source": "builtin", 267 | "dependencies": {} 268 | }, 269 | "com.unity.modules.unitywebrequestassetbundle": { 270 | "version": "1.0.0", 271 | "depth": 0, 272 | "source": "builtin", 273 | "dependencies": { 274 | "com.unity.modules.assetbundle": "1.0.0", 275 | "com.unity.modules.unitywebrequest": "1.0.0" 276 | } 277 | }, 278 | "com.unity.modules.unitywebrequestaudio": { 279 | "version": "1.0.0", 280 | "depth": 0, 281 | "source": "builtin", 282 | "dependencies": { 283 | "com.unity.modules.unitywebrequest": "1.0.0", 284 | "com.unity.modules.audio": "1.0.0" 285 | } 286 | }, 287 | "com.unity.modules.unitywebrequesttexture": { 288 | "version": "1.0.0", 289 | "depth": 0, 290 | "source": "builtin", 291 | "dependencies": { 292 | "com.unity.modules.unitywebrequest": "1.0.0", 293 | "com.unity.modules.imageconversion": "1.0.0" 294 | } 295 | }, 296 | "com.unity.modules.unitywebrequestwww": { 297 | "version": "1.0.0", 298 | "depth": 0, 299 | "source": "builtin", 300 | "dependencies": { 301 | "com.unity.modules.unitywebrequest": "1.0.0", 302 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 303 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 304 | "com.unity.modules.audio": "1.0.0", 305 | "com.unity.modules.assetbundle": "1.0.0", 306 | "com.unity.modules.imageconversion": "1.0.0" 307 | } 308 | }, 309 | "com.unity.modules.vehicles": { 310 | "version": "1.0.0", 311 | "depth": 0, 312 | "source": "builtin", 313 | "dependencies": { 314 | "com.unity.modules.physics": "1.0.0" 315 | } 316 | }, 317 | "com.unity.modules.video": { 318 | "version": "1.0.0", 319 | "depth": 0, 320 | "source": "builtin", 321 | "dependencies": { 322 | "com.unity.modules.audio": "1.0.0", 323 | "com.unity.modules.ui": "1.0.0", 324 | "com.unity.modules.unitywebrequest": "1.0.0" 325 | } 326 | }, 327 | "com.unity.modules.vr": { 328 | "version": "1.0.0", 329 | "depth": 0, 330 | "source": "builtin", 331 | "dependencies": { 332 | "com.unity.modules.jsonserialize": "1.0.0", 333 | "com.unity.modules.physics": "1.0.0", 334 | "com.unity.modules.xr": "1.0.0" 335 | } 336 | }, 337 | "com.unity.modules.wind": { 338 | "version": "1.0.0", 339 | "depth": 0, 340 | "source": "builtin", 341 | "dependencies": {} 342 | }, 343 | "com.unity.modules.xr": { 344 | "version": "1.0.0", 345 | "depth": 0, 346 | "source": "builtin", 347 | "dependencies": { 348 | "com.unity.modules.physics": "1.0.0", 349 | "com.unity.modules.jsonserialize": "1.0.0", 350 | "com.unity.modules.subsystems": "1.0.0" 351 | } 352 | } 353 | } 354 | } 355 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Volume: 1 8 | Rolloff Scale: 1 9 | Doppler Factor: 1 10 | Default Speaker Mode: 2 11 | m_SampleRate: 0 12 | m_DSPBufferSize: 1024 13 | m_VirtualVoiceCount: 512 14 | m_RealVoiceCount: 32 15 | m_SpatializerPlugin: 16 | m_AmbisonicDecoderPlugin: 17 | m_DisableAudio: 0 18 | m_VirtualizeEffects: 1 19 | m_RequestedDSPBufferSize: 1024 20 | -------------------------------------------------------------------------------- /ProjectSettings/BurstAotSettings_Android.json: -------------------------------------------------------------------------------- 1 | { 2 | "MonoBehaviour": { 3 | "Version": 3, 4 | "EnableBurstCompilation": true, 5 | "EnableOptimisations": true, 6 | "EnableSafetyChecks": false, 7 | "EnableDebugInAllBuilds": false, 8 | "CpuMinTargetX32": 0, 9 | "CpuMaxTargetX32": 0, 10 | "CpuMinTargetX64": 0, 11 | "CpuMaxTargetX64": 0 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/CommonBurstAotSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "MonoBehaviour": { 3 | "Version": 3, 4 | "DisabledWarnings": "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 11 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 0 23 | m_ReuseCollisionCallbacks: 1 24 | m_ClothInterCollisionSettingsToggle: 0 25 | m_ContactPairsMode: 0 26 | m_BroadphaseType: 0 27 | m_WorldBounds: 28 | m_Center: {x: 0, y: 0, z: 0} 29 | m_Extent: {x: 250, y: 250, z: 250} 30 | m_WorldSubdivisions: 8 31 | m_FrictionType: 0 32 | m_EnableEnhancedDeterminism: 0 33 | m_EnableUnifiedHeightmaps: 1 34 | m_DefaultMaxAngluarSpeed: 7 35 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/Examples/0-sum-numbers-sse3/SumNumbers_SSE3_Scene.unity 10 | guid: c5e80c7f43456c241a8ab44f68dd5faa 11 | - enabled: 1 12 | path: Assets/Examples/1-count-small-numbers-sse2/CountSmallNumbers_SSE2_Scene.unity 13 | guid: 3a0e1f1737267604199a127079b14e29 14 | - enabled: 1 15 | path: Assets/Examples/2-sum-small-numbers-sse3/SumSmallNumbers_SSE3_Scene.unity 16 | guid: 7436cfc3f94c7a049916907d26930266 17 | m_configObjects: {} 18 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 9 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 2 10 | m_DefaultBehaviorMode: 0 11 | m_PrefabRegularEnvironment: {fileID: 0} 12 | m_PrefabUIEnvironment: {fileID: 0} 13 | m_SpritePackerMode: 0 14 | m_SpritePackerPaddingPower: 1 15 | m_EtcTextureCompressorBehavior: 1 16 | m_EtcTextureFastCompressor: 1 17 | m_EtcTextureNormalCompressor: 2 18 | m_EtcTextureBestCompressor: 4 19 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref 20 | m_ProjectGenerationRootNamespace: 21 | m_CollabEditorSettings: 22 | inProgressEnabled: 1 23 | m_EnableTextureStreamingInEditMode: 1 24 | m_EnableTextureStreamingInPlayMode: 1 25 | m_AsyncShaderCompilation: 1 26 | m_EnterPlayModeOptionsEnabled: 0 27 | m_EnterPlayModeOptions: 3 28 | m_ShowLightmapResolutionOverlay: 1 29 | m_UseLegacyProbeSampleCount: 1 30 | m_AssetPipelineMode: 1 31 | m_CacheServerMode: 0 32 | m_CacheServerEndpoint: 33 | m_CacheServerNamespacePrefix: default 34 | m_CacheServerEnableDownload: 1 35 | m_CacheServerEnableUpload: 1 36 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 13 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | m_PreloadedShaders: [] 39 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 40 | type: 0} 41 | m_CustomRenderPipeline: {fileID: 0} 42 | m_TransparencySortMode: 0 43 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 44 | m_DefaultRenderingPath: 1 45 | m_DefaultMobileRenderingPath: 1 46 | m_TierSettings: [] 47 | m_LightmapStripping: 0 48 | m_FogStripping: 0 49 | m_InstancingStripping: 0 50 | m_LightmapKeepPlain: 1 51 | m_LightmapKeepDirCombined: 1 52 | m_LightmapKeepDynamicPlain: 1 53 | m_LightmapKeepDynamicDirCombined: 1 54 | m_LightmapKeepShadowMask: 1 55 | m_LightmapKeepSubtractive: 1 56 | m_FogKeepLinear: 1 57 | m_FogKeepExp: 1 58 | m_FogKeepExp2: 1 59 | m_AlbedoSwatchInfos: [] 60 | m_LightsUseLinearIntensity: 0 61 | m_LightsUseColorTemperature: 0 62 | m_LogWhenShaderIsCompiled: 0 63 | m_AllowEnlightenSupportForUpgradedProject: 0 64 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /ProjectSettings/PackageManagerSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 61 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: 14 | m_EditorClassIdentifier: 15 | m_EnablePreviewPackages: 1 16 | m_EnablePackageDependencies: 1 17 | m_AdvancedSettingsExpanded: 1 18 | m_ScopedRegistriesSettingsExpanded: 1 19 | oneTimeWarningShown: 1 20 | m_Registries: 21 | - m_Id: main 22 | m_Name: 23 | m_Url: https://packages.unity.com 24 | m_Scopes: [] 25 | m_IsDefault: 1 26 | m_Capabilities: 7 27 | m_UserSelectedRegistryName: 28 | m_UserAddingNewScopedRegistry: 0 29 | m_RegistryInfoDraft: 30 | m_ErrorMessage: 31 | m_Original: 32 | m_Id: 33 | m_Name: 34 | m_Url: 35 | m_Scopes: [] 36 | m_IsDefault: 0 37 | m_Capabilities: 0 38 | m_Modified: 0 39 | m_Name: 40 | m_Url: 41 | m_Scopes: 42 | - 43 | m_SelectedScopeIndex: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_JobOptions: 23 | serializedVersion: 2 24 | useMultithreading: 0 25 | useConsistencySorting: 0 26 | m_InterpolationPosesPerJob: 100 27 | m_NewContactsPerJob: 30 28 | m_CollideContactsPerJob: 100 29 | m_ClearFlagsPerJob: 200 30 | m_ClearBodyForcesPerJob: 200 31 | m_SyncDiscreteFixturesPerJob: 50 32 | m_SyncContinuousFixturesPerJob: 50 33 | m_FindNearestContactsPerJob: 100 34 | m_UpdateTriggerContactsPerJob: 100 35 | m_IslandSolverCostThreshold: 100 36 | m_IslandSolverBodyCostScale: 1 37 | m_IslandSolverContactCostScale: 10 38 | m_IslandSolverJointCostScale: 10 39 | m_IslandSolverBodiesPerJob: 50 40 | m_IslandSolverContactsPerJob: 50 41 | m_AutoSimulation: 1 42 | m_QueriesHitTriggers: 1 43 | m_QueriesStartInColliders: 1 44 | m_CallbacksOnDisable: 1 45 | m_ReuseCollisionCallbacks: 1 46 | m_AutoSyncTransforms: 0 47 | m_AlwaysShowColliders: 0 48 | m_ShowColliderSleep: 1 49 | m_ShowColliderContacts: 0 50 | m_ShowColliderAABB: 0 51 | m_ContactArrowScale: 0.2 52 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 53 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 54 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 55 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 56 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 57 | -------------------------------------------------------------------------------- /ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_DefaultPresets: {} 8 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2020.3.2f1 2 | m_EditorVersionWithRevision: 2020.3.2f1 (44ad8f41be6f) 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 5 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | blendWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | streamingMipmapsActive: 0 33 | streamingMipmapsAddAllCameras: 1 34 | streamingMipmapsMemoryBudget: 512 35 | streamingMipmapsRenderersPerFrame: 512 36 | streamingMipmapsMaxLevelReduction: 2 37 | streamingMipmapsMaxFileIORequests: 1024 38 | particleRaycastBudget: 4 39 | asyncUploadTimeSlice: 2 40 | asyncUploadBufferSize: 16 41 | asyncUploadPersistentBuffer: 1 42 | resolutionScalingFixedDPIFactor: 1 43 | excludedTargetPlatforms: [] 44 | - serializedVersion: 2 45 | name: Low 46 | pixelLightCount: 0 47 | shadows: 0 48 | shadowResolution: 0 49 | shadowProjection: 1 50 | shadowCascades: 1 51 | shadowDistance: 20 52 | shadowNearPlaneOffset: 3 53 | shadowCascade2Split: 0.33333334 54 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 55 | shadowmaskMode: 0 56 | blendWeights: 2 57 | textureQuality: 0 58 | anisotropicTextures: 0 59 | antiAliasing: 0 60 | softParticles: 0 61 | softVegetation: 0 62 | realtimeReflectionProbes: 0 63 | billboardsFaceCameraPosition: 0 64 | vSyncCount: 0 65 | lodBias: 0.4 66 | maximumLODLevel: 0 67 | streamingMipmapsActive: 0 68 | streamingMipmapsAddAllCameras: 1 69 | streamingMipmapsMemoryBudget: 512 70 | streamingMipmapsRenderersPerFrame: 512 71 | streamingMipmapsMaxLevelReduction: 2 72 | streamingMipmapsMaxFileIORequests: 1024 73 | particleRaycastBudget: 16 74 | asyncUploadTimeSlice: 2 75 | asyncUploadBufferSize: 16 76 | asyncUploadPersistentBuffer: 1 77 | resolutionScalingFixedDPIFactor: 1 78 | excludedTargetPlatforms: [] 79 | - serializedVersion: 2 80 | name: Medium 81 | pixelLightCount: 1 82 | shadows: 1 83 | shadowResolution: 0 84 | shadowProjection: 1 85 | shadowCascades: 1 86 | shadowDistance: 20 87 | shadowNearPlaneOffset: 3 88 | shadowCascade2Split: 0.33333334 89 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 90 | shadowmaskMode: 0 91 | blendWeights: 2 92 | textureQuality: 0 93 | anisotropicTextures: 1 94 | antiAliasing: 0 95 | softParticles: 0 96 | softVegetation: 0 97 | realtimeReflectionProbes: 0 98 | billboardsFaceCameraPosition: 0 99 | vSyncCount: 1 100 | lodBias: 0.7 101 | maximumLODLevel: 0 102 | streamingMipmapsActive: 0 103 | streamingMipmapsAddAllCameras: 1 104 | streamingMipmapsMemoryBudget: 512 105 | streamingMipmapsRenderersPerFrame: 512 106 | streamingMipmapsMaxLevelReduction: 2 107 | streamingMipmapsMaxFileIORequests: 1024 108 | particleRaycastBudget: 64 109 | asyncUploadTimeSlice: 2 110 | asyncUploadBufferSize: 16 111 | asyncUploadPersistentBuffer: 1 112 | resolutionScalingFixedDPIFactor: 1 113 | excludedTargetPlatforms: [] 114 | - serializedVersion: 2 115 | name: High 116 | pixelLightCount: 2 117 | shadows: 2 118 | shadowResolution: 1 119 | shadowProjection: 1 120 | shadowCascades: 2 121 | shadowDistance: 40 122 | shadowNearPlaneOffset: 3 123 | shadowCascade2Split: 0.33333334 124 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 125 | shadowmaskMode: 1 126 | blendWeights: 2 127 | textureQuality: 0 128 | anisotropicTextures: 1 129 | antiAliasing: 0 130 | softParticles: 0 131 | softVegetation: 1 132 | realtimeReflectionProbes: 1 133 | billboardsFaceCameraPosition: 1 134 | vSyncCount: 1 135 | lodBias: 1 136 | maximumLODLevel: 0 137 | streamingMipmapsActive: 0 138 | streamingMipmapsAddAllCameras: 1 139 | streamingMipmapsMemoryBudget: 512 140 | streamingMipmapsRenderersPerFrame: 512 141 | streamingMipmapsMaxLevelReduction: 2 142 | streamingMipmapsMaxFileIORequests: 1024 143 | particleRaycastBudget: 256 144 | asyncUploadTimeSlice: 2 145 | asyncUploadBufferSize: 16 146 | asyncUploadPersistentBuffer: 1 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Very High 151 | pixelLightCount: 3 152 | shadows: 2 153 | shadowResolution: 2 154 | shadowProjection: 1 155 | shadowCascades: 2 156 | shadowDistance: 70 157 | shadowNearPlaneOffset: 3 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | blendWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 2 164 | antiAliasing: 2 165 | softParticles: 1 166 | softVegetation: 1 167 | realtimeReflectionProbes: 1 168 | billboardsFaceCameraPosition: 1 169 | vSyncCount: 1 170 | lodBias: 1.5 171 | maximumLODLevel: 0 172 | streamingMipmapsActive: 0 173 | streamingMipmapsAddAllCameras: 1 174 | streamingMipmapsMemoryBudget: 512 175 | streamingMipmapsRenderersPerFrame: 512 176 | streamingMipmapsMaxLevelReduction: 2 177 | streamingMipmapsMaxFileIORequests: 1024 178 | particleRaycastBudget: 1024 179 | asyncUploadTimeSlice: 2 180 | asyncUploadBufferSize: 16 181 | asyncUploadPersistentBuffer: 1 182 | resolutionScalingFixedDPIFactor: 1 183 | excludedTargetPlatforms: [] 184 | - serializedVersion: 2 185 | name: Ultra 186 | pixelLightCount: 4 187 | shadows: 2 188 | shadowResolution: 2 189 | shadowProjection: 1 190 | shadowCascades: 4 191 | shadowDistance: 150 192 | shadowNearPlaneOffset: 3 193 | shadowCascade2Split: 0.33333334 194 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 195 | shadowmaskMode: 1 196 | blendWeights: 4 197 | textureQuality: 0 198 | anisotropicTextures: 2 199 | antiAliasing: 2 200 | softParticles: 1 201 | softVegetation: 1 202 | realtimeReflectionProbes: 1 203 | billboardsFaceCameraPosition: 1 204 | vSyncCount: 1 205 | lodBias: 2 206 | maximumLODLevel: 0 207 | streamingMipmapsActive: 0 208 | streamingMipmapsAddAllCameras: 1 209 | streamingMipmapsMemoryBudget: 512 210 | streamingMipmapsRenderersPerFrame: 512 211 | streamingMipmapsMaxLevelReduction: 2 212 | streamingMipmapsMaxFileIORequests: 1024 213 | particleRaycastBudget: 4096 214 | asyncUploadTimeSlice: 2 215 | asyncUploadBufferSize: 16 216 | asyncUploadPersistentBuffer: 1 217 | resolutionScalingFixedDPIFactor: 1 218 | excludedTargetPlatforms: [] 219 | m_PerPlatformDefaultQuality: 220 | Android: 2 221 | Lumin: 5 222 | Nintendo 3DS: 5 223 | Nintendo Switch: 5 224 | PS4: 5 225 | PSP2: 2 226 | Stadia: 5 227 | Standalone: 5 228 | WebGL: 3 229 | Windows Store Apps: 5 230 | XboxOne: 5 231 | iPhone: 2 232 | tvOS: 2 233 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_Enabled: 0 8 | m_TestMode: 0 9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events 10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events 11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com 12 | m_TestInitMode: 0 13 | CrashReportingSettings: 14 | m_EventUrl: https://perf-events.cloud.unity3d.com 15 | m_Enabled: 0 16 | m_LogBufferSize: 10 17 | m_CaptureEditorExceptions: 1 18 | UnityPurchasingSettings: 19 | m_Enabled: 0 20 | m_TestMode: 0 21 | UnityAnalyticsSettings: 22 | m_Enabled: 0 23 | m_TestMode: 0 24 | m_InitializeOnStartup: 1 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_StripUpdateShader: {fileID: 0} 10 | m_RenderPipeSettingsPath: 11 | m_FixedTimeStep: 0.016666668 12 | m_MaxDeltaTime: 0.05 13 | -------------------------------------------------------------------------------- /ProjectSettings/VersionControlSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!890905787 &1 4 | VersionControlSettings: 5 | m_ObjectHideFlags: 0 6 | m_Mode: Visible Meta Files 7 | m_CollabEditorSettings: 8 | inProgressEnabled: 1 9 | -------------------------------------------------------------------------------- /ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | **PRs welcome! Find something that could be improved? Do it!** :) 2 | 3 | # SIMD using Burst 4 | Since version 1.5, Burst supports intrinsics for both x86 and ARM SIMD extensions. This repository contains some examples and exercises for using SIMD in Burst. 5 | 6 | The code in this repository is for educational use and aims to demonstrate how to use intrinsics using Burst. The examples are not necessarily the fastest way to compute these operations 7 | 8 | ## Where to start? 9 | 1. Open the project in Unity 2020.3 or later. 10 | 2. Take a look at the examples (see below) from the `Examples` folder. The examples are aimed at demonstrating both how to use intrinsics in Burst and how to use intrinsics in general. If you already have a lot of experience programming with SIMD intrinsics, you probably just want to skim the examples. 11 | 3. Pick an exercise from the `Exercises` folder and work on it using your preferred set of intrinsics. The exercises are roughly ordered by difficulty. Each example usually consists of a scene that either displays something or will at least tell you whether you're doing the right thing when entering playmode. 12 | 13 | With any exercise you are more than welcome to change the structure of the data around, and sometimes you won't get the best results without doing that. Also, it is instructive to look at the code Burst generated for the original implementation. Did Burst vectorize it? Is the code faster than your implementation? Slower? Why? Pick a sampling profile like VTune and figure out whether your implementation is memory-bound or compute-bound. Be curious! 14 | 15 | ## SIM-What? 16 | SIMD is short for **S**ingle **I**nstruction **M**ultiple **D**ata. It describes the capability of your CPU to apply the same operation to multiple inputs at (usually) little to no additional cost - provided your program is structured with that idea in mind. Pretty much all modern CPUs support some form of SIMD instructions. The architecture that this repository is concerned with is x86/x64, which includes all modern PCs, Macs, and consoles, but excludes mobile devices for the largest part. 17 | 18 | For now, it is probably sufficient to know that there are a bunch of SIMD instruction set extensions that build on each other: 19 | * **SSE/SSE2** are present on all modern x64 machines and allow you to process up to four floats at a time (by using 128bit vector registers called `XMM` registers), 20 | * **SSE3/SSE4** and its subfamilies are wide-spread on desktop platforms but not yet universally adopted; it mostly expands on the previous SSE iteration and fleshes out support for integer operations among other things, 21 | * **AVX** extends the `XMM` registers to 256bits `YMM` registers, 22 | * **AVX2** builds on AVX and extends the instruction set, 23 | * **AVX512** is the latest iteration of AVX but only really supported on a select few CPUs in the server space. 24 | 25 | Burst 1.3 adds support for directly using instructions from all SSE sets plus AVX and AVX2 using *intrinsics*: short functions that the compiler recognizes and will (usually) replace with exact instructions from that instruction set. 26 | 27 | ### Where can I learn more? 28 | * Andreas Fredrikson's Unite CPH 2019 talk ["Intrinsics: Low-level engine development with Burst"](https://www.youtube.com/watch?v=BpwvXkoFcp8) 29 | * Andreas Fredrikson's GDC 2015 talk ["SIMD at Insomniac Games"](https://www.gdcvault.com/play/1022248/SIMD-at-Insomniac-Games-How) 30 | * Intel's [Intrinsic Guide](https://software.intel.com/sites/landingpage/IntrinsicsGuide/) 31 | 32 | ## FAQ 33 | 34 | #### How can I easily write intrinsics without having to prefix them with their class name? 35 | Each instruction set extension has its own class, `Unity.Burst.Intrinsics.X86.Sse` for example contains all intrinsics that are available with `SSE`. To access them without the `Sse` prefix, use a [static import](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-static): 36 | ``` 37 | using static Unity.Burst.Intrinsics.X86.Sse; 38 | ``` 39 | 40 | #### How can I detect whether `SSE4.2` or some other extension is available? 41 | Burst exposes some fields that you can read from to determine whether a specific instruction set extension is supported. For example, you can use this to check for `SSE4.2` support: 42 | 43 | ``` 44 | // This branch is resolved at compile time 45 | if (Sse4_2.IsSse42Supported) { 46 | // SSE4.2 code 47 | } else { 48 | // probably SSE2 code as a fallback 49 | } 50 | ``` 51 | The branches on these special fields are resolved at compile-time and Windows/Mac/Linux builds of the project ship with all different versions of your code; the right version is then automatically selected at runtime. 52 | 53 | #### Where can I find more information about intrinsics? 54 | A good overview of all available intrinsics in the different x86 instruction set extensions is avaiable in the [Intel Intrinsics Guide](https://software.intel.com/sites/landingpage/IntrinsicsGuide/). The naming of the intrinsics is almost exactly the same as in Burst if you drop some prefixes, e.g. `_mm256_andnot_ps` becomes simply `andnot_ps` and `m256` is called `v256` in Burst. 55 | 56 | #### How do I make sense of the names of the intrinsics? 57 | Most intrinsic names follow a relatively simple structure: 58 | * a prefix denoting the instruction set (e.g. `_mm_` for `SSE`, `_mm256_` for `AVX` etc.), 59 | * a short mnemonic denoting the operation (e.g. `andnot`, `add`, `cvt` for convert, `cmpgt` for compare-greater-than), 60 | * a suffix to describe the lane-layout of the inputs and outputs. 61 | 62 | With Burst, the prefix is dropped since it is encoded in the class containing the intrinsic. The mnemonics are usually self-descriptive. This leaves the suffix. There are different type-codes that generally fall into two classes: 63 | * type-codes starting with `p` or `ep` describe a _packed_ layout; this is what you usually want and means that the intrinsic operates on all lanes of a register, 64 | * type-code starting with `s` describe a _scalar_ layout; those operations usually only operate on the lower-most lane of the register. 65 | 66 | Here are the commonly used type-codes with some explanations: 67 | 68 | * `epiN` - packed N bit integer; the register is split into lanes of size N bits 69 | * `piN` - packed N bit integer; old spelling for `epiN` 70 | * `epuN` - packed N bit unsigned; the register is split into lanes of size N bits 71 | * `ps/pd` - packed single or double; the register is split into 32/64 bit IEEE754 floating point values 72 | * `siN` - scalar N bit integer; only operates on the lower N bits 73 | * `ss/sd` - scalar single or double; only operates on the lower 32/64 bits 74 | * `f32/f64` - float or double; usually used to convert to an actual `float` in the host language 75 | 76 | #### How can I debug SIMD code? 77 | The Burst implementation for SIMD intrinsics comes with a full Mono implementation of all intrinsics. Disabling Burst compilation for the function in question allows you to step through it and inspect the contents of your registers and see how the SIMD intrinsics operate on them. 78 | 79 | #### Why does SSE code look different when compiled with `AVX` support? What does the `v` prefix mean that I see on some SSE opcodes in the Burst inspector? 80 | Depending on your platform, Burst will select a different set of instructions to compile your code with. The machine you are working on most likely has support for `AVX`, which extends the 128bit `XMM` registers introduced with `SSE` to 256bit `YMM` registers. Unfortunately, the old `SSE` instructions only operate on the lower 128bit of any register and the processor has to do some internal book-keeping to make sure that the `YMM` registers maintain their proper state. This leads to delays when switching between `AVX` instructions and `SSE` instructions. To avoid these delays, `AVX` introduces new versions of all `SSE` opcodes that use the new `VEX` prefix, denoted by an additional `v` in the mnemonic of the instruction. Hence `SSE` intrinsics produce different code when `AVX` is enabled. See section 2.8, Programming Considerations with 128-bit SIMD instructions in [Intel's AVX manual](https://software.intel.com/sites/default/files/4f/5b/36945) for more information. 81 | --------------------------------------------------------------------------------