private void Start()
        {
            effect = new WeatherMakerFullScreenEffect
            {
                CommandBufferName = commandBufferName,
                DownsampleRenderBufferTextureName = "_MainTex2",
                RenderQueue = OverlayRenderQueue
            };
            updateShaderPropertiesAction = UpdateShaderProperties;

#if UNITY_EDITOR
            if (Application.isPlaying)
            {
#endif

            // clone during play mode so as to not overwrite profile properties inadvertantly
            if (OverlayProfile != null)
            {
                OverlayProfile = ScriptableObject.Instantiate(OverlayProfile);
            }
            if (OverlayBlurMaterial != null)
            {
                OverlayBlurMaterial = new Material(OverlayBlurMaterial);
            }

#if UNITY_EDITOR
        }
#endif
        }
Example #2
0
        private void OnDisable()
        {
            // use pre-render to give all other pre-cull scripts a chance to set properties, state, etc.

#if UNITY_LWRP
            RenderPipelineManager.beginCameraRendering -= CameraBeginRendering;
            RenderPipelineManager.endCameraRendering   -= CameraEndRendering;
            RenderPipelineManager.beginFrameRendering  -= CameraBeginFrameRendering;
            RenderPipelineManager.endFrameRendering    -= CameraEndFrameRendering;
#else
            Camera.onPreCull    -= CameraPreCull;
            Camera.onPreRender  -= CameraPreRender;
            Camera.onPostRender -= CameraPostRender;
#endif

            CleanupDepthTextures();

#if ENABLE_FORWARD_OPAQUE_CAPTURE
            if (AfterOpaqueBuffer != null)
            {
                AfterOpaqueBuffer.Release();
                Destroy(AfterOpaqueBuffer);
                AfterOpaqueBuffer = null;
            }
            AfterOpaqueBuffer = WeatherMakerFullScreenEffect.DestroyRenderTexture(AfterOpaqueBuffer);
#endif
        }
Example #3
0
        private void CreateAfterForwardOpaqueCommandBuffer(Camera camera)
        {
#if ENABLE_FORWARD_OPAQUE_CAPTURE
            if (afterForwardOpaqueCommandBuffer != null)
            {
                camera.RemoveCommandBuffer(CameraEvent.AfterForwardOpaque, afterForwardOpaqueCommandBuffer);
                camera.RemoveCommandBuffer(CameraEvent.AfterSkybox, afterForwardOpaqueCommandBuffer);
            }
            if (afterForwardOpaqueCommandBuffer == null || (AfterOpaqueBuffer != null && (AfterOpaqueBuffer.width != camera.pixelWidth || AfterOpaqueBuffer.height != camera.pixelHeight)))
            {
                if (AfterOpaqueBuffer != null)
                {
                    AfterOpaqueBuffer.Clear();
                    AfterOpaqueBuffer.Release();
                    Destroy(AfterOpaqueBuffer);
                    AfterOpaqueBuffer = WeatherMakerFullScreenEffect.CreateRenderTexture(WeatherMakerFullScreenEffect.GetRenderTextureDescriptor(1, 1, 1, RenderTextureFormat.DefaultHDR, 0, camera));
                }
                afterForwardOpaqueCommandBuffer = new CommandBuffer {
                    name = afterForwardOpaqueCommandBufferName + Time.unscaledDeltaTime
                };
                afterForwardOpaqueCommandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, AfterOpaqueBuffer);
                afterForwardOpaqueCommandBuffer.SetGlobalTexture(WMS._CameraOpaqueTexture, AfterOpaqueBuffer);
            }
            if (camera.clearFlags == CameraClearFlags.Skybox)
            {
                camera.AddCommandBuffer(CameraEvent.AfterSkybox, afterForwardOpaqueCommandBuffer);
            }
            else
            {
                camera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, afterForwardOpaqueCommandBuffer);
            }
#endif
        }
