コード例 #1
0
    // Update one custom render texture.
    public static void UpdateCustomRenderTexture(CommandBuffer cmd, CustomRenderTexture crt)
    {
        bool firstPass = crt.updateCount == 0;

        // Handle initialization here too:
        if (crt.initializationMode == CustomRenderTextureUpdateMode.Realtime || needsInitialization.Contains(crt) || (firstPass && crt.initializationMode == CustomRenderTextureUpdateMode.OnLoad))
        {
            switch (crt.initializationSource)
            {
            case CustomRenderTextureInitializationSource.Material:
                // TODO
                break;

            case CustomRenderTextureInitializationSource.TextureAndColor:
                // TODO
                break;
            }
            needsInitialization.Remove(crt);
        }

        needsUpdate.TryGetValue(crt, out int updateCount);

        if (crt.material != null && (crt.updateMode == CustomRenderTextureUpdateMode.Realtime || updateCount > 0 || (firstPass && crt.updateMode == CustomRenderTextureUpdateMode.OnLoad)))
        {
            onBeforeCustomTextureUpdated?.Invoke(cmd, crt);

#if CUSTOM_TEXTURE_PROFILING
            customRenderTextureSamplers.TryGetValue(crt, out var sampler);
            if (sampler == null)
            {
                sampler = customRenderTextureSamplers[crt] = CustomSampler.Create($"{crt.name} - {crt.GetInstanceID()}", true);
                sampler.GetRecorder().enabled = true;
            }
            cmd.BeginSample(sampler);
#endif

            // using (new ProfilingScope(cmd, new ProfilingSampler($"Update {crt.name}")))
            {
                updateCount = Mathf.Max(updateCount, 1);
                crtExecInfo.TryGetValue(crt, out var execInfo);
                if (execInfo != null && execInfo.runOnAllMips)
                {
                    for (int mipLevel = 0; mipLevel < crt.mipmapCount; mipLevel++)
                    {
                        UpdateCustomRenderTexture(cmd, crt, updateCount, mipLevel: mipLevel);
                    }
                }
                else
                {
                    UpdateCustomRenderTexture(cmd, crt, updateCount);
                }

                needsUpdate.Remove(crt);
            }

#if CUSTOM_TEXTURE_PROFILING
            cmd.EndSample(sampler);
#endif
            crt.IncrementUpdateCount();
        }
    }
コード例 #2
0
        private static void SaveToDisk(MenuCommand command)
        {
            CustomRenderTexture customRenderTexture = command.context as CustomRenderTexture;
            int           width       = customRenderTexture.width;
            int           height      = customRenderTexture.height;
            int           volumeDepth = customRenderTexture.volumeDepth;
            bool          flag        = RenderTextureEditor.IsHDRFormat(customRenderTexture.format);
            bool          flag2       = customRenderTexture.format == RenderTextureFormat.ARGBFloat || customRenderTexture.format == RenderTextureFormat.RFloat;
            TextureFormat format      = (!flag) ? TextureFormat.RGBA32 : TextureFormat.RGBAFloat;
            int           width2      = width;

            if (customRenderTexture.dimension == TextureDimension.Tex3D)
            {
                width2 = width * volumeDepth;
            }
            else if (customRenderTexture.dimension == TextureDimension.Cube)
            {
                width2 = width * 6;
            }
            Texture2D texture2D = new Texture2D(width2, height, format, false);

            if (customRenderTexture.dimension == TextureDimension.Tex2D)
            {
                Graphics.SetRenderTarget(customRenderTexture);
                texture2D.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0);
                texture2D.Apply();
            }
            else if (customRenderTexture.dimension == TextureDimension.Tex3D)
            {
                int num = 0;
                for (int i = 0; i < volumeDepth; i++)
                {
                    Graphics.SetRenderTarget(customRenderTexture, 0, CubemapFace.Unknown, i);
                    texture2D.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), num, 0);
                    texture2D.Apply();
                    num += width;
                }
            }
            else
            {
                int num2 = 0;
                for (int j = 0; j < 6; j++)
                {
                    Graphics.SetRenderTarget(customRenderTexture, 0, (CubemapFace)j);
                    texture2D.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), num2, 0);
                    texture2D.Apply();
                    num2 += width;
                }
            }
            byte[] bytes;
            if (flag)
            {
                bytes = texture2D.EncodeToEXR(Texture2D.EXRFlags.CompressZIP | ((!flag2) ? Texture2D.EXRFlags.None : Texture2D.EXRFlags.OutputAsFloat));
            }
            else
            {
                bytes = texture2D.EncodeToPNG();
            }
            UnityEngine.Object.DestroyImmediate(texture2D);
            string extension     = (!flag) ? "png" : "exr";
            string directoryName = Path.GetDirectoryName(AssetDatabase.GetAssetPath(customRenderTexture.GetInstanceID()));
            string text          = EditorUtility.SaveFilePanel("Save Custom Texture", directoryName, customRenderTexture.name, extension);

            if (!string.IsNullOrEmpty(text))
            {
                File.WriteAllBytes(text, bytes);
                AssetDatabase.Refresh();
            }
        }
