/// <summary>
        /// Computes and stores a texture map for the current submesh.
        /// </summary>
        private void ComputeAndStoreTextureMap()
        {
            // Check if the asset has already been processed.
            string assetName              = textureMapAssetPrefix + GeneralToolkit.ToString(_submeshIndex);
            string bundledAssetName       = dataHandler.GetBundledAssetName(this, assetName);
            string textureMapRelativePath = Path.Combine(GeneralToolkit.tempDirectoryRelativePath, bundledAssetName + ".asset");

            if (dataHandler.IsAssetAlreadyProcessed(textureMapRelativePath))
            {
                return;
            }
            // Render to the preview camera a first time to initialize all buffers correctly.
            _previewCameraModel.pixelResolution = _textureMapResolution;
            _previewCameraManager.UpdateCameraModel(_previewCameraModel, true);
            _previewCameraManager.RenderPreviewToTarget(ref _previewCameraManager.targetTexture, false);
            // Render the mesh to the preview camera's target texture.
            Camera.onPreCull += DrawSubmeshAsTextureMapWithCamera;
            _previewCameraManager.RenderPreviewToTarget(ref _previewCameraManager.targetTexture, false);
            Camera.onPreCull -= DrawSubmeshAsTextureMapWithCamera;
            // Normalize the RGB channels by the alpha channel.
            RenderTexture tempTex = new RenderTexture(1, 1, 0);

            GeneralToolkit.CreateRenderTexture(ref tempTex, _textureMapResolution, 0, RenderTextureFormat.ARGB32, false, FilterMode.Point, TextureWrapMode.Clamp);
            Graphics.Blit(_previewCameraManager.targetTexture, tempTex, _normalizeByAlphaMat);
            // Apply a morphological dilation to better handle seams in the texture map..
            GeneralToolkit.RenderTextureApplyMorphologicalDilation(ref tempTex, _textureMapResolution.x / 200, ImageProcessingKernelType.Box, false);
            // Copy the render texture to an output texture.
            Texture2D outTex = new Texture2D(1, 1);

            GeneralToolkit.CreateTexture2D(ref outTex, _textureMapResolution, TextureFormat.RGB24, false, FilterMode.Bilinear, TextureWrapMode.Clamp, true);
            GeneralToolkit.CopyRenderTextureToTexture2D(tempTex, ref outTex);
            outTex.filterMode = FilterMode.Bilinear;
            outTex.anisoLevel = 3;
            // Destroy created objects.
            DestroyImmediate(tempTex);
            // Save a copy as a png file for visualization.
            string copyName = DataHandler.GetBundledAssetPrefixFromType(this.GetType()) + assetName + ".png";

            GeneralToolkit.SaveTexture2DToPNG(outTex, Path.Combine(GeneralToolkit.tempDirectoryAbsolutePath, copyName));
            // Create an asset from the created texture map.
            AssetDatabase.CreateAsset(outTex, textureMapRelativePath);
            AssetDatabase.Refresh();
            // Set the created texture in the final array.
            Texture2D texAsset = AssetDatabase.LoadAssetAtPath <Texture2D>(textureMapRelativePath);

            textureMaps[_submeshIndex] = (Texture2D)Instantiate(texAsset);
        }