Example #4
0
 private static void DestroyInscatteringTextures()
 {
     WeatherMakerFullScreenEffect.DestroyRenderTexture(ref extinctionLUT);
     WeatherMakerFullScreenEffect.DestroyRenderTexture(ref inscatteringLUT);
     WeatherMakerFullScreenEffect.DestroyRenderTexture(ref extinctionLUT2);
     WeatherMakerFullScreenEffect.DestroyRenderTexture(ref inscatteringLUT2);
 }
Example #5
0
        /// <summary>
        /// Awake
        /// </summary>
        protected override void Awake()
        {
            if (WeatherMakerScript.Instance == null)
            {
                return;
            }

            // create fog profile now, base.Start will also create it but uses a non-full screen profile default
            if (FogProfile == null)
            {
                FogProfile = WeatherMakerScript.Instance.LoadResource <WeatherMakerFullScreenFogProfileScript>("WeatherMakerFullScreenFogProfile_Default");
            }

            base.Awake();

            effect = new WeatherMakerFullScreenEffect
            {
                CommandBufferName = commandBufferName,
                RenderQueue       = FogRenderQueue
            };

            if (Application.isPlaying)
            {
                FogFullScreenMaterial = new Material(FogFullScreenMaterial);
                FogBlurMaterial       = new Material(FogBlurMaterial);
            }
        }
 private void CameraPreCull(Camera camera)
 {
     if (!WeatherMakerScript.ShouldIgnoreCamera(this, camera))
     {
         commandBuffer.Clear();
         if (BlurMaterial != null)
         {
             RenderTextureFormat     format = (camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default);
             RenderTextureDescriptor desc1  = WeatherMakerFullScreenEffect.GetRenderTextureDescriptor((int)Scale, 1, 1, format, 0, camera);
             RenderTextureDescriptor desc2  = WeatherMakerFullScreenEffect.GetRenderTextureDescriptor(1, 1, 1, format, 0, camera);
             commandBuffer.GetTemporaryRT(WMS._MainTex2, desc1);
             commandBuffer.GetTemporaryRT(WMS._MainTex3, desc2);
             commandBuffer.SetRenderTarget(WMS._MainTex2);
             commandBuffer.ClearRenderTarget(true, true, Color.clear);
             commandBuffer.SetGlobalFloat(WMS._WeatherMakerDownsampleScale, (float)Scale);
             commandBuffer.DrawRenderer(Renderer, Renderer.sharedMaterial, 0, 0); // draw pass
             commandBuffer.SetRenderTarget(WMS._MainTex3);
             commandBuffer.ClearRenderTarget(true, true, Color.clear);
             commandBuffer.DrawRenderer(Renderer, Renderer.sharedMaterial, 0, 1); // depth pass
             commandBuffer.SetGlobalTexture(WMS._WeatherMakerTemporaryDepthTexture, WMS._MainTex3);
             commandBuffer.SetGlobalFloat(WMS._DstBlendMode, (float)BlendMode.OneMinusSrcAlpha);
             commandBuffer.Blit(WMS._MainTex2, WeatherMakerFullScreenEffect.CameraTargetIdentifier(), BlurMaterial, 0);
             commandBuffer.ReleaseTemporaryRT(WMS._MainTex2);
             commandBuffer.ReleaseTemporaryRT(WMS._MainTex3);
             camera.AddCommandBuffer(CameraEvent, commandBuffer);
         }
     }
 }
