No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AccelStructTests.cs 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. using NUnit.Framework;
  2. using System;
  3. using UnityEditor;
  4. using System.Runtime.InteropServices;
  5. using Unity.Mathematics;
  6. using Unity.Collections.LowLevel.Unsafe;
  7. namespace UnityEngine.Rendering.UnifiedRayTracing.Tests
  8. {
  9. internal static class MeshUtil
  10. {
  11. static internal Mesh CreateSingleTriangleMesh(float2 scaling, float3 translation)
  12. {
  13. Mesh mesh = new Mesh();
  14. Vector3[] vertices = new Vector3[]
  15. {
  16. (Vector3)translation + new Vector3(0.0f, 0.0f, 0),
  17. (Vector3)translation + new Vector3(1.0f * scaling.x, 0.0f, 0),
  18. (Vector3)translation + new Vector3(0.0f, 1.0f * scaling.y, 0)
  19. };
  20. mesh.vertices = vertices;
  21. Vector3[] normals = new Vector3[]
  22. {
  23. -Vector3.forward,
  24. -Vector3.forward,
  25. -Vector3.forward
  26. };
  27. mesh.normals = normals;
  28. Vector2[] uv = new Vector2[]
  29. {
  30. new Vector2(0, 1),
  31. new Vector2(1, 1),
  32. new Vector2(0, 0)
  33. };
  34. mesh.uv = uv;
  35. int[] tris = new int[3]
  36. {
  37. 0, 2, 1
  38. };
  39. mesh.triangles = tris;
  40. return mesh;
  41. }
  42. static internal Mesh CreateQuadMesh()
  43. {
  44. Mesh mesh = new Mesh();
  45. Vector3[] vertices = new Vector3[]
  46. {
  47. new Vector3(-0.5f, -0.5f, 0.0f),
  48. new Vector3(0.5f, -0.5f, 0.0f),
  49. new Vector3(-0.5f, 0.5f, 0.0f),
  50. new Vector3(0.5f, 0.5f, 0.0f)
  51. };
  52. mesh.vertices = vertices;
  53. Vector3[] normals = new Vector3[]
  54. {
  55. -Vector3.forward,
  56. -Vector3.forward,
  57. -Vector3.forward,
  58. -Vector3.forward
  59. };
  60. mesh.normals = normals;
  61. Vector2[] uv = new Vector2[]
  62. {
  63. new Vector2(0, 0),
  64. new Vector2(1, 0),
  65. new Vector2(0, 1),
  66. new Vector2(1, 1)
  67. };
  68. mesh.uv = uv;
  69. int[] tris = new int[6]
  70. {
  71. 0, 2, 1,
  72. 2, 3, 1
  73. };
  74. mesh.triangles = tris;
  75. return mesh;
  76. }
  77. }
  78. public class ComputeRayTracingAccelStructTests
  79. {
  80. [StructLayout(LayoutKind.Sequential)]
  81. internal struct BvhNode
  82. {
  83. public uint child0;
  84. public uint child1;
  85. public uint parent;
  86. public uint update;
  87. public float3 aabb0_min;
  88. public float3 aabb0_max;
  89. public float3 aabb1_min;
  90. public float3 aabb1_max;
  91. }
  92. [StructLayout(LayoutKind.Sequential)]
  93. internal struct BvhHeader
  94. {
  95. public uint totalNodeCount;
  96. public uint leafNodeCount;
  97. public uint root;
  98. public uint unused;
  99. public float3 aabb_min;
  100. public float3 aabb_max;
  101. public uint3 unused1;
  102. public uint3 unused2;
  103. }
  104. static private void AssertFloat3sAreEqual(float3 expected, float3 actual, float tolerance)
  105. {
  106. Assert.AreEqual(expected.x, actual.x, tolerance);
  107. Assert.AreEqual(expected.y, actual.y, tolerance);
  108. Assert.AreEqual(expected.z, actual.z, tolerance);
  109. }
  110. static private void AssertAABBsAreEqual(float3 expectedMin, float3 expectedMax, float3 actualMin, float3 actualMax, float tolerance)
  111. {
  112. AssertFloat3sAreEqual(expectedMin, actualMin, tolerance);
  113. AssertFloat3sAreEqual(expectedMax, actualMax, tolerance);
  114. }
  115. [Test]
  116. public void Build_TwoInstancesOfASingleTriangleMesh_ShouldGenerateCorrectResult()
  117. {
  118. var resources = new RayTracingResources();
  119. resources.Load();
  120. var MB = 1024 * 1024;
  121. var geoPoolDesc = new GeometryPoolDesc()
  122. {
  123. vertexPoolByteSize = MB,
  124. indexPoolByteSize = MB,
  125. meshChunkTablesByteSize = MB
  126. };
  127. using var accelStruct = new ComputeRayTracingAccelStruct(
  128. new AccelerationStructureOptions() { buildFlags = BuildFlags.PreferFastBuild },
  129. resources,
  130. new ReferenceCounter());
  131. uint instanceCount = 2;
  132. {
  133. var mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.0f, 1.0f), float3.zero);
  134. var globalTranslation = new float3(1.0f, 1.0f, 0.0f);
  135. for (uint i = 0; i < instanceCount; i++)
  136. {
  137. var instanceDesc = new MeshInstanceDesc(mesh);
  138. instanceDesc.localToWorldMatrix = Matrix4x4.Translate(globalTranslation + new float3(2.0f * i, 0.0f, 0.0f));
  139. accelStruct.AddInstance(instanceDesc);
  140. }
  141. using var scratchBuffer = RayTracingHelper.CreateScratchBufferForBuild(accelStruct);
  142. using var cmd = new CommandBuffer();
  143. accelStruct.Build(cmd, scratchBuffer);
  144. Graphics.ExecuteCommandBuffer(cmd);
  145. Object.DestroyImmediate(mesh);
  146. }
  147. var tolerance = 0.001f;
  148. {
  149. // Verify bottom level BVH.
  150. uint expectedTotalNodeCount = 1;
  151. var bottomLevelNodes = new BvhNode[(int)expectedTotalNodeCount + 1]; // plus one for header
  152. accelStruct.bottomLevelBvhBuffer.GetData(bottomLevelNodes);
  153. var header = UnsafeUtility.As<BvhNode, BvhHeader>(ref bottomLevelNodes[0]);
  154. Assert.AreEqual(expectedTotalNodeCount, header.totalNodeCount);
  155. Assert.AreEqual(1, header.leafNodeCount);
  156. Assert.AreEqual(expectedTotalNodeCount, header.totalNodeCount);
  157. AssertAABBsAreEqual(new float3(0.0f, 0.0f, 0.0f), new float3(1.0f, 1.0f, 0.0f), header.aabb_min, header.aabb_max, tolerance);
  158. }
  159. {
  160. // Verify top level BVH.
  161. uint expectedTotalNodeCount = 2 * instanceCount - 1;
  162. var topLevelNodes = new BvhNode[(int)expectedTotalNodeCount + 1]; // plus one for header
  163. accelStruct.topLevelBvhBuffer.GetData(topLevelNodes);
  164. var header = UnsafeUtility.As<BvhNode, BvhHeader>(ref topLevelNodes[0]);
  165. Assert.AreEqual(expectedTotalNodeCount, header.totalNodeCount);
  166. Assert.AreEqual(instanceCount, header.leafNodeCount);
  167. Assert.AreEqual(expectedTotalNodeCount, header.totalNodeCount);
  168. AssertAABBsAreEqual(new float3(1.0f, 1.0f, 0.0f), new float3(4.0f, 2.0f, 0.0f), header.aabb_min, header.aabb_max, tolerance);
  169. var instanceBvhRoot = topLevelNodes[1];
  170. Assert.AreEqual(1, instanceBvhRoot.child0);
  171. Assert.AreEqual(2, instanceBvhRoot.child1);
  172. AssertAABBsAreEqual(new float3(1.0f, 1.0f, 0.0f), new float3(2.0f, 2.0f, 0.0f), instanceBvhRoot.aabb0_min, instanceBvhRoot.aabb0_max, tolerance);
  173. AssertAABBsAreEqual(new float3(3.0f, 1.0f, 0.0f), new float3(4.0f, 2.0f, 0.0f), instanceBvhRoot.aabb1_min, instanceBvhRoot.aabb1_max, tolerance);
  174. var leftChild = topLevelNodes[2];
  175. Assert.AreEqual(0, leftChild.parent);
  176. var rightChild = topLevelNodes[3];
  177. Assert.AreEqual(0, leftChild.parent);
  178. }
  179. }
  180. }
  181. [TestFixture("Compute")]
  182. [TestFixture("Hardware")]
  183. public class AccelStructTests
  184. {
  185. RayTracingBackend m_Backend;
  186. RayTracingContext m_Context;
  187. RayTracingResources m_Resources;
  188. IRayTracingAccelStruct m_AccelStruct;
  189. IRayTracingShader m_Shader;
  190. public AccelStructTests(string backendAsString)
  191. {
  192. m_Backend = Enum.Parse<RayTracingBackend>(backendAsString);
  193. }
  194. [SetUp]
  195. public void SetUp()
  196. {
  197. if (!SystemInfo.supportsRayTracing && m_Backend == RayTracingBackend.Hardware)
  198. {
  199. Assert.Ignore("Cannot run test on this Graphics API. Hardware RayTracing is not supported");
  200. }
  201. if (!SystemInfo.supportsComputeShaders && m_Backend == RayTracingBackend.Compute)
  202. {
  203. Assert.Ignore("Cannot run test on this Graphics API. Compute shaders are not supported");
  204. }
  205. if (SystemInfo.graphicsDeviceName.Contains("llvmpipe"))
  206. {
  207. Assert.Ignore("Cannot run test on this device (Renderer: llvmpipe (LLVM 10.0.0, 128 bits)). Tests are disabled because they fail on some platforms (that do not support 11 SSBOs). Once we do not run Ubuntu 18.04 try removing this");
  208. }
  209. CreateRayTracingResources();
  210. }
  211. [TearDown]
  212. public void TearDown()
  213. {
  214. DisposeRayTracingResources();
  215. }
  216. [Test]
  217. public void RayTracePixelsInUnitQuad([Values(1, 10, 100)] int rayResolution, [Values(0, 1, 2, 3)] int buildFlagsAsInteger)
  218. {
  219. var buildFlags = (BuildFlags)buildFlagsAsInteger; // We do this ugly but simple cast hack because the BuildFlags type is not public as time of this writing (test methods must be public and so must their argument types).
  220. // re-create the acceleration structure with suitable options
  221. m_AccelStruct?.Dispose();
  222. var options = new AccelerationStructureOptions() { buildFlags = buildFlags };
  223. m_AccelStruct = m_Context.CreateAccelerationStructure(options);
  224. Mesh mesh = MeshUtil.CreateQuadMesh();
  225. var instanceDesc = new MeshInstanceDesc();
  226. instanceDesc = new MeshInstanceDesc(mesh);
  227. instanceDesc.localToWorldMatrix = Matrix4x4.identity;
  228. instanceDesc.localToWorldMatrix.SetTRS(new Vector3(0.5f, 0.5f, 0.0f), Quaternion.identity, new Vector3(1.0f, 1.0f, 1.0f));
  229. instanceDesc.enableTriangleCulling = false;
  230. instanceDesc.frontTriangleCounterClockwise = true;
  231. m_AccelStruct.AddInstance(instanceDesc);
  232. // trace N*N rays towards the quad and expect to hit it
  233. int N = rayResolution;
  234. var rays = new RayWithFlags[N*N];
  235. int rayI = 0;
  236. for (int v = 0; v < N; ++v)
  237. {
  238. for (int u = 0; u < N; ++u)
  239. {
  240. float2 uv = new float2((float)u, (float)v);
  241. uv += 0.5f;
  242. uv /= N;
  243. float3 origin = new float3(uv.x, uv.y, 1.0f);
  244. float3 direction = new float3(0.0f, 0.0f, -1.0f);
  245. rays[rayI] = new RayWithFlags(origin, direction);
  246. rays[rayI].culling = (uint)RayCulling.None;
  247. rayI++;
  248. }
  249. }
  250. HitGeomAttributes[] hitAttributes = null;
  251. var hits = TraceRays(rays, out hitAttributes);
  252. for (int i = 0; i < hits.Length; ++i)
  253. {
  254. Assert.IsTrue(hits[i].Valid(), $"Expected all rays to hit the quad but ray {i} missed.");
  255. }
  256. }
  257. [Test]
  258. public void FrontOrBackFaceCulling()
  259. {
  260. const int instanceCount = 4;
  261. Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f));
  262. CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs);
  263. var raysDuplicated = new RayWithFlags[instanceCount * 3];
  264. Array.Copy(rays, 0, raysDuplicated, 0, instanceCount);
  265. Array.Copy(rays, 0, raysDuplicated, instanceCount, instanceCount);
  266. Array.Copy(rays, 0, raysDuplicated, 2* instanceCount, instanceCount);
  267. for (int i = 0; i < instanceCount; ++i)
  268. {
  269. raysDuplicated[i].culling = (uint)RayCulling.None;
  270. raysDuplicated[i + instanceCount].culling = (uint)RayCulling.CullFrontFace;
  271. raysDuplicated[i + instanceCount * 2].culling = (uint)RayCulling.CullBackFace;
  272. }
  273. instanceDescs[0].enableTriangleCulling = false;
  274. instanceDescs[0].frontTriangleCounterClockwise = true;
  275. instanceDescs[1].enableTriangleCulling = false;
  276. instanceDescs[1].frontTriangleCounterClockwise = false;
  277. instanceDescs[2].enableTriangleCulling = true;
  278. instanceDescs[2].frontTriangleCounterClockwise = true;
  279. instanceDescs[3].enableTriangleCulling = true;
  280. instanceDescs[3].frontTriangleCounterClockwise = false;
  281. for (int i = 0; i < instanceCount; ++i)
  282. {
  283. m_AccelStruct.AddInstance(instanceDescs[i]);
  284. }
  285. HitGeomAttributes[] hitAttributes = null;
  286. var hits = TraceRays(raysDuplicated, out hitAttributes);
  287. // No culling
  288. Assert.IsTrue(hits[0].Valid());
  289. Assert.IsTrue(hits[1].Valid());
  290. Assert.IsTrue(hits[2].Valid());
  291. Assert.IsTrue(hits[3].Valid());
  292. // FrontFace culling
  293. Assert.IsTrue(hits[4].Valid());
  294. Assert.IsTrue(hits[5].Valid());
  295. Assert.IsTrue(hits[6].Valid());
  296. Assert.IsTrue(!hits[7].Valid());
  297. // BackFace culling
  298. Assert.IsTrue(hits[8].Valid());
  299. Assert.IsTrue(hits[9].Valid());
  300. Assert.IsTrue(!hits[10].Valid());
  301. Assert.IsTrue(hits[11].Valid());
  302. }
  303. [Test]
  304. public void InstanceAndRayMask()
  305. {
  306. const int instanceCount = 8;
  307. Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f));
  308. CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs);
  309. var rayAndInstanceMasks = new (uint instanceMask, uint rayMask)[]
  310. {
  311. (0, 0),
  312. (0xFFFFFFFF, 0xFFFFFFFF),
  313. (0, 0xFFFFFFFF),
  314. (0xFFFFFFFF, 0),
  315. (0x0F, 0x01),
  316. (0x0F, 0xF0),
  317. (0x90, 0xF0),
  318. (0xF0, 0x10),
  319. };
  320. for (int i = 0; i < instanceCount; ++i)
  321. {
  322. instanceDescs[i].mask = rayAndInstanceMasks[i].instanceMask;
  323. rays[i].instanceMask = rayAndInstanceMasks[i].rayMask;
  324. }
  325. for (int i = 0; i < instanceCount; ++i)
  326. {
  327. m_AccelStruct.AddInstance(instanceDescs[i]);
  328. }
  329. HitGeomAttributes[] hitAttributes = null;
  330. var hits = TraceRays(rays, out hitAttributes);
  331. for (int i = 0; i < instanceCount; ++i)
  332. {
  333. bool rayShouldHit = ((rayAndInstanceMasks[i].instanceMask & rayAndInstanceMasks[i].rayMask) != 0);
  334. bool rayHit = hits[i].Valid();
  335. var message = String.Format("Ray {0} hit for InstanceMask: 0x{1:X} & RayMask: 0x{2:X}",
  336. rayShouldHit ? "should" : "shouldn't",
  337. rayAndInstanceMasks[i].instanceMask,
  338. rayAndInstanceMasks[i].rayMask);
  339. Assert.AreEqual(rayShouldHit, rayHit, message);
  340. }
  341. }
  342. [Test]
  343. public void AddAndRemoveInstances()
  344. {
  345. const int instanceCount = 4;
  346. Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f));
  347. CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs);
  348. var instanceHandles = new int[instanceCount];
  349. var expectedVisibleInstances = new bool[instanceCount];
  350. for (int i = 0; i < instanceCount; ++i)
  351. {
  352. instanceHandles[i] = m_AccelStruct.AddInstance(instanceDescs[i]);
  353. expectedVisibleInstances[i] = true;
  354. }
  355. CheckVisibleInstances(rays, expectedVisibleInstances);
  356. m_AccelStruct.RemoveInstance(instanceHandles[0]); expectedVisibleInstances[0] = false;
  357. m_AccelStruct.RemoveInstance(instanceHandles[2]); expectedVisibleInstances[2] = false;
  358. CheckVisibleInstances(rays, expectedVisibleInstances);
  359. m_AccelStruct.ClearInstances();
  360. Array.Fill(expectedVisibleInstances, false);
  361. CheckVisibleInstances(rays, expectedVisibleInstances);
  362. m_AccelStruct.AddInstance(instanceDescs[3]);
  363. expectedVisibleInstances[3] = true;
  364. CheckVisibleInstances(rays, expectedVisibleInstances);
  365. }
  366. private void AddTerrainToAccelerationStructure(int heightmapResolution)
  367. {
  368. Terrain.CreateTerrainGameObject(new TerrainData());
  369. Terrain terrain = GameObject.FindFirstObjectByType<Terrain>();
  370. Assert.NotNull(terrain);
  371. // Set terrain texture resolution on terrain data.
  372. terrain.terrainData.heightmapResolution = heightmapResolution;
  373. // Convert to mesh.
  374. AsyncTerrainToMeshRequest request = TerrainToMesh.ConvertAsync(terrain);
  375. request.WaitForCompletion();
  376. // Add the terrain to the acceleration structure.
  377. MeshInstanceDesc instanceDesc = new MeshInstanceDesc(request.GetMesh());
  378. instanceDesc.localToWorldMatrix = float4x4.identity;
  379. m_AccelStruct.AddInstance(instanceDesc);
  380. }
  381. [Test]
  382. public void Add_1KTerrain_Works()
  383. {
  384. AddTerrainToAccelerationStructure(1025);
  385. }
  386. [Test]
  387. [Ignore("This test is disabled because of the allocation limitation of 2 GB in GraphicsBuffer.")]
  388. public void Add_4KTerrain_Works()
  389. {
  390. AddTerrainToAccelerationStructure(4097);
  391. }
  392. void CheckVisibleInstances(RayWithFlags[] rays, bool[] expectedVisibleInstances)
  393. {
  394. HitGeomAttributes[] hitAttributes = null;
  395. var hits = TraceRays(rays, out hitAttributes);
  396. for (int i = 0; i < rays.Length; ++i)
  397. {
  398. Assert.AreEqual(expectedVisibleInstances[i], hits[i].Valid(), $"Unexpected state of intersection with instance {i}");
  399. }
  400. }
  401. void CreateMatchingRaysAndInstanceDescs(uint instanceCount, Mesh mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs)
  402. {
  403. instanceDescs = new MeshInstanceDesc[instanceCount];
  404. rays = new RayWithFlags[instanceCount];
  405. var ray = new RayWithFlags(new float3(0.0f, 0.0f, 1.0f), new float3(0.0f, 0.0f, -1.0f));
  406. float3 step = new float3(2.0f, 0.0f, 0.0f);
  407. for (int i = 0; i < instanceCount; ++i)
  408. {
  409. instanceDescs[i] = new MeshInstanceDesc(mesh);
  410. instanceDescs[i].localToWorldMatrix = float4x4.Translate(step * i);
  411. rays[i] = ray;
  412. rays[i].origin += step * i;
  413. }
  414. }
  415. Hit[] TraceRays(RayWithFlags[] rays, out HitGeomAttributes[] hitAttributes)
  416. {
  417. var bufferTarget = GraphicsBuffer.Target.Structured;
  418. var rayCount = rays.Length;
  419. using var raysBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf<RayWithFlags>());
  420. raysBuffer.SetData(rays);
  421. using var hitsBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf<Hit>());
  422. using var attributesBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf<HitGeomAttributes>());
  423. using var scratchBuffer = RayTracingHelper.CreateScratchBufferForBuildAndDispatch(m_AccelStruct, m_Shader, (uint)rayCount, 1, 1);
  424. var cmd = new CommandBuffer();
  425. m_AccelStruct.Build(cmd, scratchBuffer);
  426. m_Shader.SetAccelerationStructure(cmd, "_AccelStruct", m_AccelStruct);
  427. m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_Rays"), raysBuffer);
  428. m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_Hits"), hitsBuffer);
  429. m_Shader.Dispatch(cmd, scratchBuffer, (uint)rayCount, 1, 1);
  430. Graphics.ExecuteCommandBuffer(cmd);
  431. var hits = new Hit[rayCount];
  432. hitsBuffer.GetData(hits);
  433. hitAttributes = new HitGeomAttributes[rayCount];
  434. attributesBuffer.GetData(hitAttributes);
  435. return hits;
  436. }
  437. void CreateRayTracingResources()
  438. {
  439. m_Resources = new RayTracingResources();
  440. m_Resources.Load();
  441. m_Context = new RayTracingContext(m_Backend, m_Resources);
  442. m_AccelStruct = m_Context.CreateAccelerationStructure(new AccelerationStructureOptions());
  443. Type type = BackendHelpers.GetTypeOfShader(m_Backend);
  444. string filename = BackendHelpers.GetFileNameOfShader(m_Backend, $"Tests/Editor/UnifiedRayTracing/TraceRays");
  445. Object shader = AssetDatabase.LoadAssetAtPath($"Packages/com.unity.rendering.light-transport/{filename}", type);
  446. m_Shader = m_Context.CreateRayTracingShader(shader);
  447. }
  448. void DisposeRayTracingResources()
  449. {
  450. m_AccelStruct?.Dispose();
  451. m_Context?.Dispose();
  452. }
  453. [StructLayout(LayoutKind.Sequential)]
  454. public struct RayWithFlags
  455. {
  456. public float3 origin;
  457. public float minT;
  458. public float3 direction;
  459. public float maxT;
  460. public uint culling;
  461. public uint instanceMask;
  462. uint padding;
  463. uint padding2;
  464. public RayWithFlags(float3 origin, float3 direction)
  465. {
  466. this.origin = origin;
  467. this.direction = direction;
  468. minT = 0.0f;
  469. maxT = float.MaxValue;
  470. instanceMask = 0xFFFFFFFF;
  471. culling = 0;
  472. padding = 0;
  473. padding2 = 0;
  474. }
  475. }
  476. [System.Flags]
  477. enum RayCulling { None = 0, CullFrontFace = 0x10, CullBackFace = 0x20 }
  478. [StructLayout(LayoutKind.Sequential)]
  479. public struct Hit
  480. {
  481. public uint instanceID;
  482. public uint primitiveIndex;
  483. public float2 uvBarycentrics;
  484. public float hitDistance;
  485. public uint isFrontFace;
  486. public bool Valid() { return instanceID != 0xFFFFFFFF; }
  487. }
  488. [StructLayout(LayoutKind.Sequential)]
  489. public struct HitGeomAttributes
  490. {
  491. public float3 position;
  492. public float3 normal;
  493. public float3 faceNormal;
  494. public float4 uv0;
  495. public float4 uv1;
  496. }
  497. }
  498. }