Esempio n. 1
0
        public static Texture2D GenerateBillboardNormalTexture(GameObject prefab, BillboardQuality billboardQuality,
                                                               LODLevel billboardSourceLODLevel, Quaternion rotationOffset, string overrideBillboardAtlasNormalShader, bool recalculateNormals, float normalBlendFactor, bool flipBackNormals)
        {
            Shader normalShader = BillboardShaderDetector.GetNormalBillboardAtlasShader(prefab);

            if (overrideBillboardAtlasNormalShader != "")
            {
                normalShader = Shader.Find(overrideBillboardAtlasNormalShader);
            }

            if (flipBackNormals)
            {
                Shader.SetGlobalInt("_FlipBackNormals", 1);
            }
            else
            {
                Shader.SetGlobalInt("_FlipBackNormals", 0);
            }

            Material  minPostfilter = (Material)Resources.Load("MinPostFilter/MinPostFilter", typeof(Material));
            Texture2D texture       = GenerateBillboardNew(prefab, GetBillboardQualityTileWidth(billboardQuality),
                                                           GetBillboardQualityTileWidth(billboardQuality), GetBillboardQualityColumnCount(billboardQuality),
                                                           GetBillboardQualityRowCount(billboardQuality), normalShader, new Color(0.5f, 0.5f, 1, 0), minPostfilter,
                                                           billboardSourceLODLevel, rotationOffset, false, recalculateNormals, normalBlendFactor);

            Shader.SetGlobalInt("_FlipBackNormals", 0);
            return(texture);
        }
Esempio n. 2
0
        public static Texture2D GenerateBillboardTexture(GameObject prefab, BillboardQuality billboardQuality,
                                                         LODLevel billboardSourceLODLevel, VegetationShaderType vegetationShaderType, Quaternion rotationOffset,
                                                         Color backgroundColor, string overrideBillboardAtlasShader, bool recalculateNormals, float normalBlendFactor)
        {
            Shader diffuseShader = BillboardShaderDetector.GetDiffuceBillboardAtlasShader(prefab);

            if (overrideBillboardAtlasShader != "")
            {
                diffuseShader = Shader.Find(overrideBillboardAtlasShader);
            }

            //if (vegetationShaderType == VegetationShaderType.Speedtree)
            //{

            //    diffuseShader = Shader.Find("AwesomeTechnologies/Billboards/RenderDiffuseAtlas");
            //}
            //else
            //{
            //    diffuseShader = Shader.Find("AwesomeTechnologies/Billboards/RenderDiffuseAtlasBright");
            //}

            Material  minPostfilter = (Material)Resources.Load("MinPostFilter/MinPostFilter", typeof(Material));
            Texture2D texture       = GenerateBillboardNew(prefab, GetBillboardQualityTileWidth(billboardQuality),
                                                           GetBillboardQualityTileWidth(billboardQuality), GetBillboardQualityColumnCount(billboardQuality),
                                                           GetBillboardQualityRowCount(billboardQuality), diffuseShader, backgroundColor, minPostfilter,
                                                           billboardSourceLODLevel, rotationOffset, false, recalculateNormals, normalBlendFactor);

            return(texture);
        }
Esempio n. 3
0
 public LODParent(int lodCount)
 {
     lodLevels = new LODLevel[lodCount];
     for (int i = 0; i < lodLevels.Length; i++)
     {
         lodLevels[i] = new LODLevel();
     }
 }