Example #7
0
        private void CameraPreCull(Camera camera)
        {
            if (WeatherMakerCommandBufferManagerScript.CameraStack == 1 && WeatherMakerScript.GetCameraType(camera) == WeatherMakerCameraType.Normal)
            {
                // render cloud shadows at half scale for large screens
                int scale = (WeatherMakerScript.Instance == null || WeatherMakerScript.Instance.PerformanceProfile == null ? (UnityEngine.XR.XRDevice.isPresent || Screen.width > 2000 ? 4 : 2) :
                             (int)WeatherMakerScript.Instance.PerformanceProfile.VolumetricCloudShadowDownsampleScale);
                tempShadowBuffer            = RenderTexture.GetTemporary(WeatherMakerFullScreenEffect.GetRenderTextureDescriptor(scale, 0, 1, RenderTextureFormat.ARGB32, 0, camera));
                tempShadowBuffer.wrapMode   = TextureWrapMode.Clamp;
                tempShadowBuffer.filterMode = FilterMode.Bilinear;
                AddScreenSpaceShadowsCommandBuffer(camera);

                // ensure that the any shader using cloud shadows knows the correct cloud shadow parameters
                if (CloudShadowMaterial != null)
                {
                    Shader.SetGlobalFloat(WMS._CloudShadowMapAdder, CloudShadowMaterial.GetFloat(WMS._CloudShadowMapAdder));
                    Shader.SetGlobalFloat(WMS._CloudShadowMapMultiplier, CloudShadowMaterial.GetFloat(WMS._CloudShadowMapMultiplier));
                    Shader.SetGlobalFloat(WMS._CloudShadowMapPower, CloudShadowMaterial.GetFloat(WMS._CloudShadowMapPower));
                    Shader.SetGlobalFloat(WMS._WeatherMakerCloudVolumetricShadowDither, CloudShadowMaterial.GetFloat(WMS._WeatherMakerCloudVolumetricShadowDither));
                    Shader.SetGlobalTexture(WMS._WeatherMakerCloudShadowDetailTexture, CloudShadowMaterial.GetTexture(WMS._WeatherMakerCloudShadowDetailTexture));
                    Shader.SetGlobalFloat(WMS._WeatherMakerCloudShadowDetailScale, CloudShadowMaterial.GetFloat(WMS._WeatherMakerCloudShadowDetailScale));
                    Shader.SetGlobalFloat(WMS._WeatherMakerCloudShadowDetailIntensity, CloudShadowMaterial.GetFloat(WMS._WeatherMakerCloudShadowDetailIntensity));
                    Shader.SetGlobalFloat(WMS._WeatherMakerCloudShadowDetailFalloff, CloudShadowMaterial.GetFloat(WMS._WeatherMakerCloudShadowDetailFalloff));
                    Shader.SetGlobalFloat(WMS._WeatherMakerCloudShadowDistanceFade, CloudShadowMaterial.GetFloat(WMS._WeatherMakerCloudShadowDistanceFade));
                }
            }
        }
        protected override void Start()
        {
            // create fog profile now, base.Start will also create it but uses a non-full screen profile default
            if (FogProfile == null)
            {
                FogProfile = Resources.Load <WeatherMakerFullScreenFogProfileScript>("WeatherMakerFullScreenFogProfile_Default");
            }
            updateShaderPropertiesAction = UpdateShaderProperties;

            base.Start();

            effect = new WeatherMakerFullScreenEffect
            {
                CommandBufferName = commandBufferName,
                DownsampleRenderBufferTextureName = "_MainTex2",
                RenderQueue = FogRenderQueue
            };

#if UNITY_EDITOR
            if (Application.isPlaying)
            {
#endif

            FogFullScreenMaterial = new Material(FogFullScreenMaterial);
            FogBlurMaterial       = new Material(FogBlurMaterial);

#if UNITY_EDITOR
        }
#endif
        }
 private void EnsureProfile()
 {
     if (emptyProfile == null)
     {
         emptyProfile = Resources.Load <WeatherMakerCloudProfileScript>("WeatherMakerCloudProfile_None");
         emptyProfile = emptyProfile.Clone();
     }
     if (_CloudProfile == null)
     {
         _CloudProfile = emptyProfile;
     }
     if (effect == null)
     {
         lastProfile = currentRenderCloudProfile = _CloudProfile;
         currentRenderCloudProfileIsTemporary = false;
         updateShaderPropertiesAction         = UpdateShaderProperties;
         effect = new WeatherMakerFullScreenEffect
         {
             CommandBufferName = "WeatherMakerFullScreenCloudsScript",
             DownsampleRenderBufferTextureName = "_MainTex2",
             RenderQueue = RenderQueue,
             ZTest       = CompareFunction.LessEqual
         };
     }
 }
 private void CleanupEffect()
 {
     if (Effect != null)
     {
         Effect.Dispose();
         Effect = null;
     }
 }
