Beispiel #1
0
        public void PostRenderFrame(Camera camera)
        {
            if (TemporalReprojectionMaterial == null)
            {
                return;
            }
            WeatherMakerCameraType cameraType = WeatherMakerScript.GetCameraType(camera);

            if (cameraType == WeatherMakerCameraType.Other)
            {
                return;
            }

            // turn off first frame handling
            NeedsFirstFrameHandling = false;

            prevView[0] = view[0];
            prevView[1] = view[1];

            // move to next temporal reprojection frame
            unchecked
            {
                //if (++debugCount % 60 == 0)
                {
                    if (++frameIndex == frameNumbers.Length)
                    {
                        frameIndex = 0;
                    }
                    SubFrameNumber = frameNumbers[frameIndex];
                }
            }
        }
Beispiel #2
0
        private void SetupCommandBufferForCamera(Camera camera)
        {
#if !UNITY_SERVER
            if (camera == null)
            {
                return;
            }

            WeatherMakerCameraProperties props      = GetCameraProperties(camera);
            WeatherMakerCameraType       cameraType = WeatherMakerScript.GetCameraType(camera);
            Camera baseCamera = WeatherMakerCommandBufferManagerScript.BaseCamera;
            UpdateDeferredShadingKeyword(camera);
            CalculateMatrixes(camera, baseCamera);
            CalculateFrustumCorners(camera);
            Shader.SetGlobalMatrixArray(WMS._WeatherMakerInverseView, inverseView);
            Shader.SetGlobalMatrixArray(WMS._WeatherMakerInverseProj, inverseProj);
            Shader.SetGlobalMatrixArray(WMS._WeatherMakerView, view);
            Shader.SetGlobalVectorArray(WMS._WeatherMakerCameraFrustumCorners, cameraFrustumCorners);
            Shader.SetGlobalVector(WMS._WeatherMakerCameraOriginOffset, props.OriginOffsetCumulative);
            Shader.SetGlobalVector(WMS._WeatherMakerCameraPosComputeShader, camera.transform.position);
            if (cameraType == WeatherMakerCameraType.CubeMap)
            {
                Shader.SetGlobalFloat(WMS._WeatherMakerCameraRenderMode, 2.0f);
            }
            else if (cameraType == WeatherMakerCameraType.Reflection)
            {
                Shader.SetGlobalFloat(WMS._WeatherMakerCameraRenderMode, 1.0f);
            }
            else
            {
                Shader.SetGlobalFloat(WMS._WeatherMakerCameraRenderMode, 0.0f);
            }
#endif
        }
