| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672 | using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.Rendering;#if ENVIRO_HDRPusing UnityEngine.Rendering.HighDefinition;#endifnamespace Enviro {    [AddComponentMenu("Enviro 3/Reflection Probe")]    [RequireComponent(typeof(ReflectionProbe)), ExecuteInEditMode]    public class EnviroReflectionProbe : MonoBehaviour    {        #region Public Var        #region Standalone Settings        public bool standalone = false;        public bool updateReflectionOnGameTime = true;        public float reflectionsUpdateTreshhold = 0.025f;        public bool useTimeSlicing = true;        #endregion        public Camera renderCam;        [HideInInspector]        public ReflectionProbe myProbe;        public bool customRendering = false;    #if !ENVIRO_HDRP        private EnviroRenderer enviroRenderer;    #endif        public bool useFog = false;        #endregion        #region Private Var        // Privates        public Camera bakingCam;        public int renderId = -1;        private bool currentMode = false;        private int currentRes;        private RenderTexture cubemap;        private RenderTexture finalCubemap;        private RenderTexture mirrorTexture;        private RenderTexture renderTexture;        private GameObject renderCamObj;        private Material mirror = null;        private Material bakeMat = null;        private Material convolutionMat;        private Coroutine refreshing;        private int renderID;    #if ENVIRO_HDRP        public HDProbe hdprobe;    #endif        private static Quaternion[] orientations = new Quaternion[]        {                Quaternion.LookRotation(Vector3.right, Vector3.down),                Quaternion.LookRotation(Vector3.left, Vector3.down),                Quaternion.LookRotation(Vector3.up, Vector3.forward),                Quaternion.LookRotation(Vector3.down, Vector3.back),                Quaternion.LookRotation(Vector3.forward, Vector3.down),                Quaternion.LookRotation(Vector3.back, Vector3.down)        };        private double lastRelfectionUpdate;        #endregion        ////////        void OnEnable()        {            myProbe = GetComponent<ReflectionProbe>();    #if ENVIRO_HDRP            if (EnviroManager.instance != null)            {                hdprobe = GetComponent<HDProbe>();                if(!standalone && myProbe != null)                    myProbe.enabled = true;                if (customRendering)                {                    if (hdprobe != null)                    {                        hdprobe.mode = ProbeSettings.Mode.Custom;                        CreateCubemap();                        CreateTexturesAndMaterial();                        CreateRenderCamera();                        currentRes = myProbe.resolution;                        StartCoroutine(RefreshFirstTime());                    }                }                else                {                    if (hdprobe != null)                    {                        hdprobe.mode = ProbeSettings.Mode.Realtime;                        hdprobe.realtimeMode = ProbeSettings.RealtimeMode.OnDemand;                        hdprobe.RequestRenderNextUpdate();                    }                }            }    #else            if (!standalone && myProbe != null)                myProbe.enabled = true;            if (customRendering)            {                myProbe.mode = ReflectionProbeMode.Custom;                myProbe.refreshMode = ReflectionProbeRefreshMode.ViaScripting;                CreateCubemap();                CreateTexturesAndMaterial();                CreateRenderCamera();                currentRes = myProbe.resolution;                StartCoroutine(RefreshFirstTime());                    }            else            {                myProbe.mode = ReflectionProbeMode.Realtime;                myProbe.refreshMode = ReflectionProbeRefreshMode.ViaScripting;                //StartCoroutine(RefreshUnity());                renderId = myProbe.RenderProbe();            }    #endif        }        void OnDisable()        {            Cleanup();            if (!standalone && myProbe != null)                myProbe.enabled = false;            RenderSettings.defaultReflectionMode = UnityEngine.Rendering.DefaultReflectionMode.Skybox;        }        private void Cleanup()        {            if (refreshing != null)                StopCoroutine(refreshing);            if (cubemap != null)            {                if (renderCam != null)                    renderCam.targetTexture = null;                DestroyImmediate(cubemap);            }            if (renderCamObj != null)                DestroyImmediate(renderCamObj);            if (mirrorTexture != null)                DestroyImmediate(mirrorTexture);            if (renderTexture != null)                DestroyImmediate(renderTexture);        }        // Creation        private void CreateRenderCamera()        {            if (renderCamObj == null)            {                renderCamObj = new GameObject();                renderCamObj.name = "Reflection Probe Cam";                renderCamObj.hideFlags = HideFlags.HideAndDontSave;                renderCam = renderCamObj.AddComponent<Camera>();                renderCam.gameObject.SetActive(true);                renderCam.cameraType = CameraType.Reflection;                renderCam.fieldOfView = 90;                renderCam.farClipPlane = myProbe.farClipPlane;                renderCam.nearClipPlane = myProbe.nearClipPlane;                renderCam.clearFlags = (CameraClearFlags)myProbe.clearFlags;                renderCam.backgroundColor = myProbe.backgroundColor;                renderCam.allowHDR = myProbe.hdr;                renderCam.targetTexture = cubemap;                renderCam.enabled = false;    #if VEGETATION_STUDIO_PRO        //     VegetationStudioManager.Instance.AddCamera(renderCam);    #endif    #if !ENVIRO_HDRP                if (EnviroManager.instance != null)                {                    enviroRenderer = renderCamObj.AddComponent<EnviroRenderer>();                }    #endif            }        }        private void UpdateCameraSettings()        {            if (renderCam != null)            {                renderCam.cullingMask = myProbe.cullingMask;    #if !ENVIRO_HDRP              if (EnviroManager.instance != null)                {                 //Update Quality                }    #endif            }        }        private Camera CreateBakingCamera()        {            GameObject tempCam = new GameObject();            tempCam.name = "Reflection Probe Cam";            Camera cam = tempCam.AddComponent<Camera>();            cam.enabled = false;            cam.gameObject.SetActive(true);            cam.cameraType = CameraType.Reflection;            cam.fieldOfView = 90;            cam.farClipPlane = myProbe.farClipPlane;            cam.nearClipPlane = myProbe.nearClipPlane;            cam.cullingMask = myProbe.cullingMask;            cam.clearFlags = (CameraClearFlags)myProbe.clearFlags;            cam.backgroundColor = myProbe.backgroundColor;            cam.allowHDR = myProbe.hdr;            cam.targetTexture = cubemap;    #if !ENVIRO_HDRP            if (EnviroManager.instance != null)                {                    enviroRenderer = renderCamObj.AddComponent<EnviroRenderer>();                }    #endif            tempCam.hideFlags = HideFlags.HideAndDontSave;            return cam;        }        private void CreateCubemap()        {            if (cubemap != null && myProbe.resolution == currentRes)                return;            if (cubemap != null)            {                cubemap.Release();                DestroyImmediate(cubemap);            }            if (finalCubemap != null)            {                finalCubemap.Release();                DestroyImmediate(finalCubemap);            }                            int resolution = myProbe.resolution;            currentRes = resolution;            RenderTextureFormat format = myProbe.hdr ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;            cubemap = new RenderTexture(resolution, resolution, 16, format, RenderTextureReadWrite.Linear);            cubemap.dimension = TextureDimension.Cube;            cubemap.useMipMap = true;            cubemap.autoGenerateMips = false;            cubemap.name = "Enviro Reflection Temp Cubemap";            cubemap.filterMode = FilterMode.Trilinear;            cubemap.Create();            finalCubemap = new RenderTexture(resolution, resolution, 16, format, RenderTextureReadWrite.Linear);            finalCubemap.dimension = TextureDimension.Cube;            finalCubemap.useMipMap = true;            finalCubemap.autoGenerateMips = false;            finalCubemap.name = "Enviro Reflection Final Cubemap";            finalCubemap.filterMode = FilterMode.Trilinear;            finalCubemap.Create();        }        //Create the textures        private void CreateTexturesAndMaterial()        {            if (mirror == null)                mirror = new Material(Shader.Find("Hidden/Enviro/ReflectionProbe"));            if (convolutionMat == null)                convolutionMat = new Material(Shader.Find("Hidden/EnviroCubemapBlur"));            int resolution = myProbe.resolution;            RenderTextureFormat format = myProbe.hdr ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;            if (mirrorTexture == null || mirrorTexture.width != resolution || mirrorTexture.height != resolution)            {                if (mirrorTexture != null)                    DestroyImmediate(mirrorTexture);                mirrorTexture = new RenderTexture(resolution, resolution, 16, format, RenderTextureReadWrite.Linear);                mirrorTexture.useMipMap = true;                mirrorTexture.autoGenerateMips = false;                mirrorTexture.name = "Enviro Reflection Mirror Texture";                mirrorTexture.Create();            }            if (renderTexture == null || renderTexture.width != resolution || renderTexture.height != resolution)            {                if (renderTexture != null)                    DestroyImmediate(renderTexture);                renderTexture = new RenderTexture(resolution, resolution, 16, format, RenderTextureReadWrite.Linear);                renderTexture.useMipMap = true;                renderTexture.autoGenerateMips = false;                renderTexture.name = "Enviro Reflection Target Texture";                renderTexture.Create();            }        }        // Refresh Methods        public void RefreshReflection(bool timeSlice = false)        {    #if ENVIRO_HDRP            if (customRendering)            {                if (refreshing != null)                    return;                CreateTexturesAndMaterial();                if (renderCam == null)                    CreateRenderCamera();                UpdateCameraSettings();                renderCam.transform.position = transform.position;                renderCam.targetTexture = renderTexture;                if (Application.isPlaying)                {                    if (!timeSlice)                        refreshing = StartCoroutine(RefreshInstant(renderTexture, mirrorTexture));                    else                        refreshing = StartCoroutine(RefreshOvertime(renderTexture, mirrorTexture));                }                else                {                    refreshing = StartCoroutine(RefreshInstant(renderTexture, mirrorTexture));                }            }            else            {                            if(hdprobe != null)                   hdprobe.RequestRenderNextUpdate();            }    #else            if (customRendering)            {                if (refreshing != null)                    return;                CreateTexturesAndMaterial();                if (renderCam == null)                    CreateRenderCamera();                UpdateCameraSettings();                renderCam.transform.position = transform.position;                renderCam.targetTexture = renderTexture;                if (Application.isPlaying)                {                    if (!timeSlice)                        refreshing = StartCoroutine(RefreshInstant(renderTexture, mirrorTexture));                    else                        refreshing = StartCoroutine(RefreshOvertime(renderTexture, mirrorTexture));                }                else                {                    refreshing = StartCoroutine(RefreshInstant(renderTexture, mirrorTexture));                }            }             else            {                renderId = myProbe.RenderProbe();             }    #endif        }        IEnumerator RefreshFirstTime()        {            yield return null;            RefreshReflection(false);            RefreshReflection(false);        }        public IEnumerator RefreshUnity()        {            yield return null;            renderId = myProbe.RenderProbe();        }        public IEnumerator RefreshInstant(RenderTexture renderTex, RenderTexture mirrorTex)        {            CreateCubemap();            yield return null;            for (int face = 0; face < 6; face++)            {                renderCam.transform.rotation = orientations[face];                renderCam.Render();                if(mirrorTex != null)                {                    Graphics.Blit(renderTex, mirrorTex, mirror);                    Graphics.CopyTexture(mirrorTex, 0, 0, cubemap, face, 0);                   }               }            ConvolutionCubemap();    #if ENVIRO_HDRP        if (hdprobe != null)            hdprobe.SetTexture(ProbeSettings.Mode.Custom, finalCubemap);    #else            myProbe.customBakedTexture = finalCubemap;    #endif            refreshing = null;        }        /// <summary>        /// Update Reflections with Time Slicing        /// </summary>        public IEnumerator RefreshOvertime(RenderTexture renderTex, RenderTexture mirrorTex)        {            CreateCubemap();            for (int face = 0;  face < 6; face++)            {                yield return null;                renderCam.transform.rotation = orientations[face];                      renderCam.Render();                if(mirrorTex != null)                {                             Graphics.Blit(renderTex, mirrorTex, mirror);                    Graphics.CopyTexture(mirrorTex, 0, 0, cubemap, face, 0);                }                //ClearTextures();                       }                ConvolutionCubemap();    #if ENVIRO_HDRP            if (hdprobe != null)                hdprobe.SetTexture(ProbeSettings.Mode.Custom, finalCubemap);    #else                myProbe.customBakedTexture = finalCubemap;    #endif            refreshing = null;        }        /// <summary>        /// Bakes one face per time into a render texture        /// </summary>        /// <param name="face"></param>        /// <param name="res"></param>        /// <returns></returns>        public RenderTexture BakeCubemapFace(int face, int res)        {            if (bakeMat == null)                bakeMat = new Material(Shader.Find("Hidden/Enviro/BakeCubemap"));            if (bakingCam == null)                bakingCam = CreateBakingCamera();            bakingCam.transform.rotation = orientations[face];            RenderTexture temp = RenderTexture.GetTemporary(res, res, 0, RenderTextureFormat.ARGBFloat);            bakingCam.targetTexture = temp;            bakingCam.Render();            RenderTexture tex = new RenderTexture(res, res, 0, RenderTextureFormat.ARGBFloat);            Graphics.Blit(temp, tex, bakeMat);            RenderTexture.ReleaseTemporary(temp);            return tex;        }        private void ClearTextures()        {            RenderTexture rt = RenderTexture.active;            RenderTexture.active = renderTexture;            GL.Clear(true, true, Color.clear);            RenderTexture.active = mirrorTexture;            GL.Clear(true, true, Color.clear);            RenderTexture.active = rt;        }            //This is not a proper convolution and very hacky to get anywhere near of unity realtime reflection probe mip convolution.        private void ConvolutionCubemap()        {            int mipCount = 7;            GL.PushMatrix();            GL.LoadOrtho();            cubemap.GenerateMips();            float texel = 1f;            switch(finalCubemap.width)            {                case 16:                texel = 1f;                break;                case 32:                texel = 1f;                break;                case 64:                texel = 2f;                break;                case 128:                texel = 4f;                break;                case 256:                texel = 8f;                break;                case 512:                texel = 14f;                break;                case 1024:                texel = 30f;                break;                    case 2048:                texel = 60f;                break;            }            float res = finalCubemap.width;            for (int mip = 0; mip < mipCount + 1; mip++)            {                //Copy each face                Graphics.CopyTexture(cubemap, 0, mip, finalCubemap, 0, mip);                Graphics.CopyTexture(cubemap, 1, mip, finalCubemap, 1, mip);                Graphics.CopyTexture(cubemap, 2, mip, finalCubemap, 2, mip);                Graphics.CopyTexture(cubemap, 3, mip, finalCubemap, 3, mip);                Graphics.CopyTexture(cubemap, 4, mip, finalCubemap, 4, mip);                Graphics.CopyTexture(cubemap, 5, mip, finalCubemap, 5, mip);                int dstMip = mip + 1;                if (dstMip == mipCount)                    break;                            float texelSize = (texel * dstMip) / res;                             convolutionMat.SetTexture("_MainTex", finalCubemap);                convolutionMat.SetFloat("_Texel", texelSize);                        convolutionMat.SetFloat("_Level", mip);                convolutionMat.SetPass(0);                res *= 0.75f;                // Positive X                Graphics.SetRenderTarget(cubemap, dstMip, CubemapFace.PositiveX);                GL.Begin(GL.QUADS);                GL.TexCoord3(1, 1, 1);                GL.Vertex3(0, 0, 1);                GL.TexCoord3(1, -1, 1);                GL.Vertex3(0, 1, 1);                GL.TexCoord3(1, -1, -1);                GL.Vertex3(1, 1, 1);                GL.TexCoord3(1, 1, -1);                GL.Vertex3(1, 0, 1);                GL.End();                // Negative X                Graphics.SetRenderTarget(cubemap, dstMip, CubemapFace.NegativeX);                GL.Begin(GL.QUADS);                GL.TexCoord3(-1, 1, -1);                GL.Vertex3(0, 0, 1);                GL.TexCoord3(-1, -1, -1);                GL.Vertex3(0, 1, 1);                GL.TexCoord3(-1, -1, 1);                GL.Vertex3(1, 1, 1);                GL.TexCoord3(-1, 1, 1);                GL.Vertex3(1, 0, 1);                GL.End();                // Positive Y                Graphics.SetRenderTarget(cubemap, dstMip, CubemapFace.PositiveY);                GL.Begin(GL.QUADS);                GL.TexCoord3(-1, 1, -1);                GL.Vertex3(0, 0, 1);                GL.TexCoord3(-1, 1, 1);                GL.Vertex3(0, 1, 1);                GL.TexCoord3(1, 1, 1);                GL.Vertex3(1, 1, 1);                GL.TexCoord3(1, 1, -1);                GL.Vertex3(1, 0, 1);                GL.End();                // Negative Y                Graphics.SetRenderTarget(cubemap, dstMip, CubemapFace.NegativeY);                GL.Begin(GL.QUADS);                GL.TexCoord3(-1, -1, 1);                GL.Vertex3(0, 0, 1);                GL.TexCoord3(-1, -1, -1);                GL.Vertex3(0, 1, 1);                GL.TexCoord3(1, -1, -1);                GL.Vertex3(1, 1, 1);                GL.TexCoord3(1, -1, 1);                GL.Vertex3(1, 0, 1);                GL.End();                // Positive Z                Graphics.SetRenderTarget(cubemap, dstMip, CubemapFace.PositiveZ);                GL.Begin(GL.QUADS);                GL.TexCoord3(-1, 1, 1);                GL.Vertex3(0, 0, 1);                GL.TexCoord3(-1, -1, 1);                GL.Vertex3(0, 1, 1);                GL.TexCoord3(1, -1, 1);                GL.Vertex3(1, 1, 1);                GL.TexCoord3(1, 1, 1);                GL.Vertex3(1, 0, 1);                GL.End();                // Negative Z                Graphics.SetRenderTarget(cubemap, dstMip, CubemapFace.NegativeZ);                GL.Begin(GL.QUADS);                GL.TexCoord3(1, 1, -1);                GL.Vertex3(0, 0, 1);                GL.TexCoord3(1, -1, -1);                GL.Vertex3(0, 1, 1);                GL.TexCoord3(-1, -1, -1);                GL.Vertex3(1, 1, 1);                GL.TexCoord3(-1, 1, -1);                GL.Vertex3(1, 0, 1);                GL.End();            }            GL.PopMatrix();        }        private void UpdateStandaloneReflection()        {            if ((EnviroManager.instance.Time.GetDateInHours() > lastRelfectionUpdate + reflectionsUpdateTreshhold ||EnviroManager.instance.Time.GetDateInHours() < lastRelfectionUpdate - reflectionsUpdateTreshhold) && updateReflectionOnGameTime)            {                lastRelfectionUpdate = EnviroManager.instance.Time.GetDateInHours();                RefreshReflection(!useTimeSlicing);            }        }        private void Update()        {            if (currentMode != customRendering)            {                currentMode = customRendering;                if (customRendering)                {                    OnEnable();                }                else                {                    OnEnable();                    Cleanup();                }            }            if (EnviroManager.instance != null && standalone)            {                UpdateStandaloneReflection();                        }        }    }}
 |