Example #11
0
 private void CleanupDepthTextures()
 {
     HalfDepthBuffer      = WeatherMakerFullScreenEffect.DestroyRenderTexture(HalfDepthBuffer);
     QuarterDepthBuffer   = WeatherMakerFullScreenEffect.DestroyRenderTexture(QuarterDepthBuffer);
     EighthDepthBuffer    = WeatherMakerFullScreenEffect.DestroyRenderTexture(EighthDepthBuffer);
     SixteenthDepthBuffer = WeatherMakerFullScreenEffect.DestroyRenderTexture(SixteenthDepthBuffer);
     WeatherMakerFullScreenEffect.ReleaseCommandBuffer(ref depthCommandBuffer);
 }
Example #12
0
 private void Start()
 {
     effect = new WeatherMakerFullScreenEffect
     {
         CommandBufferName = "WeatherMakerFullScreenCloudsScript",
         DownsampleRenderBufferTextureName = "_MainTex2",
         RenderQueue = RenderQueue,
         ZTest       = CompareFunction.LessEqual
     };
 }
Example #13
0
        public void PreCullFrame(Camera camera, WeatherMakerDownsampleScale scale, WeatherMakerTemporalReprojectionSize projSize)
        {
            if (TemporalReprojectionMaterial == null)
            {
                return;
            }
            WeatherMakerCameraType cameraType = WeatherMakerScript.GetCameraType(camera);

            if (cameraType == WeatherMakerCameraType.Other)
            {
                return;
            }
            int projSizeInt  = (int)projSize;
            int downsampling = (int)scale;
            int frameWidth   = camera.pixelWidth / downsampling;
            int frameHeight  = camera.pixelHeight / downsampling;

            // ensure reprojection fits cleanly into frame
            while (frameWidth % projSizeInt != 0)
            {
                frameWidth++;
            }
            while (frameHeight % projSizeInt != 0)
            {
                frameHeight++;
            }

            if (frameWidth != FrameWidth || frameHeight != FrameHeight || ReprojectionSize != projSizeInt)
            {
                DisposeRenderTextures();
                ReprojectionSize        = projSizeInt;
                ReprojectionSizeSquared = ReprojectionSize * ReprojectionSize;
                CreateFrameNumbers();
                FrameWidth     = frameWidth;
                FrameHeight    = frameHeight;
                SubFrameWidth  = frameWidth / projSizeInt;
                SubFrameHeight = frameHeight / projSizeInt;

                RenderTextureFormat     format       = camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;
                RenderTextureDescriptor descSubFrame = WeatherMakerFullScreenEffect.GetRenderTextureDescriptor(downsampling, projSizeInt, projSizeInt, format, 0, camera);
                subFrameCurrent      = WeatherMakerFullScreenEffect.CreateRenderTexture(descSubFrame, FilterMode.Bilinear, TextureWrapMode.Clamp);
                subFrameCurrent.name = "WeatherMakerTemporalReprojectionSubFrame";
                RenderTextureDescriptor descPrevFrame = WeatherMakerFullScreenEffect.GetRenderTextureDescriptor(downsampling, projSizeInt, 1, format, 0, camera);
                prevFrameCurrent      = WeatherMakerFullScreenEffect.CreateRenderTexture(descPrevFrame, FilterMode.Bilinear, TextureWrapMode.Clamp);
                prevFrameCurrent.name = "WeatherMakerTemporalReprojectionPrevFrame";

                OffsetXConstant         = (1.0f / (float)frameWidth);
                OffsetYConstant         = (1.0f / (float)frameHeight);
                OffsetXConstant2        = (-0.5f * (float)(ReprojectionSize - 1) * OffsetXConstant);
                OffsetYConstant2        = (-0.5f * (float)(ReprojectionSize - 1) * OffsetYConstant);
                NeedsFirstFrameHandling = true;
            }

            ComputeTemporalOffsets();
        }
