Esempio n. 1
0
 private void AttachPostProcessing(CommandBuffer commandBuffer, Material material, int w, int h, RenderTextureFormat defaultFormat,
                                   RenderTargetIdentifier renderedImageId, WeatherMakerTemporalReprojectionState reprojState, Camera camera,
                                   ref int postSourceId, ref RenderTargetIdentifier postSource)
 {
     if (material.passCount > 2)
     {
         if (renderedImageId == CameraTargetIdentifier())
         {
             Debug.LogError("Weather Maker command buffer post processing cannot blit directly to camera target");
         }
         else
         {
             int   downsampleMain = WMS._MainTex2;
             float postScale      = (float)Mathf.Max((int)DownsampleScale, (int)DownsampleScalePostProcess);
             commandBuffer.SetGlobalFloat(WMS._WeatherMakerDownsampleScale, postScale);
             postSourceId = WMS._MainTex4;
             postSource   = new RenderTargetIdentifier(WMS._MainTex4);
             commandBuffer.GetTemporaryRT(postSourceId, GetRenderTextureDescriptor((int)postScale, 0, 1, defaultFormat, 0, camera), FilterMode.Bilinear);
             if (reprojState == null)
             {
                 if ((int)DownsampleScale < (int)DownsampleScalePostProcess)
                 {
                     // downsample main texture
                     commandBuffer.GetTemporaryRT(downsampleMain, GetRenderTextureDescriptor((int)postScale, 0, 1, defaultFormat, 0, camera), FilterMode.Bilinear);
                     commandBuffer.GetTemporaryRT(postSourceId, GetRenderTextureDescriptor((int)postScale, 0, 1, defaultFormat, 0, camera), FilterMode.Bilinear);
                     commandBuffer.SetGlobalTexture(WMS._MainTex2, downsampleMain);
                     commandBuffer.Blit(renderedImageId, downsampleMain);
                     commandBuffer.Blit(downsampleMain, postSourceId, material, 2);
                     commandBuffer.ReleaseTemporaryRT(downsampleMain);
                 }
                 else
                 {
                     commandBuffer.SetGlobalTexture(WMS._MainTex2, renderedImageId);
                     commandBuffer.Blit(renderedImageId, postSourceId, material, 2);
                 }
             }
             else if ((int)DownsampleScale * (int)reprojState.ReprojectionSize < (int)DownsampleScalePostProcess)
             {
                 commandBuffer.GetTemporaryRT(downsampleMain, GetRenderTextureDescriptor((int)postScale, 0, 1, defaultFormat, 0, camera), FilterMode.Bilinear);
                 commandBuffer.GetTemporaryRT(postSourceId, GetRenderTextureDescriptor((int)postScale, 0, 1, defaultFormat, 0, camera), FilterMode.Bilinear);
                 commandBuffer.SetGlobalTexture(WMS._MainTex2, downsampleMain);
                 commandBuffer.Blit(reprojState.PrevFrameTexture, downsampleMain);
                 commandBuffer.Blit(downsampleMain, postSourceId, material, 2);
                 commandBuffer.ReleaseTemporaryRT(downsampleMain);
             }
             else
             {
                 commandBuffer.SetGlobalTexture(WMS._MainTex2, reprojState.PrevFrameTexture);
                 commandBuffer.Blit(reprojState.PrevFrameTexture, postSourceId, material, 2);
             }
             commandBuffer.SetGlobalFloat(WMS._WeatherMakerDownsampleScale, (float)DownsampleScale);
             commandBuffer.SetGlobalTexture(WMS._MainTex4, postSourceId);
             commandBuffer.Blit(postSourceId, renderedImageId, material, 3); // pass index 3 is post process blit pass
             commandBuffer.ReleaseTemporaryRT(postSourceId);
         }
     }
 }
Esempio n. 2
0
 /// <summary>
 /// Post render event
 /// </summary>
 /// <param name="camera">Camera</param>
 public void PostRenderCamera(Camera camera)
 {
     if (camera != null && Enabled)
     {
         WeatherMakerTemporalReprojectionState reprojState = temporalStates.Find(b => b.Camera == camera);
         if (reprojState != null)
         {
             reprojState.PostRenderFrame(camera);
         }
     }
 }
        private void AttachTemporalReprojection(CommandBuffer commandBuffer, WeatherMakerTemporalReprojectionState reprojState, RenderTargetIdentifier depthTarget,
                                                RenderTargetIdentifier renderedImageId, Material material, int scale, RenderTextureFormat defaultFormat)
        {
            if (reprojState.NeedsFirstFrameHandling)
            {
                // do a more expensive render once to get the image looking nice, only happens once on first frame
                commandBuffer.Blit(depthTarget, reprojState.PrevFrameTexture, material, 0);

                // copy to sub frame so it's ready for next pass
                commandBuffer.Blit(reprojState.PrevFrameTexture, reprojState.SubFrameTexture);

                // copy to final image
                commandBuffer.Blit(reprojState.PrevFrameTexture, renderedImageId);
            }
            else if (reprojState.IntegratedTemporalReprojection)
            {
                // render fast pass with offset temporal reprojection so it is available in the full pass
                commandBuffer.SetGlobalFloat(WMS._WeatherMakerTemporalReprojectionEnabled, 1.0f);
                commandBuffer.Blit(depthTarget, reprojState.SubFrameTexture, material, 0);

                // perform full pass with full temporal reprojection
                commandBuffer.SetGlobalFloat(WMS._WeatherMakerTemporalReprojectionEnabled, 2.0f);
                commandBuffer.Blit(reprojState.SubFrameTexture, renderedImageId, material, 0);

                // copy to previous frame so we can re-use it next frame
                if (reprojState.BlendMode == WeatherMakerTemporalReprojectionState.TemporalReprojectionBlendMode.Blur)
                {
                    commandBuffer.Blit(reprojState.SubFrameTexture, reprojState.PrevFrameTexture);
                }
                else
                {
                    commandBuffer.Blit(renderedImageId, reprojState.PrevFrameTexture);
                }
            }
            else
            {
                // render to sub frame (fast, this is a small texture)
                commandBuffer.SetGlobalFloat(WMS._WeatherMakerTemporalReprojectionEnabled, 1.0f);
                commandBuffer.Blit(depthTarget, reprojState.SubFrameTexture, material, 0);

                // combine sub frame and prev frame to final image
                commandBuffer.Blit(reprojState.PrevFrameTexture, renderedImageId, reprojState.TemporalReprojectionMaterial, 0);

                // copy combined to previous frame for re-use next frame
                commandBuffer.Blit(renderedImageId, reprojState.PrevFrameTexture);
            }

            commandBuffer.SetGlobalFloat(WMS._WeatherMakerTemporalReprojectionEnabled, 0.0f);
        }
Esempio n. 4
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;
                }
            }
        }
Esempio 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);
        }