Beispiel #3
0
        public void PreRenderFrame(Camera camera, Camera lastNormalCamera, CommandBuffer commandBuffer)
        {
            if (TemporalReprojectionMaterial == null)
            {
                return;
            }
            WeatherMakerCameraType cameraType = WeatherMakerScript.GetCameraType(camera);

            if (cameraType == WeatherMakerCameraType.Other)
            {
                return;
            }

            lastNormalCamera = (cameraType == WeatherMakerCameraType.Normal ? camera : (lastNormalCamera ?? camera));

            // assign current matrixes, only normal stereo cameras use the stereo methods
            // reflection cameras are rendered one eye at a time without stereo
            if (camera.stereoEnabled)
            {
                view[0]                  = camera.GetStereoViewMatrix(Camera.StereoscopicEye.Left);
                view[1]                  = camera.GetStereoViewMatrix(Camera.StereoscopicEye.Right);
                projection[0]            = lastNormalCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left);
                projection[1]            = lastNormalCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right);
                inverseView[0]           = view[0].inverse;
                inverseView[1]           = view[1].inverse;
                inverseProjection[0]     = projection[0].inverse;
                inverseProjection[1]     = projection[1].inverse;
                inverseProjectionView[0] = inverseProjection[0] * inverseView[0];
                inverseProjectionView[1] = inverseProjection[1] * inverseView[1];
                prevViewProjection[0]    = (projection[0] * prevView[0]);
                prevViewProjection[1]    = (projection[1] * prevView[1]);
                ipivpvp[0]               = projection[0] * prevView[0] * inverseView[0] * inverseProjection[0];
                ipivpvp[1]               = projection[1] * prevView[1] * inverseView[1] * inverseProjection[1];
            }
            else
            {
                view[0]                  = view[1] = camera.worldToCameraMatrix;
                inverseView[0]           = inverseView[1] = camera.cameraToWorldMatrix;
                projection[0]            = projection[1] = lastNormalCamera.projectionMatrix;
                inverseProjection[0]     = inverseProjection[1] = lastNormalCamera.projectionMatrix.inverse;
                inverseProjectionView[0] = inverseProjectionView[1] = inverseView[0] * inverseProjection[0];
                prevViewProjection[0]    = prevViewProjection[1] = (projection[0] * prevView[0]);
                ipivpvp[0]               = ipivpvp[1] = projection[0] * prevView[0] * inverseView[0] * inverseProjection[0];
            }

            commandBuffer.SetGlobalTexture(WMS._TemporalReprojection_SubFrame, SubFrameTexture);
            commandBuffer.SetGlobalTexture(WMS._TemporalReprojection_PrevFrame, PrevFrameTexture);
            commandBuffer.SetGlobalFloat(WMS._TemporalReprojection_BlendMode, (float)BlendMode);
            commandBuffer.SetGlobalFloat(WMS._TemporalReprojection_SubPixelSize, ReprojectionSize);
            commandBuffer.SetGlobalFloat(WMS._TemporalReprojection_SubFrameNumber, SubFrameNumber);
            commandBuffer.SetGlobalFloat(WMS._TemporalReprojection_SimilarityMax, TemporalReprojectionMaterial.GetFloat(WMS._TemporalReprojection_SimilarityMax));
            commandBuffer.SetGlobalMatrixArray(WMS._TemporalReprojection_PreviousView, prevView);
            commandBuffer.SetGlobalMatrixArray(WMS._TemporalReprojection_View, view);
            commandBuffer.SetGlobalMatrixArray(WMS._TemporalReprojection_InverseView, inverseView);
            commandBuffer.SetGlobalMatrixArray(WMS._TemporalReprojection_Projection, projection);
            commandBuffer.SetGlobalMatrixArray(WMS._TemporalReprojection_InverseProjection, inverseProjection);
            commandBuffer.SetGlobalMatrixArray(WMS._TemporalReprojection_InverseProjectionView, inverseProjectionView);
            commandBuffer.SetGlobalMatrixArray(WMS._TemporalReprojection_PreviousViewProjection, prevViewProjection);
            commandBuffer.SetGlobalMatrixArray(WMS._TemporalReprojection_ipivpvp, ipivpvp);
        }