コード例 #3
0
        static void SaveToDisk(MenuCommand command)
        {
            CustomRenderTexture texture = command.context as CustomRenderTexture;
            int width  = texture.width;
            int height = texture.height;
            int depth  = texture.volumeDepth;

            // This has its TextureFormat helper equivalent in C++ but since we are going to try to refactor TextureFormat/RenderTextureFormat into a single type so let's not bloat Scripting APIs with stuff that will get useless soon(tm).
            bool isFormatHDR   = GraphicsFormatUtility.IsIEEE754Format(texture.graphicsFormat);
            bool isFloatFormat = GraphicsFormatUtility.IsFloatFormat(texture.graphicsFormat);

            TextureFormat format     = isFormatHDR ? TextureFormat.RGBAFloat : TextureFormat.RGBA32;
            int           finalWidth = width;

            if (texture.dimension == UnityEngine.Rendering.TextureDimension.Tex3D)
            {
                finalWidth = width * depth;
            }
            else if (texture.dimension == UnityEngine.Rendering.TextureDimension.Cube)
            {
                finalWidth = width * 6;
            }

            Texture2D tex = new Texture2D(finalWidth, height, format, false);

            // Read screen contents into the texture
            if (texture.dimension == UnityEngine.Rendering.TextureDimension.Tex2D)
            {
                Graphics.SetRenderTarget(texture);
                tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
                tex.Apply();
            }
            else if (texture.dimension == UnityEngine.Rendering.TextureDimension.Tex3D)
            {
                int offset = 0;
                for (int i = 0; i < depth; ++i)
                {
                    Graphics.SetRenderTarget(texture, 0, CubemapFace.Unknown, i);
                    tex.ReadPixels(new Rect(0, 0, width, height), offset, 0);
                    tex.Apply();
                    offset += width;
                }
            }
            else
            {
                int offset = 0;
                for (int i = 0; i < 6; ++i)
                {
                    Graphics.SetRenderTarget(texture, 0, (CubemapFace)i);
                    tex.ReadPixels(new Rect(0, 0, width, height), offset, 0);
                    tex.Apply();
                    offset += width;
                }
            }

            // Encode texture into PNG
            byte[] bytes = null;
            if (isFormatHDR)
            {
                bytes = tex.EncodeToEXR(Texture2D.EXRFlags.CompressZIP | (isFloatFormat ? Texture2D.EXRFlags.OutputAsFloat : 0));
            }
            else
            {
                bytes = tex.EncodeToPNG();
            }

            Object.DestroyImmediate(tex);

            var extension = isFormatHDR ? "exr" : "png";

            var    directory = Path.GetDirectoryName(AssetDatabase.GetAssetPath(texture.GetInstanceID()));
            string assetPath = EditorUtility.SaveFilePanel("Save Custom Render Texture", directory, texture.name, extension);

            if (!string.IsNullOrEmpty(assetPath))
            {
                File.WriteAllBytes(assetPath, bytes);
                AssetDatabase.Refresh();
            }
        }