Example #14
0
        private RenderTargetIdentifier UpdateDepthDownsampler(ref RenderTexture tex, int scale)
        {
            RenderTextureDescriptor desc = WeatherMakerFullScreenEffect.GetRenderTextureDescriptor(scale, 0, 1, RenderTextureFormat.RFloat);

            if (tex == null || tex.width != desc.width || tex.height != desc.height)
            {
                WeatherMakerFullScreenEffect.DestroyRenderTexture(ref tex);
                tex      = WeatherMakerFullScreenEffect.CreateRenderTexture(desc, FilterMode.Point, TextureWrapMode.Clamp);
                tex.name = "WeatherMakerDepthTexture_" + scale;
            }
            return(tex);
        }
        private void UpdateEffectProperties()
        {
            if (Effect == null)
            {
                Effect = new WeatherMakerFullScreenEffect
                {
                    CommandBufferName = this.CommandBufferName,
                    RenderQueue       = OverlayRenderQueue
                };
            }
            SetupEffect(Effect);
            bool showOverlay = (OverlayProfile != null && !OverlayProfile.Disabled && (OverlayProfile.OverlayIntensity > 0.0001f || OverlayProfile.AutoIntensityMultiplier != 0.0f || OverlayProfile.OverlayMinimumIntensity > 0.0001f) && OverlayProfile.OverlayColor.a > 0.0f);

            if (showOverlay)
            {
                OverlayProfile.Update();
            }
            updateShaderPropertiesAction = (updateShaderPropertiesAction ?? UpdateShaderProperties);
            Effect.SetupEffect(OverlayMaterial, OverlayAlphaMaterial, OverlayBlurMaterial, BlurShader, DownSampleScale, WeatherMakerDownsampleScale.Disabled, WeatherMakerDownsampleScale.Disabled,
                               null, WeatherMakerTemporalReprojectionSize.None, updateShaderPropertiesAction, showOverlay);
        }
Example #16
0
        private static void DestroyTextures()
        {
            DestroyInscatteringTextures();
            WeatherMakerFullScreenEffect.DestroyRenderTexture(ref lightColorTexture);
            WeatherMakerFullScreenEffect.DestroyRenderTexture(ref skyboxLUT);
            WeatherMakerFullScreenEffect.DestroyRenderTexture(ref skyboxLUT);

#if WEATHER_MAKER_ATMOSPHERE_HIGH_QUALITY
            WeatherMakerFullScreenEffect.DestroyRenderTexture(ref skyboxLUT2);
#endif

            if (randomVectorsLUT != null)
            {
                GameObject.DestroyImmediate(randomVectorsLUT);
                randomVectorsLUT = null;
            }
            if (particleDensityLUT != null)
            {
                GameObject.DestroyImmediate(particleDensityLUT);
                particleDensityLUT = null;
            }
        }
        protected override void Start()
        {
            base.Start();

            effect = new WeatherMakerFullScreenEffect
            {
                CommandBufferName = commandBufferName,
                DownsampleRenderBufferTextureName = "_MainTex2",
                RenderQueue = FogRenderQueue
            };

#if UNITY_EDITOR
            if (Application.isPlaying)
            {
#endif

            FogBlurMaterial = new Material(FogBlurMaterial);

#if UNITY_EDITOR
        }
#endif
        }
Example #18
0
 private void DisposeRenderTextures()
 {
     WeatherMakerFullScreenEffect.DestroyRenderTexture(ref subFrameCurrent);
     WeatherMakerFullScreenEffect.DestroyRenderTexture(ref prevFrameCurrent);
 }
 /// <summary>
 /// Setup an effect
 /// </summary>
 /// <param name="effect">Effect to setup</param>
 protected virtual void SetupEffect(WeatherMakerFullScreenEffect effect)
 {
 }