Esempio n. 4
0
            void AddObjectInternal(MeshCombiner meshCombiner, CachedGameObject cachedGO, Vector3 position, int lodParentIndex, int lodLevel, bool isChangeMode)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;

                    if (thisCell.lodParents == null)
                    {
                        thisCell.lodParents = new LODParent[10];
                    }
                    if (thisCell.lodParents[lodParentIndex] == null)
                    {
                        thisCell.lodParents[lodParentIndex] = new LODParent(lodParentIndex + 1);
                    }

                    LODParent lodParent = thisCell.lodParents[lodParentIndex];
                    LODLevel  lod       = lodParent.lodLevels[lodLevel];

                    lod.cachedGOs.Add(cachedGO);
                    if (isChangeMode)
                    {
                        if (SortObject(meshCombiner, lod, cachedGO))
                        {
                            if (!thisCell.hasChanged)
                            {
                                thisCell.hasChanged = true;
                                if (meshCombiner.changedCells == null)
                                {
                                    meshCombiner.changedCells = new List <MaxCell>();
                                }
                                meshCombiner.changedCells.Add(thisCell);
                            }
                            if (!lodParent.hasChanged)
                            {
                                lodParent.hasChanged = true;
                                thisCell.changedLodParents.Add(lodParent);
                            }
                        }
                    }

                    lod.objectCount++;

                    lod.vertCount += cachedGO.mesh.vertexCount;
                    return;
                }
                else
                {
                    bool maxCellCreated;
                    int  index = AddCell <Cell, MaxCell>(ref cells, position, out maxCellCreated);
                    if (maxCellCreated)
                    {
                        MaxCell.maxCellCount++;
                    }
                    cells[index].AddObjectInternal(meshCombiner, cachedGO, position, lodParentIndex, lodLevel, isChangeMode);
                }
            }
Esempio n. 5
0
        public static Texture2D GenerateBillboardAOTexture(GameObject prefab, BillboardQuality billboardQuality,
                                                           LODLevel billboardSourceLODLevel, Quaternion rotationOffset, bool recalculateNormals, float normalBlendFactor)
        {
            Shader    normalShader  = Shader.Find("AwesomeTechnologies/Billboards/AOBackground");
            Material  minPostfilter = (Material)Resources.Load("MinPostFilter/MinPostFilter", typeof(Material));
            Texture2D texture       = GenerateBillboardNew(prefab, GetBillboardQualityTileWidth(billboardQuality),
                                                           GetBillboardQualityTileWidth(billboardQuality), GetBillboardQualityColumnCount(billboardQuality),
                                                           GetBillboardQualityRowCount(billboardQuality), normalShader, new Color(0.5f, 0.5f, 1, 0), minPostfilter,
                                                           billboardSourceLODLevel, rotationOffset, true, recalculateNormals, normalBlendFactor);

            return(texture);
        }
Esempio n. 6
0
        public static Quaternion GetMeshRotation(GameObject go, LODLevel lodLevel)
        {
            GameObject meshGameObject = SelectMeshObject(go, lodLevel);

            if (meshGameObject)
            {
                return(Quaternion.Inverse(Quaternion.identity) * meshGameObject.transform.rotation);
            }
            else
            {
                return(Quaternion.identity);
            }
        }
Esempio n. 7
0
            public bool SortObject(MeshCombiner meshCombiner, LODLevel lod, CachedGameObject cachedGO, bool isChangeMode = false)
            {
                if (cachedGO.mr == null)
                {
                    return(false);
                }

                if (lod.meshObjectsHolders == null)
                {
                    lod.meshObjectsHolders = new List <MeshObjectsHolder>();
                }

                Material[] mats = cachedGO.mr.sharedMaterials;

                // TODO check submeshes and material
                int length = Mathf.Min(cachedGO.mesh.subMeshCount, mats.Length);

                for (int l = 0; l < length; l++)
                {
                    Material mat = mats[l];
                    if (mat == null)
                    {
                        continue;
                    }

                    bool shadowCastingModeTwoSided = (cachedGO.mr.shadowCastingMode == UnityEngine.Rendering.ShadowCastingMode.TwoSided);
                    int  lightmapIndex             = meshCombiner.validCopyBakedLighting ? cachedGO.mr.lightmapIndex : -1;

                    int index = lod.GetSortMeshIndex(mat, shadowCastingModeTwoSided, lightmapIndex);

                    MeshObjectsHolder meshObjectHolder;
                    if (index == -1)
                    {
                        meshObjectHolder = new MeshObjectsHolder(cachedGO, mat, l, shadowCastingModeTwoSided, lightmapIndex);
                        lod.meshObjectsHolders.Add(meshObjectHolder);
                    }
                    else
                    {
                        meshObjectHolder = lod.meshObjectsHolders[index];
                        meshObjectHolder.meshObjects.Add(new MeshObject(cachedGO, l));
                    }

                    if (isChangeMode && !meshObjectHolder.hasChanged)
                    {
                        meshObjectHolder.hasChanged = true;
                        lod.changedMeshObjectsHolders.Add(meshObjectHolder);
                    }
                }

                return(true);
            }
        private static Mesh GetVegetationMesh(GameObject rootVegetationModel, LODLevel lodLevel)
        {
            GameObject selectedVegetationModel = MeshUtils.SelectMeshObject(rootVegetationModel, lodLevel);
            MeshFilter vegetationMeshFilter    = selectedVegetationModel.GetComponentInChildren <MeshFilter>();

            if (vegetationMeshFilter.sharedMesh)
            {
                return(vegetationMeshFilter.sharedMesh);
            }
            else
            {
                return(new Mesh());
            }
        }
