private void UpdateShaderProperties(WeatherMakerCommandBuffer b) { SetShaderCloudParameters(b.Material); }
/// <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; } } }
private void UpdateShaderProperties(WeatherMakerCommandBuffer b) { FogProfile.UpdateMaterialProperties(b.Material, b.Camera); }
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); }
/// <summary> /// Remove a command buffer from rendering /// </summary> /// <param name="cmdBuffer">Command buffer</param> public void RemoveCommandBuffer(WeatherMakerCommandBuffer cmdBuffer) { commandBuffers.Remove(cmdBuffer); }
private void CreateCommandBuffer(Camera camera) { CommandBuffer commandBuffer = new CommandBuffer { name = CommandBufferName }; //commandBuffer.SetViewMatrix(Matrix4x4.Ortho(0.0f, 1.0f, 0.0f, 1.0f, camera.farClipPlane, camera.farClipPlane)); int frameBufferSourceId = -1; RenderTargetIdentifier frameBufferSource = new RenderTargetIdentifier(BuiltinRenderTextureType.None); Material material = new Material(Material); material.name += " (Clone)"; if (DownsampleRenderBufferScale > 0.0f) { // render camera target to texture, performing separate down-sampling frameBufferSourceId = Shader.PropertyToID(DownsampleRenderBufferTextureName); frameBufferSource = new RenderTargetIdentifier(frameBufferSourceId); commandBuffer.GetTemporaryRT(frameBufferSourceId, (int)(Screen.width * DownsampleRenderBufferScale), (int)(Screen.height * DownsampleRenderBufferScale), 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32); commandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, frameBufferSource, null); } if (BlurShaderType == BlurShaderType.None && DownsampleScale >= 0.99f) { // draw directly to render target material.SetInt("_SrcBlendMode", (int)BlendMode.One); material.SetInt("_DstBlendMode", (int)BlendMode.OneMinusSrcAlpha); material.SetInt("_ZTest", (int)ZTest); commandBuffer.Blit(frameBufferSource, new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget), material); } else { // render to texture, using current image target as input _MainTex, no blend int intermediateRenderTargetId = Shader.PropertyToID("_MainTex"); RenderTargetIdentifier intermediateRenderTarget = new RenderTargetIdentifier(intermediateRenderTargetId); commandBuffer.GetTemporaryRT(intermediateRenderTargetId, (int)(Screen.width * DownsampleScale), (int)(Screen.height * DownsampleScale), 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32); material.SetInt("_SrcBlendMode", (int)BlendMode.One); material.SetInt("_DstBlendMode", (int)BlendMode.Zero); material.SetInt("_ZTest", (int)ZTest); commandBuffer.Blit(frameBufferSource, intermediateRenderTarget, material); // blur if requested if (BlurShaderType == BlurShaderType.None) { // blit texture directly on top of camera, alpha blend BlitMaterial.SetInt("_SrcBlendMode", (int)BlendMode.One); BlitMaterial.SetInt("_DstBlendMode", (int)BlendMode.OneMinusSrcAlpha); BlitMaterial.SetInt("_ZTest", (int)ZTest); commandBuffer.Blit(intermediateRenderTarget, BuiltinRenderTextureType.CameraTarget, BlitMaterial); } else { // blur texture directly on to camera target, alpha blend BlurMaterial.SetInt("_SrcBlendMode", (int)BlendMode.One); BlurMaterial.SetInt("_DstBlendMode", (int)BlendMode.OneMinusSrcAlpha); if (BlurShaderType == BlurShaderType.GaussianBlur7) { BlurMaterial.EnableKeyword("BLUR7"); } else { BlurMaterial.DisableKeyword("BLUR7"); } BlurMaterial.SetInt("_ZTest", (int)ZTest); commandBuffer.Blit(intermediateRenderTarget, BuiltinRenderTextureType.CameraTarget, BlurMaterial); } // cleanup commandBuffer.ReleaseTemporaryRT(intermediateRenderTargetId); } if (DownsampleRenderBufferScale > 0.0f) { // cleanup commandBuffer.ReleaseTemporaryRT(frameBufferSourceId); } // add to manager WeatherMakerCommandBuffer weatherMakerCommandBuffer = new WeatherMakerCommandBuffer { Camera = camera, CommandBuffer = commandBuffer, Material = material, RenderQueue = RenderQueue, UpdateMaterial = UpdateMaterialProperties, IsReflection = IsReflection(camera) }; WeatherMakerScript.Instance.CommandBufferManagerScript.AddCommandBuffer(weatherMakerCommandBuffer); cameras.Add(camera); }
/// <summary> /// Remove a command buffer from rendering /// </summary> /// <param name="cmdBuffer">Command buffer</param> public void RemoveCommandBuffer(WeatherMakerCommandBuffer cmdBuffer) { #if !UNITY_SERVER commandBuffers.Remove(cmdBuffer); #endif }
private void RenderMeteorShower(WeatherMakerCommandBuffer cmdBuffer) { cmdBuffer.CommandBuffer.DrawRenderer(meteorParticlesRenderer, meteorParticlesRenderer.material, 0, 0); cmdBuffer.CommandBuffer.DrawRenderer(meteorParticlesRenderer, meteorParticlesRenderer.trailMaterial, 1, 0); }