Exemplo n.º 1
0
 /// <summary>
 /// Cleanup all resources and set Enabled to false
 /// </summary>
 public void Dispose()
 {
     lastDownSampleScale             = -1.0f;
     lastDownsampleRenderBufferScale = -1.0f;
     lastBlurShaderType = (BlurShaderType)0x7FFFFFFF;
     foreach (Camera c in cameras)
     {
         if (c != null)
         {
             WeatherMakerScript.Instance.CommandBufferManagerScript.RemoveCommandBuffer(c, CommandBufferName);
         }
     }
     cameras.Clear();
     Enabled = false;
 }
Exemplo n.º 2
0
 /// <summary>
 /// Call from LateUpdate in script
 /// </summary>
 public void LateUpdate()
 {
     if (Enabled)
     {
         needsToBeRecreated = lastDownSampleScale != DownsampleScale ||
                              lastDownsampleRenderBufferScale != DownsampleRenderBufferScale ||
                              lastBlurShaderType != BlurShaderType;
         lastDownSampleScale             = DownsampleScale;
         lastDownsampleRenderBufferScale = DownsampleRenderBufferScale;
         lastBlurShaderType = BlurShaderType;
     }
     else
     {
         Dispose();
     }
 }
 /// <summary>
 /// Call from LateUpdate in script
 /// </summary>
 public void SetupEffect(Material material, Material blitMaterial, Material blurMaterial, BlurShaderType blurShaderType, float downSampleScale,
                         float downsampleRenderBufferScale, System.Action <WeatherMakerCommandBuffer> updateMaterialProperties, bool enabled)
 {
     Enabled = enabled;
     if (Enabled)
     {
         if (material != Material)
         {
             Material = material;
         }
         if (BlitMaterial != blitMaterial)
         {
             BlitMaterial = blitMaterial;
         }
         if (BlurMaterial != blurMaterial)
         {
             BlurMaterial = blurMaterial;
         }
         BlurShaderType              = blurShaderType;
         DownsampleScale             = downSampleScale;
         DownsampleRenderBufferScale = downsampleRenderBufferScale;
         if (UpdateMaterialProperties != updateMaterialProperties)
         {
             UpdateMaterialProperties = updateMaterialProperties;
         }
         needsToBeRecreated = lastDownSampleScale != DownsampleScale ||
                              lastDownsampleRenderBufferScale != DownsampleRenderBufferScale ||
                              lastBlurShaderType != BlurShaderType;
         lastDownSampleScale             = DownsampleScale;
         lastDownsampleRenderBufferScale = DownsampleRenderBufferScale;
         lastBlurShaderType = BlurShaderType;
     }
     else
     {
         Dispose();
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Call from LateUpdate in script
        /// </summary>
        public void SetupEffect
        (
            Material material,
            Material blitMaterial,
            Material blurMaterial,
            BlurShaderType blurShaderType,
            WeatherMakerDownsampleScale downSampleScale,
            WeatherMakerDownsampleScale downsampleRenderBufferScale,
            WeatherMakerDownsampleScale downsampleScalePostProcess,
            Material temporalReprojectionMaterial,
            WeatherMakerTemporalReprojectionSize temporalReprojection,
            System.Action <WeatherMakerCommandBuffer> updateMaterialProperties,
            bool enabled,
            WeatherMakerTemporalReprojectionState.TemporalReprojectionBlendMode temporalReprojectionBlendMode = WeatherMakerTemporalReprojectionState.TemporalReprojectionBlendMode.Blur,
            System.Action <WeatherMakerCommandBuffer> preSetupCommandBuffer = null
        )
        {
            Enabled = enabled;
            if (Enabled || preSetupCommandBuffer != null)
            {
                // setup material, if playing we want to clone it to avoid modifying the material
                if (Material != material || (Application.isPlaying && clonedMaterial == null))
                {
                    Material = material;
                    if (Application.isPlaying)
                    {
                        if (clonedMaterial != null)
                        {
                            GameObject.DestroyImmediate(clonedMaterial);
                        }
                        clonedMaterial       = new Material(Material);
                        clonedMaterial.name += " (Clone)";
                    }
                    else
                    {
                        clonedMaterial = Material;
                    }
                }
                BlitMaterial = blitMaterial;
                BlurMaterial = blurMaterial;
                TemporalReprojectionMaterial = temporalReprojectionMaterial;
                DownsampleScalePostProcess   = downsampleScalePostProcess;
                BlurShaderType              = blurShaderType;
                DownsampleScale             = (downSampleScale == WeatherMakerDownsampleScale.Disabled ? WeatherMakerDownsampleScale.FullResolution : downSampleScale);
                DownsampleRenderBufferScale = downsampleRenderBufferScale;
                TemporalReprojection        = temporalReprojection;
                UpdateMaterialProperties    = updateMaterialProperties;
                this.preSetupCommandBuffer  = preSetupCommandBuffer;
                foreach (WeatherMakerTemporalReprojectionState state in temporalStates)
                {
                    state.BlendMode = temporalReprojectionBlendMode;
                }

                // cleanup dead cameras
                for (int i = weatherMakerCommandBuffers.Count - 1; i >= 0; i--)
                {
                    if (weatherMakerCommandBuffers[i].Key == null)
                    {
                        if (weatherMakerCommandBuffers[i].Value.CommandBuffer != null)
                        {
                            weatherMakerCommandBuffers[i].Value.CommandBuffer.Clear();
                            weatherMakerCommandBuffers[i].Value.CommandBuffer.Release();
                        }
                        weatherMakerCommandBuffers.RemoveAt(i);
                    }
                }
            }
            else
            {
                Dispose();
            }
        }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
0
        internal void AttachBlurBlit(CommandBuffer commandBuffer, RenderTargetIdentifier renderedImageId, RenderTargetIdentifier depthTextureId,
                                     RenderTargetIdentifier finalTargetId, Material material, BlurShaderType blur, RenderTextureFormat defaultFormat, Camera camera)
        {
            if (material != null && material.passCount > 1)
            {
                // assume second pass is a depth writer pass, just writes the chosen depth pixel to a new texture
                // TODO: Would be nice to just use the depth buffer of the render texture to do this in one pass,
                // but Unity does not appear to expose pulling out the depth buffer of a temporary render texture using command buffers
                commandBuffer.Blit(renderedImageId, depthTextureId, material, 1);
            }

            // set blend mode for blitting to camera target
            commandBuffer.SetGlobalFloat(WMS._SrcBlendMode, (float)SourceBlendMode);
            commandBuffer.SetGlobalFloat(WMS._DstBlendMode, (float)DestBlendMode);

            // blur if requested
            if (blur == BlurShaderType.None)
            {
                // blit texture directly on top of camera without blur, depth aware alpha blend
                commandBuffer.Blit(renderedImageId, finalTargetId, BlitMaterial);
            }
            else
            {
                // blur texture directly on to camera target, depth and alpha aware blur, alpha blend
                if (blur == BlurShaderType.GaussianBlur7)
                {
                    commandBuffer.SetGlobalFloat(WMS._Blur7, 1.0f);
                    commandBuffer.Blit(renderedImageId, finalTargetId, BlurMaterial);
                }
                else if (blur == BlurShaderType.GaussianBlur17 || BlurMaterial.passCount < 4)
                {
                    commandBuffer.SetGlobalFloat(WMS._Blur7, 0.0f);
                    commandBuffer.Blit(renderedImageId, finalTargetId, BlurMaterial);
                }
                else
                {
                    AttachBilateralBlur(commandBuffer, BlurMaterial, renderedImageId, finalTargetId, defaultFormat, DownsampleScale, camera);
                }
            }
        }