Esempio n. 9
0
            public void AssignLODGroup(MeshCombiner meshCombiner)
            {
                LOD[] lods = new LOD[lodLevels.Length];
                int   lodGroupParentIndex = lods.Length - 1;

                for (int i = 0; i < lodLevels.Length; i++)
                {
                    LODLevel lodLevel = lodLevels[i];
                    // Debug.Log(i + " " + lodLevel.newMeshRenderers.Count);
                    lods[i] = new LOD(meshCombiner.lodGroupsSettings[lodGroupParentIndex].lodSettings[i].screenRelativeTransitionHeight, lodLevel.newMeshRenderers.ToArray());
                }

                lodGroup.SetLODs(lods);
                lodGroup.size = meshCombiner.cellSize;
            }
Esempio n. 10
0
            public void SortObjects(MeshCombiner meshCombiner)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;

                    LODParent[] lodParents = thisCell.lodParents;

                    for (int i = 0; i < lodParents.Length; i++)
                    {
                        LODParent lodParent = lodParents[i];
                        if (lodParent == null)
                        {
                            continue;
                        }

                        for (int j = 0; j < lodParent.lodLevels.Length; j++)
                        {
                            LODLevel lod = lodParent.lodLevels[j];

                            if (lod == null || lod.cachedGOs.Count == 0)
                            {
                                return;
                            }

                            for (int k = 0; k < lod.cachedGOs.Count; ++k)
                            {
                                CachedGameObject cachedGO = lod.cachedGOs.items[k];

                                if (!SortObject(meshCombiner, lod, cachedGO))
                                {
                                    lod.cachedGOs.RemoveAt(k--);
                                }
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].SortObjects(meshCombiner);
                        }
                    }
                }
            }