Example #20
0
        private void AddScreenSpaceShadowsCommandBuffer(Camera camera)
        {
            if (CloudShadowMaterial != null && _light != null && _light.type == LightType.Directional &&
                _light.shadows != LightShadows.None && WeatherMakerLightManagerScript.Instance != null &&
                WeatherMakerLightManagerScript.ScreenSpaceShadowMode != BuiltinShaderMode.Disabled &&
                (WeatherMakerScript.Instance == null || WeatherMakerScript.Instance.PerformanceProfile == null ||
                 (WeatherMakerScript.Instance.PerformanceProfile.VolumetricCloudShadowDownsampleScale != WeatherMakerDownsampleScale.Disabled &&
                  WeatherMakerScript.Instance.PerformanceProfile.VolumetricCloudShadowSampleCount > 0)))
            {
                if (_commandBufferScreenSpaceShadows1 == null)
                {
                    // copy the screen space shadow texture for re-use later
                    _commandBufferScreenSpaceShadows1 = new CommandBuffer {
                        name = "WeatherMakerShadowMapScreensSpaceShadowScriptBlur_" + gameObject.name
                    };
                }
                if (_commandBufferScreenSpaceShadows2 == null)
                {
                    // copy the screen space shadow texture for re-use later
                    _commandBufferScreenSpaceShadows2 = new CommandBuffer {
                        name = "WeatherMakerShadowMapScreensSpaceShadowScriptBlit_" + gameObject.name
                    };
                }

                _commandBufferScreenSpaceShadows1.Clear();
                _commandBufferScreenSpaceShadows1.SetGlobalFloat(WMS._BlendOp, (float)BlendOp.Add);
                _commandBufferScreenSpaceShadows1.SetGlobalFloat(WMS._SrcBlendMode, (float)BlendMode.One);
                _commandBufferScreenSpaceShadows1.SetGlobalFloat(WMS._DstBlendMode, (float)BlendMode.Zero);

#if UNITY_LWRP
                _commandBufferScreenSpaceShadows1.SetGlobalTexture(WMS._MainTex5, WMS._ScreenSpaceShadowmapTexture);
                _commandBufferScreenSpaceShadows1.Blit(WMS._ScreenSpaceShadowmapTexture, tempShadowBuffer, CloudShadowMaterial, 0);
                camera.AddCommandBuffer(CameraEvent.BeforeForwardOpaque, _commandBufferScreenSpaceShadows1);
#else
                _commandBufferScreenSpaceShadows1.SetGlobalTexture(WMS._MainTex5, BuiltinRenderTextureType.CurrentActive);
                _commandBufferScreenSpaceShadows1.Blit(BuiltinRenderTextureType.CurrentActive, tempShadowBuffer, CloudShadowMaterial, 0);
                _light.AddCommandBuffer(LightEvent.AfterScreenspaceMask, _commandBufferScreenSpaceShadows1);
#endif

                // screen space shadow mask does not use concept of stereo, so turn it off
                _commandBufferScreenSpaceShadows2.Clear();
                _commandBufferScreenSpaceShadows2.SetGlobalFloat(WMS._SrcBlendMode, (float)BlendMode.One);
                _commandBufferScreenSpaceShadows2.SetGlobalFloat(WMS._DstBlendMode, (float)BlendMode.One);
                _commandBufferScreenSpaceShadows2.SetGlobalFloat(WMS._WeatherMakerAdjustFullScreenUVStereoDisable, 1.0f);

#if UNITY_LWRP
                _commandBufferScreenSpaceShadows2.Blit(tempShadowBuffer, WMS._ScreenSpaceShadowmapTexture, BlurMaterial, 0);
                _commandBufferScreenSpaceShadows2.SetGlobalTexture(WeatherMakerLightManagerScript.Instance.ScreenSpaceShadowsRenderTextureName, WMS._ScreenSpaceShadowmapTexture);
#else
                _commandBufferScreenSpaceShadows2.Blit(tempShadowBuffer, BuiltinRenderTextureType.CurrentActive, BlurMaterial, 0);
                _commandBufferScreenSpaceShadows2.SetGlobalTexture(WeatherMakerLightManagerScript.Instance.ScreenSpaceShadowsRenderTextureName, BuiltinRenderTextureType.CurrentActive);
#endif

                // must be set back to 0 after the blit
                _commandBufferScreenSpaceShadows2.SetGlobalFloat(WMS._WeatherMakerAdjustFullScreenUVStereoDisable, 0.0f);

#if UNITY_LWRP
                _commandBufferScreenSpaceShadows2.SetRenderTarget(WeatherMakerFullScreenEffect.CameraTargetIdentifier());
                camera.AddCommandBuffer(CameraEvent.BeforeForwardOpaque, _commandBufferScreenSpaceShadows2);
#else
                _light.AddCommandBuffer(LightEvent.AfterScreenspaceMask, _commandBufferScreenSpaceShadows2);
#endif
            }
            else
            {
                CleanupCommandBuffers();
            }
        }
