Ejemplo n.º 1
0
        private void ParseGeometry(
            GameObject[] roots,
            ref SceneParseResult sceneParseResult)
        {
            // TODO: Optimize dynamic array generation
            sceneParseResult.ClearAllPrimitives();
            sceneParseResult.ClearAllGeometries();
            sceneParseResult.ClearAllMaterials();
            sceneParseResult.ClearTopLevelBVH();

            foreach (var root in roots)
            {
                RTRenderer[] renderers = root.GetComponentsInChildren <RTRenderer>();

                foreach (var renderer in renderers)
                {
                    if (renderer.gameObject.activeSelf)
                    {
                        List <float> geoInsData           = renderer.geometry.GetGeometryInstanceData();
                        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);

                        RTMaterial material = renderer.material;

                        if (geoInsData == null || material == null)
                        {
                            continue;
                        }

                        if (!sceneParseResult.GeometryStride.ContainsKey(intersectShaderIndex))
                        {
                            sceneParseResult.GeometryStride.Add(intersectShaderIndex, renderer.geometry.GetStride());
                        }

                        sceneParseResult.AddGeometryData(
                            geometryData: geoInsData,
                            intersectIndex: intersectShaderIndex
                            );

                        int startIndex = sceneParseResult.AddGeometryCount(
                            count: renderer.geometry.GetCount(),
                            intersectIndex: intersectShaderIndex
                            );

                        sceneParseResult.AddWorldToPrimitive(renderer.gameObject.transform.worldToLocalMatrix);

                        sceneParseResult.AddPrimitive(new Primitive(
                                                          geometryIndex: intersectShaderIndex,
                                                          geometryInstanceBegin: startIndex,
                                                          geometryInstanceCount: renderer.geometry.GetCount(),
                                                          materialIndex: closestShaderIndex,
                                                          transformIndex: sceneParseResult.WorldToPrimitive.Count - 1
                                                          ));

                        var boxOfThisObject = renderer.geometry.GetBoundingBox();
                        sceneParseResult.AddBoundingBox(new RTBoundingBox(
                                                            max: boxOfThisObject.max,
                                                            min: boxOfThisObject.min,
                                                            primitive: sceneParseResult.Primitives.Count - 1
                                                            ));

                        sceneParseResult.AddMaterial(material);
                    }
                }
            }
        }
        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);
                }
            }
        }