Esempio n. 11
0
        static GameObject SelectNormalMesh(GameObject go, LODLevel lodLevel)
        {
            LODGroup lodGroup = go.GetComponentInChildren <LODGroup>();

            if (lodGroup)
            {
                LOD[] lods = lodGroup.GetLODs();

                int lodIndex = (int)lodLevel;
                lodIndex = Mathf.Clamp(lodIndex, 0, lods.Length - 1);

                LOD lod = lods[lodIndex];
                if (lod.renderers.Length > 0)
                {
                    if (lod.renderers[0].gameObject.GetComponent <BillboardRenderer>())
                    {
                        if (lodIndex > 0)
                        {
                            lod = lods[lodIndex - 1];
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }

                return(lod.renderers.Length > 0 ? lod.renderers[0].gameObject : null);
            }
            else
            {
                var meshRenderer = go.GetComponent <MeshRenderer>();
                if (meshRenderer)
                {
                    return(meshRenderer.gameObject);
                }

                meshRenderer = go.GetComponentInChildren <MeshRenderer>();
                if (meshRenderer)
                {
                    return(meshRenderer.gameObject);
                }
                return(null);
            }
        }
Esempio n. 12
0
 public LOD(BinaryReader reader)
 {
     Type             = (LODLevel)reader.ReadUInt32();
     MaxEdgeLength    = reader.ReadSingle();
     GroupCount       = reader.ReadUInt32();
     PositionsPointer = reader.ReadUInt32();
     //if (Context.Current.Game == Context.NextGenGame.DromeRacers)
     RenderGroupsPointer = reader.ReadUInt32();
     if (PositionsPointer > 0)
     {
         Positions = new Vector3[GroupCount];
         for (int i = 0; i < GroupCount; i++)
         {
             Positions[i] = reader.ReadVector3();
         }
     }
     for (int i = 0; i < GroupCount; i++)
     {
         RenderGroups.Add(new RenderGroup(reader, true));
     }
 }
Esempio n. 13
0
    LODLevel EnableLODRenderers( LODLevel newLevel )
    {
        LODLevel retLevel = newLevel;
        currentRenderer = null;

        for ( int i = 0; i < (int)LODLevel.LODCulled; i++ )
        {
            if ( i == (int)newLevel )
            {
                if ( _renderers[i] != null )
                {
                    _renderers[i].enabled = true;
                    currentRenderer = _renderers[i];
                    if ( level == newLevel && !_renderers[i].isVisible )
                    {
                        retLevel = LODLevel.LODCulled;
                    }
                }
            }
            else
            {
                if ( _renderers[i] != null )
                {
                    _renderers[i].enabled = false;
                }
            }
        }

        return retLevel;
    }
Esempio n. 14
0
            public void CombineMeshes(MeshCombiner meshCombiner, int lodParentIndex)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;

                    LODParent lodParent = thisCell.lodParents[lodParentIndex];
                    if (lodParent == null)
                    {
                        return;
                    }

                    CombineMode combineMode = meshCombiner.combineMode;

                    if (combineMode != CombineMode.DynamicObjects)
                    {
                        lodParent.cellGO         = new GameObject(meshCombiner.combineMode == CombineMode.StaticObjects ? "Cell " + bounds.center : "Combined Objects");
                        lodParent.cellT          = lodParent.cellGO.transform;
                        lodParent.cellT.position = bounds.center;
                        lodParent.cellT.parent   = meshCombiner.lodParentHolders[lodParentIndex].t;
                    }

                    if (lodParentIndex > 0)
                    {
                        lodParent.lodGroup = lodParent.cellGO.AddComponent <LODGroup>();
                        lodParent.lodGroup.localReferencePoint = lodParent.cellT.position = bounds.center;
                    }

                    LODLevel[] lods = lodParent.lodLevels;
                    for (int i = 0; i < lods.Length; i++)
                    {
                        LODLevel lod = lodParent.lodLevels[i];
                        if (lod == null || lod.meshObjectsHoldersLookup == null)
                        {
                            return;
                        }

                        GameObject lodGO;
                        Transform  lodT = null;

                        if (lodParentIndex > 0)
                        {
                            lodGO       = new GameObject("LOD" + i);
                            lodT        = lodGO.transform;
                            lodT.parent = lodParent.cellT;
                        }

                        foreach (MeshObjectsHolder sortedMeshes in lod.meshObjectsHoldersLookup.Values)
                        {
                            sortedMeshes.lodParent = lodParent;
                            sortedMeshes.lodLevel  = i;
                            Vector3 position = (combineMode == CombineMode.DynamicObjects ? sortedMeshes.meshObjects.items[0].cachedGO.rootT.position : bounds.center);
                            MeshCombineJobManager.instance.AddJob(meshCombiner, sortedMeshes, lodParentIndex > 0 ? lodT : lodParent.cellT, position);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].CombineMeshes(meshCombiner, lodParentIndex);
                        }
                    }
                }
            }
Esempio n. 15
0
            public bool SortObject(MeshCombiner meshCombiner, LODLevel lod, CachedGameObject cachedGO, bool isChangeMode = false)
            {
                if (cachedGO.mr == null)
                {
                    return(false);
                }

                if (lod.meshObjectsHoldersLookup == null)
                {
                    lod.meshObjectsHoldersLookup = new Dictionary <CombineCondition, MeshObjectsHolder>();
                }

                CombineConditionSettings combineConditions = meshCombiner.combineConditionSettings;

                Material[] mats = cachedGO.mr.sharedMaterials;

                // TODO check submeshes and material
                int length = Mathf.Min(cachedGO.mesh.subMeshCount, mats.Length);

                int rootInstanceId = -1;

                if (meshCombiner.combineMode == CombineMode.DynamicObjects)
                {
                    rootInstanceId = cachedGO.rootInstanceId;

                    if (rootInstanceId == -1)
                    {
                        cachedGO.GetRoot();
                        rootInstanceId = cachedGO.rootInstanceId;
                    }
                }

                for (int l = 0; l < length; l++)
                {
                    Material mat;

                    if (combineConditions.sameMaterial)
                    {
                        mat = mats[l];
                        if (mat == null)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        mat = combineConditions.material;
                    }

                    CombineCondition combineCondition = new CombineCondition();
                    combineCondition.ReadFromGameObject(rootInstanceId, combineConditions, meshCombiner.copyBakedLighting && meshCombiner.validCopyBakedLighting, cachedGO.go, cachedGO.t, cachedGO.mr, mat);

                    MeshObjectsHolder meshObjectHolder;
                    if (!lod.meshObjectsHoldersLookup.TryGetValue(combineCondition, out meshObjectHolder))
                    {
                        meshCombiner.foundCombineConditions.combineConditions.Add(combineCondition);
                        meshObjectHolder = new MeshObjectsHolder(ref combineCondition, mat);
                        lod.meshObjectsHoldersLookup.Add(combineCondition, meshObjectHolder);
                    }

                    meshObjectHolder.meshObjects.Add(new MeshObject(cachedGO, l));

                    if (isChangeMode && !meshObjectHolder.hasChanged)
                    {
                        meshObjectHolder.hasChanged = true;
                        lod.changedMeshObjectsHolders.Add(meshObjectHolder);
                    }
                }

                return(true);
            }
