private void ParseGeometry( GameObject[] roots, ref SceneParseResult sceneParseResult) { var renderers = GetAllRenderers(roots); if (!IsAllGeometriesDirty(renderers) && sceneParseResult.Primitives.Count != 0) { // All the geometries are unchange, no need to rebuild return; } // TODO: Optimize dynamic array generation sceneParseResult.ClearAllPrimitives(); sceneParseResult.ClearAllGeometries(); sceneParseResult.ClearAllMaterials(); sceneParseResult.ClearTopLevelBVH(); foreach (var renderer in renderers) { if (renderer.gameObject.activeInHierarchy) { RTMaterial material = renderer.material; if (renderer.geometry == null || !renderer.geometry.IsGeometryValid() || material == null) { continue; } var closestShaderGUID = renderer.material.GetClosestHitGUID(); int closestShaderIndex = CustomShaderDatabase.Instance.GUIDToShaderIndex(closestShaderGUID, EShaderType.ClosestHit); var intersectShaderGUID = renderer.geometry.GetIntersectShaderGUID(); int intersectShaderIndex = CustomShaderDatabase.Instance.GUIDToShaderIndex(intersectShaderGUID, EShaderType.Intersect); if (!sceneParseResult.GeometryStride.ContainsKey(intersectShaderIndex)) { sceneParseResult.GeometryStride.Add(intersectShaderIndex, renderer.geometry.IsAccelerationStructure() ? 0 : renderer.geometry.GetStride()); } if (renderer.geometry.IsAccelerationStructure()) { // Such as Low-Level BVH (RTMeshBVH) int mapOffset = sceneParseResult.ObjectLevelAccGeoMapCursor(intersectShaderIndex); int geoOffset = sceneParseResult.ObjectLevelAccGeoCursor(intersectShaderIndex); ((IRTMeshBVH)(renderer.geometry)).BuildBVHAndTriangleList(geoLocalToGlobalIndexOffset: geoOffset, mappingLocalToGlobalIndexOffset: mapOffset); List <float> geoInsData = renderer.geometry.GetGeometryInstanceData(geoLocalToGlobalIndexOffset: geoOffset, mappingLocalToGlobalIndexOffset: mapOffset); sceneParseResult.AddAccelerationStructureGeometry( accelerationStructureData: geoInsData, accelGeometryMapping: renderer.geometry.GetAccelerationStructureGeometryMapping(geoLocalToGlobalIndexOffset: geoOffset, mappingLocalToGlobalIndexOffset: mapOffset), accelGeometryData: renderer.geometry.GetAccelerationStructureGeometryData(geoLocalToGlobalIndexOffset: geoOffset, mappingLocalToGlobalIndexOffset: mapOffset), intersectIndex: intersectShaderIndex ); } else { // Standardized Geometry (Sphere, Triangle) List <float> geoInsData = renderer.geometry.GetGeometryInstanceData(geoLocalToGlobalIndexOffset: 0, mappingLocalToGlobalIndexOffset: 0); // No offset sceneParseResult.AddGeometryData( geometryData: geoInsData, intersectIndex: intersectShaderIndex ); } int startIndex = sceneParseResult.AddGeometryCount( count: renderer.geometry.GetCount(), intersectIndex: intersectShaderIndex ); int materialInstanceIndex = sceneParseResult.AddMaterial(material); sceneParseResult.AddWorldToPrimitive(renderer.gameObject.transform.worldToLocalMatrix); sceneParseResult.AddPrimitive(new Primitive( geometryIndex: intersectShaderIndex, geometryInstanceBegin: startIndex, geometryInstanceCount: renderer.geometry.GetCount(), materialIndex: closestShaderIndex, materialInstanceIndex: materialInstanceIndex, transformIndex: sceneParseResult.WorldToPrimitive.Count - 1 )); var boxOfThisObject = renderer.geometry.GetTopLevelBoundingBox(assginedPrimitiveId: sceneParseResult.Primitives.Count - 1); sceneParseResult.AddBoundingBox(boxOfThisObject); } } }