Beispiel #4
0
        private void SetupCommandBufferForCamera(Camera camera)
        {
            if (camera == null)
            {
                return;
            }

            WeatherMakerCameraType cameraType = WeatherMakerScript.GetCameraType(camera);
            Camera baseCamera = WeatherMakerCommandBufferManagerScript.BaseCamera;

            UpdateDeferredShadingKeyword(camera);
            CalculateMatrixes(camera, baseCamera);
            CalculateFrustumCorners(camera);
            Shader.SetGlobalMatrixArray(WMS._WeatherMakerInverseView, inverseView);
            Shader.SetGlobalMatrixArray(WMS._WeatherMakerInverseProj, inverseProj);
            Shader.SetGlobalMatrixArray(WMS._WeatherMakerView, view);
            Shader.SetGlobalVectorArray(WMS._WeatherMakerCameraFrustumCorners, cameraFrustumCorners);
            Shader.SetGlobalVector(WMS._WeatherMakerCameraPos, camera.transform.position);
            if (cameraType == WeatherMakerCameraType.CubeMap || camera == WeatherMakerCommandBufferManagerScript.CubemapCamera)
            {
                Shader.SetGlobalFloat(WMS._WeatherMakerCameraRenderMode, 2.0f);
            }
            else if (cameraType == WeatherMakerCameraType.Reflection)
            {
                Shader.SetGlobalFloat(WMS._WeatherMakerCameraRenderMode, 1.0f);
            }
            else
            {
                Shader.SetGlobalFloat(WMS._WeatherMakerCameraRenderMode, 0.0f);
            }
        }
        private void CameraPostRender(Camera camera)
        {
            if (WeatherMakerScript.Instance == null || WeatherMakerScript.Instance.PerformanceProfile == null)
            {
                return;
            }

            WeatherMakerCameraType cameraType = WeatherMakerScript.GetCameraType(camera);

            if ((WeatherMakerCommandBufferManagerScript.CameraStack == 0 && cameraType == WeatherMakerCameraType.Normal) ||
                (cameraType == WeatherMakerCameraType.Reflection && WeatherMakerScript.Instance.PerformanceProfile.VolumetricCloudReflectionShadows))
            {
                RenderTexture.ReleaseTemporary(tempShadowBuffer);

#if UNITY_URP
                if (_commandBufferDepthShadows != null)
                {
                    camera.RemoveCommandBuffer(CameraEvent.BeforeForwardOpaque, _commandBufferDepthShadows);
                }
                if (_commandBufferScreenSpaceShadows1 != null)
                {
                    camera.RemoveCommandBuffer(CameraEvent.BeforeForwardOpaque, _commandBufferScreenSpaceShadows1);
                }
                if (_commandBufferScreenSpaceShadows2 != null)
                {
                    camera.RemoveCommandBuffer(CameraEvent.BeforeForwardOpaque, _commandBufferScreenSpaceShadows2);
                }
#else
                RemoveCommandBuffer(LightEvent.AfterScreenspaceMask, ref _commandBufferScreenSpaceShadows1, false);
                RemoveCommandBuffer(LightEvent.AfterScreenspaceMask, ref _commandBufferScreenSpaceShadows2, false);
#endif
            }
        }
        private void CameraPreCull(Camera camera)
        {
            if (WeatherMakerScript.Instance == null || WeatherMakerScript.Instance.PerformanceProfile == null)
            {
                return;
            }

            WeatherMakerCameraType cameraType = WeatherMakerScript.GetCameraType(camera);

            if ((WeatherMakerCommandBufferManagerScript.CameraStack == 1 && cameraType == WeatherMakerCameraType.Normal) ||
                (cameraType == WeatherMakerCameraType.Reflection && WeatherMakerScript.Instance.PerformanceProfile.VolumetricCloudReflectionShadows))
            {
                // render cloud shadows at half scale for large screens
                int scale = (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));
                }
            }
        }