コード例 #4
0
    // Update one custom render texture.
    public static void UpdateCustomRenderTexture(CommandBuffer cmd, CustomRenderTexture crt)
    {
        bool firstPass = crt.updateCount == 0;

        // Handle initialization here too:
        if (crt.initializationMode == CustomRenderTextureUpdateMode.Realtime || needsInitialization.Contains(crt) || (firstPass && crt.initializationMode == CustomRenderTextureUpdateMode.OnLoad))
        {
            switch (crt.initializationSource)
            {
            case CustomRenderTextureInitializationSource.Material:
                // TODO
                break;

            case CustomRenderTextureInitializationSource.TextureAndColor:
                // TODO
                break;
            }
            needsInitialization.Remove(crt);
        }

        needsUpdate.TryGetValue(crt, out int updateCount);

        if (crt.material != null && (crt.updateMode == CustomRenderTextureUpdateMode.Realtime || updateCount > 0 || (firstPass && crt.updateMode == CustomRenderTextureUpdateMode.OnLoad)))
        {
            onBeforeCustomTextureUpdated?.Invoke(cmd, crt);

#if CUSTOM_TEXTURE_PROFILING
            customRenderTextureSamplers.TryGetValue(crt, out var sampler);
            if (sampler == null)
            {
                sampler = customRenderTextureSamplers[crt] = CustomSampler.Create($"{crt.name} - {crt.GetInstanceID()}", true);
                sampler.GetRecorder().enabled = true;
            }
            cmd.BeginSample(sampler);
#endif

            using (new ProfilingScope(cmd, new ProfilingSampler($"Update {crt.name}")))
            {
                // Prepare "self" texture for reading in the shader for double buffered custom textures
                RenderTexture textureSelf2D   = null;
                RenderTexture textureSelf3D   = null;
                RenderTexture textureSelfCube = null;
                if (crt.doubleBuffered)
                {
                    if (crt.dimension == TextureDimension.Tex2D)
                    {
                        textureSelf2D = crt;
                    }
                    if (crt.dimension == TextureDimension.Cube)
                    {
                        textureSelfCube = crt;
                    }
                    if (crt.dimension == TextureDimension.Tex3D)
                    {
                        textureSelf3D = crt;
                    }
                }

                if (crt.doubleBuffered)
                {
                    // Update the internal double buffered render texture (resize / alloc / ect.)
                    crt.EnsureDoubleBufferConsistency();
                }

                MaterialPropertyBlock block = new MaterialPropertyBlock();

                // If the user didn't called the update on CRT, we still process it because it's realtime
                updateCount = Mathf.Max(updateCount, 1);
                for (int i = 0; i < updateCount; i++)
                {
                    // TODO: cache everything
                    List <CustomRenderTextureUpdateZone> updateZones = new List <CustomRenderTextureUpdateZone>();
                    crt.GetUpdateZones(updateZones);

                    if (updateZones.Count == 0)
                    {
                        updateZones.Add(new CustomRenderTextureUpdateZone {
                            needSwap = false, updateZoneCenter = new Vector3(0.5f, 0.5f, 0.5f), updateZoneSize = Vector3.one, rotation = 0, passIndex = 0
                        });
                    }

                    foreach (var zone in updateZones)
                    // int sliceCount = GetSliceCount(crt);
                    // for (int slice = 0; slice < sliceCount; slice++)
                    {
                        var zoneCenters          = updateZones.Select(z => new Vector4(z.updateZoneCenter.x, z.updateZoneCenter.y, z.updateZoneCenter.z, 0)).ToList();
                        var zoneSizesAndRotation = updateZones.Select(z => new Vector4(z.updateZoneSize.x, z.updateZoneSize.y, z.updateZoneSize.z, z.rotation)).ToList();
                        var zonePrimitiveIDs     = Enumerable.Range(0, updateZones.Count).Select(j => (float)j).ToList();// updateZones.Select(z => 0.0f).ToList();
                        int sliceCount           = GetSliceCount(crt);

                        // Copy all the slices in case the texture is double buffered
                        if (zone.needSwap)
                        {
                            var doubleBuffer = crt.GetDoubleBufferRenderTexture();
                            if (doubleBuffer != null)
                            {
                                // For now, it's just a copy, once we actually do the swap of pointer, be careful to reset the Active Render Texture
                                for (int slice = 0; slice < sliceCount; slice++)
                                {
                                    cmd.CopyTexture(doubleBuffer, slice, crt, slice);
                                }
                            }
                        }

                        // foreach (var zone in updateZones)
                        for (int slice = 0; slice < sliceCount; slice++)
                        {
                            RenderTexture renderTexture = crt.doubleBuffered ? crt.GetDoubleBufferRenderTexture() : crt;
                            cmd.SetRenderTarget(renderTexture, 0, (crt.dimension == TextureDimension.Cube) ? (CubemapFace)slice : 0, (crt.dimension == TextureDimension.Tex3D) ? slice : 0);
                            cmd.SetViewport(new Rect(0, 0, crt.width, crt.height));
                            block.SetVector(kCustomRenderTextureInfo, GetTextureInfos(crt, slice));
                            block.SetVector(kCustomRenderTextureParameters, GetTextureParameters(crt, slice));
                            if (textureSelf2D != null)
                            {
                                block.SetTexture(kSelf2D, textureSelf2D);
                            }
                            if (textureSelf3D != null)
                            {
                                block.SetTexture(kSelf3D, textureSelf3D);
                            }
                            if (textureSelfCube != null)
                            {
                                block.SetTexture(kSelfCube, textureSelfCube);
                            }

                            int passIndex = zone.passIndex == -1 ? 0 : zone.passIndex;

                            block.SetVectorArray(kUpdateDataCenters, zoneCenters);
                            block.SetVectorArray(kUpdateDataSizesAndRotation, zoneSizesAndRotation);
                            block.SetFloatArray(kUpdateDataPrimitiveIDs, zonePrimitiveIDs);

                            cmd.DrawProcedural(Matrix4x4.identity, crt.material, passIndex, MeshTopology.Triangles, 6 * updateZones.Count, 1, block);
                        }
                    }
                }

                needsUpdate.Remove(crt);
            }

#if CUSTOM_TEXTURE_PROFILING
            cmd.EndSample(sampler);
#endif
            crt.IncrementUpdateCount();
        }
    }