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(); }
private void UpdateFogProperties(Camera camera) { if (FogProfile == null || WeatherMakerScript.Instance == null || WeatherMakerLightManagerScript.Instance == null || WeatherMakerScript.Instance.PerformanceProfile == null) { return; } DownSampleScale = WeatherMakerScript.Instance.PerformanceProfile.FogDownsampleScale; TemporalReprojection = WeatherMakerScript.Instance.PerformanceProfile.FogTemporalReprojectionSize; DownSampleScaleFullScreenShafts = WeatherMakerScript.Instance.PerformanceProfile.FogDownsampleScaleFullScreenShafts; if (WeatherMakerLightManagerScript.ScreenSpaceShadowMode == BuiltinShaderMode.Disabled || QualitySettings.shadows == ShadowQuality.Disable) { float fogShadowMultiplier = Mathf.Clamp(FogProfile.FogIntensityMultiplier, 0.5f, 1.0f); WeatherMakerLightManagerScript.Instance.DirectionalLightIntensityMultipliers["WeatherMakerFullScreenFogScript"] = fogShadowMultiplier; WeatherMakerLightManagerScript.Instance.DirectionalLightShadowIntensityMultipliers["WeatherMakerFullScreenFogScript"] = FogProfile.FogGlobalShadow; } else { WeatherMakerLightManagerScript.Instance.DirectionalLightIntensityMultipliers.Remove("WeatherMakerFullScreenFogScript"); WeatherMakerLightManagerScript.Instance.DirectionalLightShadowIntensityMultipliers.Remove("WeatherMakerFullScreenFogScript"); } updateShaderPropertiesAction = (updateShaderPropertiesAction ?? UpdateShaderProperties); effect.SetupEffect ( FogMaterial, FogFullScreenMaterial, FogBlurMaterial, BlurShader, DownSampleScale, FogProfile.SunShaftBackgroundColorMultiplier <= 0.0f ? WeatherMakerDownsampleScale.Disabled : DownSampleScaleFullScreenShafts, DownSampleScaleFullScreenShafts, TemporalReprojectionMaterial, TemporalReprojection, updateShaderPropertiesAction, (FogProfile.FogDensity > Mathf.Epsilon && FogProfile.FogMode != WeatherMakerFogMode.None && !UseUnityFog) ); UpdateWind(); UpdateUnityFog(camera); }
/// <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; } } }
/// <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(); } }