Esempio n. 16
0
            public void CombineMeshes(MeshCombiner meshCombiner, int lodParentIndex)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;

                    LODParent lodParent = thisCell.lodParents[lodParentIndex];
                    if (lodParent == null)
                    {
                        return;
                    }

                    lodParent.cellGO         = new GameObject(meshCombiner.useCells ? "Cell " + bounds.center : "Combined Objects");
                    lodParent.cellT          = lodParent.cellGO.transform;
                    lodParent.cellT.position = bounds.center;
                    lodParent.cellT.parent   = meshCombiner.lodParentHolders[lodParentIndex].t;

                    if (lodParentIndex > 0)
                    {
                        lodParent.lodGroup = lodParent.cellGO.AddComponent <LODGroup>();
                        lodParent.lodGroup.localReferencePoint = lodParent.cellT.position = bounds.center;
                    }

                    LODLevel[] lods = lodParent.lodLevels;
                    for (int i = 0; i < lods.Length; i++)
                    {
                        LODLevel lod = lodParent.lodLevels[i];
                        if (lod == null || lod.meshObjectsHolders == null)
                        {
                            return;
                        }

                        GameObject lodGO;
                        Transform  lodT = null;

                        if (lodParentIndex > 0)
                        {
                            lodGO       = new GameObject("LOD" + i);
                            lodT        = lodGO.transform;
                            lodT.parent = lodParent.cellT;
                        }

                        for (int k = 0; k < lod.meshObjectsHolders.Count; ++k)
                        {
                            MeshObjectsHolder sortedMeshes = lod.meshObjectsHolders[k];
                            sortedMeshes.lodParent = lodParent;
                            sortedMeshes.lodLevel  = i;
                            MeshCombineJobManager.instance.AddJob(meshCombiner, sortedMeshes, lodParentIndex > 0 ? lodT : lodParent.cellT, bounds.center);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].CombineMeshes(meshCombiner, lodParentIndex);
                        }
                    }
                }
            }
Esempio n. 17
0
 public static GameObject SelectMeshObject(GameObject go, LODLevel lodLevel)
 {
     return(SelectNormalMesh(go, lodLevel));
 }