Example #21
0
        public override void PreCullCamera(Camera camera)
        {
#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                return;
            }
#endif

            bool isReflection = WeatherMakerFullScreenEffect.IsReflection(camera);
            if (!isReflection && camera.cameraType == CameraType.Game)
            {
                // move particle system around camera
                TransformParticleSystem(ParticleSystem, camera, ForwardOffset, Height, 1.0f);
                TransformParticleSystem(ParticleSystemSecondary, camera, SecondaryForwardOffset, SecondaryHeight, 1.0f);
                TransformParticleSystem(MistParticleSystem, camera, 0.0f, MistHeight, 0.0f);

                if (AnimatedTextureRenderer != null)
                {
                    if (AnimatedTextureRendererIntensityThreshold >= 1.0f)
                    {
                        AnimatedTextureRenderer.enabled = false;
                    }
                    else
                    {
                        RaycastHit hit;
                        Vector3    pos = camera.transform.position;

                        // check if something above camera, if so disable animated texture
                        if (Physics.Raycast(pos, Vector3.up, out hit, 200.0f, AnimatedTextureCollisionMaskAbove, QueryTriggerInteraction.Ignore) &&
                            hit.point.y > pos.y)
                        {
                            AnimatedTextureRenderer.enabled = false;
                        }
                        else
                        {
                            AnimatedTextureRenderer.transform.rotation = Quaternion.AngleAxis(camera.transform.rotation.eulerAngles.y, Vector3.up);
                            if (Physics.Raycast(pos, Vector3.down, out hit, 200.0f, AnimatedTextureCollisionMaskBelow, QueryTriggerInteraction.Ignore))
                            {
                                Vector3 newPos = hit.point;
                                float   y      = newPos.y;
                                newPos  += (camera.transform.forward * AnimatedTextureRendererPositionOffset.z);
                                newPos.y = y + AnimatedTextureRendererPositionOffset.y;
                                AnimatedTextureRenderer.transform.position = newPos;
                            }
                            AnimatedTextureRenderer.sharedMaterial.SetFloat("_AlphaMultiplierAnimation", Mathf.Lerp(0.0f, 1.0f, Mathf.Pow(Intensity / Mathf.Max(0.01f, AnimatedTextureRendererIntensityThreshold), 3.0f)));
                            AnimatedTextureRenderer.enabled = (AnimatedTextureRenderer.sharedMaterial.GetFloat("_AlphaMultiplierAnimation") > 0.0f);
                        }
                    }
                }

                // if we have a world space particle system, simulate it in front of the new camera (i.e. snow), moving the camera multiple
                //  times per frame will not emit particles each time it is moved unfortunately
                if (Intensity > 0.0f && (lastCamera == null || lastCamera != camera) && ParticleSystem.isPlaying &&
                    ParticleSystem.main.simulationSpace == ParticleSystemSimulationSpace.World)
                {
                    ParticleSystem.Emit((int)Mathf.Round(ParticleSystem.emission.rateOverTime.constant * Time.deltaTime));
                }
                lastCamera = camera;
            }
        }