Example #2
0
 /// <summary>
 /// Coroutine that renders per-view meshes from the given depth texture array.
 /// </summary>
 /// <returns></returns>
 private IEnumerator StorePerViewMeshesCoroutine()
 {
     // Reset the progress bar.
     GeneralToolkit.ResetCancelableProgressBar(true, false);
     // Initialize the compute shader's properties.
     PMPerViewMeshesQSTR.InitializePerCall();
     // Create a mesh for each source depth map.
     for (int sourceCamIndex = 0; sourceCamIndex < cameraSetup.cameraModels.Length; sourceCamIndex++)
     {
         // Check if the asset has already been processed.
         string bundledAssetName = dataHandler.GetBundledAssetName(PMPerViewMeshesQSTR, PerViewMeshesQSTR.perViewMeshAssetPrefix + sourceCamIndex);
         string meshRelativePath = Path.Combine(GeneralToolkit.tempDirectoryRelativePath, bundledAssetName + ".asset");
         if (dataHandler.IsAssetAlreadyProcessed(meshRelativePath))
         {
             continue;
         }
         // Update the progress bar, and enable the user to cancel the process.
         PMPerViewMeshesQSTR.DisplayAndUpdateCancelableProgressBar();
         if (GeneralToolkit.progressBarCanceled)
         {
             processingCaller.processingCanceled = true;
             break;
         }
         // Update the camera model.
         PMPerViewMeshesQSTR.cameraModel = cameraSetup.cameraModels[sourceCamIndex];
         // Initialize the distance map texture, and load the depth data into it.
         PMPerViewMeshesQSTR.InitializeDistanceMap();
         Vector2Int    distanceMapResolution  = new Vector2Int(PMPerViewMeshesQSTR.distanceMap.width, PMPerViewMeshesQSTR.distanceMap.height);
         RenderTexture depthTextureArraySlice = new RenderTexture(1, 1, 0);
         GeneralToolkit.CreateRenderTexture(ref depthTextureArraySlice, distanceMapResolution, 0, RenderTextureFormat.ARGB32, true, FilterMode.Point);
         Graphics.Blit(PMDepthTextureArray.depthData, depthTextureArraySlice, sourceCamIndex, 0);
         GeneralToolkit.CopyRenderTextureToTexture2D(depthTextureArraySlice, ref PMPerViewMeshesQSTR.distanceMap);
         DestroyImmediate(depthTextureArraySlice);
         // Compute a mesh from the distance map.
         Mesh meshAsset;
         PMPerViewMeshesQSTR.ComputeMesh(out meshAsset);
         // Save this mesh as an asset.
         GeneralToolkit.CreateAndUnloadAsset(meshAsset, meshRelativePath);
         yield return(null);
     }
     // Reset the progress bar.
     GeneralToolkit.ResetCancelableProgressBar(true, false);
 }
 /// <inheritdoc/>
 protected override void ProvideDepthTextureToGeometryProcessingMethod()
 {
     // Convert the camera's z-buffer to a color texture, and provide it to the processing method.
     ConvertZBufferToColorTexture();
     GeneralToolkit.CopyRenderTextureToTexture2D(_distanceAsColorTexture, ref _geometryProcessingMethod.distanceMap);
 }
        /// <summary>
        /// Coroutine that renders depth maps for each view using a given global mesh, and stores this information as a depth texture array.
        /// </summary>
        /// <returns></returns>
        private IEnumerator StoreDepthMapTextureArrayCoroutine()
        {
            // Get the processed asset's name and path in the bundle.
            string bundledAssetName      = GetBundledAssetName(depthMapsAssetName);
            string depthDataPathRelative = GetAssetPathRelative(bundledAssetName);

            // Check if the asset has already been processed.
            if (!dataHandler.IsAssetAlreadyProcessed(depthDataPathRelative))
            {
                // Reset the progress bar.
                GeneralToolkit.ResetCancelableProgressBar(true, false);
                // Create and initialize a temporary preview camera manager aimed at storing depth data.
                PreviewCameraManager previewCameraManager   = new GameObject("TempPreviewCameraManager").AddComponent <PreviewCameraManager>();
                Transform            previewCameraTransform = new GameObject("TempPreviewCamera").transform;
                GeneralToolkit.CreateRenderTexture(ref previewCameraManager.targetTexture, Vector2Int.one, 24, RenderTextureFormat.RFloat, true, FilterMode.Point, TextureWrapMode.Clamp);
                previewCameraManager.CreatePreviewCamera(previewCameraManager.gameObject, previewCameraTransform, cameraSetup.cameraModels[0]);
                // Instantiate the mesh as a set of submeshes, provided with the default material.
                Material     defaultMat = new Material(GeneralToolkit.shaderStandard);
                GameObject[] submeshGOs = new GameObject[PMGlobalMeshEF.globalMesh.subMeshCount];
                for (int i = 0; i < submeshGOs.Length; i++)
                {
                    submeshGOs[i] = new GameObject("TempMesh_" + i);
                    submeshGOs[i].transform.parent = previewCameraManager.transform;
                    submeshGOs[i].AddComponent <MeshFilter>().sharedMesh = PMGlobalMeshEF.globalMesh;
                    Material[] materials = new Material[submeshGOs.Length];
                    materials[i] = defaultMat;
                    submeshGOs[i].AddComponent <MeshRenderer>().materials = materials;
                }
                // Create an empty texture array in which to store the depth data.
                Vector2Int arrayResolution; int arrayDepth;
                ColorTextureArray.GetCorrectedPowerOfTwoForImages(cameraSetup.cameraModels, out arrayResolution, out arrayDepth);
                depthData = new Texture2DArray(1, 1, 1, TextureFormat.RGB24, false);
                GeneralToolkit.CreateTexture2DArray(ref depthData, arrayResolution, arrayDepth, TextureFormat.RGB24, false, FilterMode.Point, TextureWrapMode.Clamp, false);
                // Create a render texture in which to store RFloat depth data, with the array's resolution.
                RenderTexture arraySliceRFloatRenderTex = new RenderTexture(1, 1, 0);
                GeneralToolkit.CreateRenderTexture(ref arraySliceRFloatRenderTex, arrayResolution, 24, RenderTextureFormat.RFloat, true, FilterMode.Point, TextureWrapMode.Clamp);
                // Create a material and render texture to encode the RFloat distance as a RGB color.
                Material      distanceToColorMat     = new Material(GeneralToolkit.shaderAcquisitionConvert01ToColor);
                RenderTexture distanceAsColorTexture = new RenderTexture(1, 1, 0);
                GeneralToolkit.CreateRenderTexture(ref distanceAsColorTexture, arrayResolution, 0, RenderTextureFormat.ARGB32, true, FilterMode.Point, TextureWrapMode.Clamp);
                // Create a texture in which to store the RGB-encoded distance.
                Texture2D arraySliceRGBTex = new Texture2D(1, 1);
                GeneralToolkit.CreateTexture2D(ref arraySliceRGBTex, arrayResolution, TextureFormat.RGB24, true, FilterMode.Point, TextureWrapMode.Clamp, false);
                // Create a depth map in each layer of the texture array, corresponding to each source camera.
                for (int i = 0; i < arrayDepth; i++)
                {
                    // Update the progress bar, and enable the user to cancel the process.
                    DisplayAndUpdateCancelableProgressBar();
                    if (GeneralToolkit.progressBarCanceled)
                    {
                        processingCaller.processingCanceled = true;
                        break;
                    }
                    // Set the preview camera manager's camera model to the current source camera.
                    previewCameraManager.UpdateCameraModel(cameraSetup.cameraModels[i]);
                    // Render the depth data seen by this camera as an RFloat texture.
                    previewCameraManager.RenderPreviewToTarget(ref previewCameraManager.targetTexture, true);
                    // Resize the rendered texture to the output array's resolution.
                    Graphics.Blit(previewCameraManager.targetTexture, arraySliceRFloatRenderTex);
                    // Convert the resized RFloat texture to an RGB encoding.
                    Graphics.Blit(arraySliceRFloatRenderTex, distanceAsColorTexture, distanceToColorMat);
                    // Store the RGB color texture into the texture array.
                    GeneralToolkit.CopyRenderTextureToTexture2D(distanceAsColorTexture, ref arraySliceRGBTex);
                    depthData.SetPixels(arraySliceRGBTex.GetPixels(), i);
                    depthData.Apply();
                    yield return(null);
                }
                // If the user has not canceled the process, continue.
                if (!GeneralToolkit.progressBarCanceled)
                {
                    // Create an asset from this texture array.
                    AssetDatabase.CreateAsset(depthData, depthDataPathRelative);
                    AssetDatabase.Refresh();
                }
                // Destroy the created textures and conversion material.
                DestroyImmediate(arraySliceRGBTex);
                DestroyImmediate(distanceAsColorTexture);
                DestroyImmediate(distanceToColorMat);
                DestroyImmediate(arraySliceRFloatRenderTex);
                // Destroy the created meshes and default material.
                DestroyImmediate(defaultMat);
                foreach (GameObject submeshGO in submeshGOs)
                {
                    DestroyImmediate(submeshGO);
                }
                // Destroy the preview camera manager.
                previewCameraManager.DestroyPreviewCamera();
                DestroyImmediate(previewCameraManager.gameObject);
                // Reset the progress bar.
                GeneralToolkit.ResetCancelableProgressBar(true, false);
            }
            Texture2DArray depthDataAsset = AssetDatabase.LoadAssetAtPath <Texture2DArray>(depthDataPathRelative);

            depthData = (Texture2DArray)Instantiate(depthDataAsset);
        }