Esempio n. 18
0
        public static Texture2D GenerateBillboardNew(GameObject prefab, int width, int height, int gridSizeX,
                                                     int gridSizeY, Shader replacementShader, Color backgroundColor, Material minPostfilter,
                                                     LODLevel billboardSourceLODLevel, Quaternion rotationOffset, bool generateAo, bool recalculateNormals, float normalBlendFactor)
        {
#if UNITY_EDITOR
            bool fog = RenderSettings.fog;
            Unsupported.SetRenderSettingsUseFogNoDirty(false);
#endif

            Vector3   renderPosition = new Vector3(0, 0, 0);
            const int invisibleLayer = 31; // used for instance and camera cull

            // atlas size
            var w = width * gridSizeX;
            var h = height * gridSizeY;

            var result      = new Texture2D(w, h);
            var frameBuffer = new RenderTexture(width, height, 24);

            var filteredFrameBuffer = new RenderTexture(width, height, 24);

            var camGo = new GameObject("TempCamera");
            var cam   = camGo.AddComponent <Camera>();

            //if (generateAo)
            //{
            //    ScreenSpaceAmbientOcclusion ao = camGo.AddComponent<ScreenSpaceAmbientOcclusion>();
            //    ao.m_Radius = 0.874f;
            //    ao.m_SampleCount = ScreenSpaceAmbientOcclusion.SSAOSamples.High;
            //    ao.m_OcclusionIntensity = 4;
            //    ao.m_Blur = 4;
            //    ao.m_Downsampling = 6;
            //    ao.m_OcclusionAttenuation = 2;
            //    ao.m_MinZ = 0.0001f;
            //}

            cam.clearFlags = CameraClearFlags.Color;

            backgroundColor.a   = 0;
            cam.backgroundColor = backgroundColor;

            cam.renderingPath = RenderingPath.Forward;



            if (replacementShader != null)
            {
                cam.SetReplacementShader(replacementShader, "");
            }
            //cam.renderingPath = RenderingPath.DeferredShading;
            //cam.gameObject.AddComponent<ReadSpecularOcclusion>();

            var go = Instantiate(prefab, renderPosition, rotationOffset);
            if (recalculateNormals)
            {
                RecalculateMeshNormals(go, normalBlendFactor);
            }

            go.hideFlags = HideFlags.DontSave;

            LODGroup lodGroup = go.GetComponent <LODGroup>();
            if (lodGroup)
            {
                if (lodGroup.fadeMode == LODFadeMode.SpeedTree)
                {
                    lodGroup.ForceLOD((int)billboardSourceLODLevel);
                }
            }

            //MeshFilter meshFilter = go.GetComponent<MeshFilter>();
            //RecalculateMeshNormals(meshFilter.mesh,0);


            var children = go.GetComponentsInChildren <Transform>();
            foreach (var t in children)
            {
                t.gameObject.layer = invisibleLayer;
            }

            var   bounds  = CalculateBounds(go);
            float yOffset = FindLowestMeshYposition(go);

            cam.cullingMask  = 1 << invisibleLayer;
            cam.orthographic = true;


            //var boundsSize = Mathf.Max(bounds.extents.x, bounds.extents.y, bounds.extents.z) * 2;
            var boundsSize = Mathf.Max(bounds.extents.x, bounds.extents.y, bounds.extents.z);
            cam.orthographicSize = boundsSize;
            cam.nearClipPlane    = -boundsSize * 2;
            cam.farClipPlane     = boundsSize * 2;


            //cam.renderingPath = RenderingPath.DeferredShading;
            //float aspect = (float) width/(float)height;
            //float orthographicSize = boundsSize;
            //cam.projectionMatrix = Matrix4x4.Ortho(-orthographicSize * aspect, orthographicSize * aspect, -orthographicSize, orthographicSize, 0, cam.farClipPlane);


            cam.targetTexture = frameBuffer;

            cam.transform.position = renderPosition + new Vector3(0, bounds.extents.y - yOffset / 2, 0); // + yOffset/2

            var xAngleStep = 360f / gridSizeY / 4;
            var yAngleStep = 360f / gridSizeX;


            minPostfilter.SetInt("_UseGammaCorrection", 0);

#if UNITY_EDITOR
#if UNITY_2018_1_OR_NEWER
#else
            if (PlayerSettings.colorSpace == ColorSpace.Linear)
            {
                minPostfilter.SetInt("_UseGammaCorrection", 1);
            }
#endif
#endif


            for (int i = 0; i < gridSizeX; i++)
            {
                for (int j = 0; j < gridSizeY; j++)
                {
                    cam.transform.rotation = Quaternion.AngleAxis(yAngleStep * i, Vector3.up) *
                                             Quaternion.AngleAxis(xAngleStep * j, Vector3.right);
                    cam.Render();

                    RenderTexture.active = filteredFrameBuffer;

                    Graphics.Blit(frameBuffer, minPostfilter);

                    result.ReadPixels(new Rect(0, 0, frameBuffer.width, frameBuffer.height), i * width, j * height);

                    RenderTexture.active = null;
                }
            }

            DestroyImmediate(go);
            DestroyImmediate(camGo);

            result.Apply();

#if UNITY_EDITOR
            Unsupported.SetRenderSettingsUseFogNoDirty(fog);
#endif

            return(result);
        }