Beispiel #7
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();
        }
        /// <summary>
        /// Determine if a camera should be rendered in weather maker
        /// </summary>
        /// <param name="script">Script</param>
        /// <param name="camera">Camera</param>
        /// <param name="ignoreReflections">Whether to ignore reflection cameras (i.e. water reflection or mirror)</param>
        /// <returns>True to ignore, false to render</returns>
        public static bool ShouldIgnoreCamera(MonoBehaviour script, Camera camera, bool ignoreReflections = true)
        {
            if (camera == null || Instance == null || script == null || !script.enabled || !script.gameObject.activeInHierarchy ||
                camera.cameraType == UnityEngine.CameraType.Preview || (Instance.AllowCameras.Count == 0 && Instance.AllowCamerasNames.Count == 0 && Instance.AllowCamerasNamesPartial.Count == 0) ||
                (camera.CachedName().IndexOf("depth", System.StringComparison.OrdinalIgnoreCase) >= 0))
            {
                return(true);
            }

#if UNITY_EDITOR
            else if (camera.cameraType == UnityEngine.CameraType.SceneView)
            {
                return(WeatherMakerScript.Instance == null || !WeatherMakerScript.Instance.AllowSceneCamera);
            }
#endif

            WeatherMakerCameraType type = WeatherMakerScript.GetCameraType(camera);

            // if camera is not in allow list and
            // camera is not an allowed reflection camera and
            // camera is not an allowed reflection probe camera
            // then ignore it
            bool notInAllowList     = !Instance.AllowCameras.Contains(camera);
            bool notInAllowNameList = true;
            foreach (string s in Instance.AllowCamerasNames)
            {
                if (camera.CachedName() == s)
                {
                    notInAllowNameList = false;
                    break;
                }
            }
            if (notInAllowNameList)
            {
                foreach (string s in Instance.AllowCamerasNamesPartial)
                {
                    if (camera.CachedName().IndexOf(s, System.StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        notInAllowNameList = false;
                        break;
                    }
                }
            }
            bool ignoreReflection = (ignoreReflections || type != WeatherMakerCameraType.Reflection);
            bool ignoreProbe      = (Instance.PerformanceProfile.IgnoreReflectionProbes || type != WeatherMakerCameraType.CubeMap);
            bool ignore           = notInAllowList && notInAllowNameList && ignoreReflection && ignoreProbe;
            return(ignore);
        }
Beispiel #9
0
        /// <summary>
        /// Update the full screen effect, usually called from OnPreRender or OnPreCull
        /// </summary>
        /// <param name="camera">Camera</param>
        /// <param name="integratedTemporalReprojection">Whether to use integrated temporal reprojection (if temporal reprojection is enabled)</param>
        public void PreCullCamera(Camera camera, bool integratedTemporalReprojection = true)
        {
            //integratedTemporalReprojection = false;
            if (WeatherMakerScript.Instance != null && WeatherMakerScript.Instance.CommandBufferManager != null && (Enabled || preSetupCommandBuffer != null) &&
                Material != null && clonedMaterial != null && camera != null)
            {
                WeatherMakerCameraType cameraType = WeatherMakerScript.GetCameraType(camera);
                if (cameraType == WeatherMakerCameraType.Other)
                {
                    return;
                }

                WeatherMakerTemporalReprojectionState reprojState     = null;
                WeatherMakerDownsampleScale           downsampleScale = DownsampleScale;
                if (cameraType != WeatherMakerCameraType.Normal)
                {
                    if (camera.pixelWidth > 2000)
                    {
                        downsampleScale = WeatherMakerDownsampleScale.QuarterResolution;
                    }
                    else if (camera.pixelWidth > 1000)
                    {
                        downsampleScale = WeatherMakerDownsampleScale.HalfResolution;
                    }
                }

                if (Enabled)
                {
                    // setup temporal reprojection state
                    reprojState = temporalStates.Find(b => b.Camera == camera);

                    if (reprojState == null)
                    {
                        // temporal reprojection is not currently possible with cubemap
                        if (TemporalReprojection != WeatherMakerTemporalReprojectionSize.None && TemporalReprojectionMaterial != null &&
                            (cameraType == WeatherMakerCameraType.Normal || cameraType == WeatherMakerCameraType.Reflection))
                        {
                            reprojState = new WeatherMakerTemporalReprojectionState(camera, TemporalReprojectionMaterial, integratedTemporalReprojection);
                            temporalStates.Add(reprojState);
                        }
                    }
                    else if (TemporalReprojection == WeatherMakerTemporalReprojectionSize.None || TemporalReprojectionMaterial == null)
                    {
                        reprojState.Dispose();
                        temporalStates.Remove(reprojState);
                        reprojState = null;
                    }

                    if (reprojState != null)
                    {
                        WeatherMakerTemporalReprojectionSize reprojSize = (cameraType == WeatherMakerCameraType.Normal ? TemporalReprojection : WeatherMakerTemporalReprojectionSize.FourByFour);
                        reprojState.PreCullFrame(camera, downsampleScale, reprojSize);
                    }
                }
                WeatherMakerCommandBuffer cmdBuffer = CreateCommandBuffer(camera, reprojState, downsampleScale, preSetupCommandBuffer);
                if (reprojState != null)
                {
                    reprojState.CommandBuffer = cmdBuffer;
                }
            }
        }
Beispiel #10
0
        private WeatherMakerCommandBuffer CreateCommandBuffer(Camera camera, WeatherMakerTemporalReprojectionState reprojState, WeatherMakerDownsampleScale downsampleScale,
                                                              System.Action <WeatherMakerCommandBuffer> preSetupCommandBuffer)
        {
            if (WeatherMakerScript.Instance == null)
            {
                Debug.LogError("Cannot create command buffer, WeatherMakerScript.Instance is null");
                return(null);
            }

            // Debug.Log("Creating command buffer " + CommandBufferName);

            WeatherMakerCommandBuffer weatherMakerCommandBuffer = GetOrCreateWeatherMakerCommandBuffer(camera);

            // multi-pass vr uses one command buffer for each eye
            if (camera.stereoTargetEye == StereoTargetEyeMask.Right)
            {
                weatherMakerCommandBuffer.Camera = camera;
                return(weatherMakerCommandBuffer);
            }
            else if (weatherMakerCommandBuffer != null && weatherMakerCommandBuffer.CommandBuffer != null)
            {
                camera.RemoveCommandBuffer(RenderQueue, weatherMakerCommandBuffer.CommandBuffer);
                weatherMakerCommandBuffer.CommandBuffer.Clear();
            }

            RenderTextureFormat defaultFormat = (camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default);
            CommandBuffer       commandBuffer = weatherMakerCommandBuffer.CommandBuffer;
            int postSourceId = -1;
            RenderTargetIdentifier postSource = postSourceId;
            WeatherMakerCameraType cameraType = weatherMakerCommandBuffer.CameraType;

            // setup reprojection state
            if (reprojState != null)
            {
                reprojState.PreRenderFrame(camera, WeatherMakerCommandBufferManagerScript.BaseCamera, commandBuffer);
                if (!reprojState.NeedsFirstFrameHandling && reprojState.BlendMode == WeatherMakerTemporalReprojectionState.TemporalReprojectionBlendMode.Sharp)
                {
                    float xo = reprojState.TemporalOffsetX;
                    float yo = reprojState.TemporalOffsetY;
                    commandBuffer.SetGlobalVector(WMS._WeatherMakerTemporalUV, new Vector4(xo, yo, 1.0f, 1.0f));
                }
                else
                {
                    commandBuffer.SetGlobalVector(WMS._WeatherMakerTemporalUV, Vector4.zero);
                }
            }

            int scale = (int)downsampleScale;

            if (reprojState != null && reprojState.BlendMode == WeatherMakerTemporalReprojectionState.TemporalReprojectionBlendMode.Blur)
            {
                int totalDownScale = (scale * reprojState.ReprojectionSize);
                switch (totalDownScale)
                {
                case 0:
                case 1:
                    totalDownScale = 1;
                    break;

                case 2:
                case 3:
                    totalDownScale = 2;
                    break;

                case 4:
                case 5:
                    totalDownScale = 4;
                    break;

                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                    totalDownScale = 8;
                    break;

                default:
                    totalDownScale = 16;
                    break;
                }
                //Debug.LogFormat("Total down scale: {0}, {1}, {2}", totalDownScale, scale, reprojState.ReprojectionSize);
                commandBuffer.SetGlobalFloat(WMS._WeatherMakerDownsampleScale, (float)totalDownScale);
            }
            else
            {
                commandBuffer.SetGlobalFloat(WMS._WeatherMakerDownsampleScale, scale);
            }

            if (preSetupCommandBuffer != null)
            {
                preSetupCommandBuffer.Invoke(weatherMakerCommandBuffer);
            }
            if (Enabled)
            {
                commandBuffer.SetGlobalFloat(WMS._WeatherMakerTemporalReprojectionEnabled, 0.0f);
                commandBuffer.SetGlobalVector(WMS._WeatherMakerTemporalUV_VertexShaderProjection, Vector4.zero);
                commandBuffer.SetGlobalVector(WMS._WeatherMakerTemporalUV_FragmentShader, Vector4.zero);

                if (DownsampleRenderBufferScale != WeatherMakerDownsampleScale.Disabled)
                {
                    // render camera target to texture, performing separate down-sampling
                    commandBuffer.GetTemporaryRT(WMS._MainTex5, GetRenderTextureDescriptor((int)DownsampleRenderBufferScale, 0, 1, defaultFormat, 0, camera), FilterMode.Bilinear);
                    commandBuffer.Blit(CameraTargetIdentifier(), WMS._MainTex5);
                }

                commandBuffer.SetGlobalFloat(WMS._ZTest, (float)ZTest);

                // if no blur, no downsample, no temporal reprojection and no post processing (pass count > 2) then we can just draw directly to camera target
                if (BlurShaderType == BlurShaderType.None && DownsampleScale == WeatherMakerDownsampleScale.FullResolution && reprojState == null && clonedMaterial.passCount < 3)
                {
                    // set blend mode for blitting to camera target
                    commandBuffer.SetGlobalFloat(WMS._SrcBlendMode, (float)SourceBlendMode);
                    commandBuffer.SetGlobalFloat(WMS._DstBlendMode, (float)DestBlendMode);
                    commandBuffer.Blit(CameraTargetIdentifier(), CameraTargetIdentifier(), clonedMaterial, 0);
                }
                else
                {
                    // render to texture, using current image target as input _MainTex, no blend
                    // alpha or blue will use _MainTex to render the final result
                    int renderTargetRenderedImageId = WMS._MainTex3;
                    int renderTargetDepthTextureId  = WMS._WeatherMakerTemporaryDepthTexture;
                    RenderTargetIdentifier renderTargetRenderedImage = new RenderTargetIdentifier(renderTargetRenderedImageId);
                    RenderTargetIdentifier renderTargetDepthTexture  = new RenderTargetIdentifier(renderTargetDepthTextureId);
                    BlurShaderType         blur = BlurShaderType;

                    if (cameraType != WeatherMakerCameraType.Normal)
                    {
                        if (BlurMaterial.passCount > 3)
                        {
                            blur = BlurShaderType.Bilateral;
                        }
                        else
                        {
                            blur = BlurShaderType.GaussianBlur17;
                        }
                    }

                    int mod = (reprojState == null ? 0 : reprojState.ReprojectionSize);
                    commandBuffer.GetTemporaryRT(renderTargetRenderedImageId, GetRenderTextureDescriptor(scale, mod, 1, defaultFormat, 0, camera), FilterMode.Bilinear);
                    commandBuffer.GetTemporaryRT(renderTargetDepthTextureId, GetRenderTextureDescriptor(scale, mod, 1, RenderTextureFormat.RFloat, 0, camera), FilterMode.Point);

                    // set blend mode for blitting to render texture
                    commandBuffer.SetGlobalFloat(WMS._SrcBlendMode, (float)BlendMode.One);
                    commandBuffer.SetGlobalFloat(WMS._DstBlendMode, (float)BlendMode.Zero);

                    if (reprojState == null || reprojState.TemporalReprojectionMaterial == null)
                    {
                        // render to final destination
                        commandBuffer.Blit(renderTargetDepthTextureId, renderTargetRenderedImage, clonedMaterial, 0);
                    }
                    else
                    {
                        AttachTemporalReprojection(commandBuffer, reprojState, renderTargetDepthTextureId, renderTargetRenderedImage, clonedMaterial, scale, defaultFormat);
                    }

                    if (cameraType == WeatherMakerCameraType.Normal && DownsampleScalePostProcess != WeatherMakerDownsampleScale.Disabled)
                    {
                        AttachPostProcessing(commandBuffer, clonedMaterial, 0, 0, defaultFormat, renderTargetRenderedImage, reprojState, camera, ref postSourceId, ref postSource);
                        //AttachPostProcessing(commandBuffer, material, w, h, defaultFormat, renderTargetRenderedImageId, reprojState, ref postSourceId, ref postSource);
                    }

                    AttachBlurBlit(commandBuffer, renderTargetRenderedImage, renderTargetDepthTexture, CameraTargetIdentifier(), clonedMaterial, blur, defaultFormat, camera);

                    // cleanup
                    commandBuffer.ReleaseTemporaryRT(renderTargetRenderedImageId);
                    commandBuffer.ReleaseTemporaryRT(renderTargetDepthTextureId);

                    commandBuffer.SetGlobalTexture(WMS._MainTex2, new RenderTargetIdentifier(BuiltinRenderTextureType.None));
                }

                if (DownsampleRenderBufferScale != WeatherMakerDownsampleScale.Disabled)
                {
                    // cleanup
                    commandBuffer.ReleaseTemporaryRT(WMS._MainTex5);
                }
            }
            weatherMakerCommandBuffer.Material          = clonedMaterial;
            weatherMakerCommandBuffer.ReprojectionState = reprojState;
            weatherMakerCommandBuffer.RenderQueue       = RenderQueue;
            camera.AddCommandBuffer(RenderQueue, commandBuffer);
            if (WeatherMakerCommandBufferManagerScript.Instance != null)
            {
                WeatherMakerCommandBufferManagerScript.Instance.AddCommandBuffer(weatherMakerCommandBuffer);
            }
            return(weatherMakerCommandBuffer);
        }