internal void OnEnable() { RuntimeUtilities.CreateIfNull(ref lightMeter); RuntimeUtilities.CreateIfNull(ref histogram); RuntimeUtilities.CreateIfNull(ref waveform); RuntimeUtilities.CreateIfNull(ref vectorscope); RuntimeUtilities.CreateIfNull(ref overlaySettings); m_Monitors = new Dictionary <MonitorType, Monitor> { { MonitorType.LightMeter, lightMeter }, { MonitorType.Histogram, histogram }, { MonitorType.Waveform, waveform }, { MonitorType.Vectorscope, vectorscope } }; foreach (var kvp in m_Monitors) { kvp.Value.OnEnable(); } }
public Matrix4x4 GetJitteredProjectionMatrix(Camera camera) { Matrix4x4 cameraProj; jitter = GenerateRandomOffset(); jitter *= jitterSpread; if (jitteredMatrixFunc != null) { cameraProj = jitteredMatrixFunc(camera, jitter); } else { cameraProj = camera.orthographic ? RuntimeUtilities.GetJitteredOrthographicProjectionMatrix(camera, jitter) : RuntimeUtilities.GetJitteredPerspectiveProjectionMatrix(camera, jitter); } jitter = new Vector2(jitter.x / camera.pixelWidth, jitter.y / camera.pixelHeight); return(cameraProj); }
void CheckInternalStripLut() { // Check internal lut state, (re)create it if needed if (m_InternalLdrLut == null || !m_InternalLdrLut.IsCreated()) { RuntimeUtilities.Destroy(m_InternalLdrLut); var format = GetLutFormat(); m_InternalLdrLut = new RenderTexture(k_Lut2DSize * k_Lut2DSize, k_Lut2DSize, 0, format, RenderTextureReadWrite.Linear) { name = "Color Grading Strip Lut", hideFlags = HideFlags.DontSave, filterMode = FilterMode.Bilinear, wrapMode = TextureWrapMode.Clamp, anisoLevel = 0, autoGenerateMips = false, useMipMap = false }; m_InternalLdrLut.Create(); } }
// This will be called only once at runtime and everytime script reload kicks-in in the // editor as we need to keep track of any compatible post-processing effects in the project void ReloadBaseTypes() { CleanBaseTypes(); // Rebuild the base type map var types = RuntimeUtilities.GetAllTypesDerivedFrom <PostProcessEffectSettings>() .Where( t => t.IsDefined(typeof(PostProcessAttribute), false) && !t.IsAbstract ); foreach (var type in types) { settingsTypes.Add(type, type.GetAttribute <PostProcessAttribute>()); // Create an instance for each effect type, these will be used for the lowest // priority global volume as we need a default state when exiting volume ranges var inst = (PostProcessEffectSettings)ScriptableObject.CreateInstance(type); inst.SetAllOverridesTo(true, false); m_BaseSettings.Add(inst); } }
public void InitBundles() { if (haveBundlesBeenInited) { return; } // Create these lists only once, the serialization system will take over after that RuntimeUtilities.CreateIfNull(ref m_BeforeTransparentBundles); RuntimeUtilities.CreateIfNull(ref m_BeforeStackBundles); RuntimeUtilities.CreateIfNull(ref m_AfterStackBundles); // Create a bundle for each effect type m_Bundles = new Dictionary <Type, PostProcessBundle>(); foreach (var type in PostProcessManager.instance.settingsTypes.Keys) { var settings = (PostProcessEffectSettings)ScriptableObject.CreateInstance(type); var bundle = new PostProcessBundle(settings); m_Bundles.Add(type, bundle); } // Update sorted lists with newly added or removed effects in the assemblies UpdateBundleSortList(m_BeforeTransparentBundles, PostProcessEvent.BeforeTransparent); UpdateBundleSortList(m_BeforeStackBundles, PostProcessEvent.BeforeStack); UpdateBundleSortList(m_AfterStackBundles, PostProcessEvent.AfterStack); // Push all sorted lists in a dictionary for easier access sortedBundles = new Dictionary <PostProcessEvent, List <SerializedBundleRef> >(new PostProcessEventComparer()) { { PostProcessEvent.BeforeTransparent, m_BeforeTransparentBundles }, { PostProcessEvent.BeforeStack, m_BeforeStackBundles }, { PostProcessEvent.AfterStack, m_AfterStackBundles } }; // Done haveBundlesBeenInited = true; }
void CheckAOTexture(PostProcessRenderContext context) { bool AOUpdateNeeded = m_AmbientOnlyAO == null || !m_AmbientOnlyAO.IsCreated() || m_AmbientOnlyAO.width != context.width || m_AmbientOnlyAO.height != context.height; #if UNITY_2017_3_OR_NEWER AOUpdateNeeded = AOUpdateNeeded || m_AmbientOnlyAO.useDynamicScale != context.camera.allowDynamicResolution; #endif if (AOUpdateNeeded) { RuntimeUtilities.Destroy(m_AmbientOnlyAO); m_AmbientOnlyAO = new RenderTexture(context.width, context.height, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear) { hideFlags = HideFlags.DontSave, filterMode = FilterMode.Point, enableRandomWrite = true, #if UNITY_2017_3_OR_NEWER useDynamicScale = context.camera.allowDynamicResolution #endif }; m_AmbientOnlyAO.Create(); } }
void CheckInternalLogLut() { // Check internal lut state, (re)create it if needed if (m_InternalLogLut == null || !m_InternalLogLut.IsCreated()) { RuntimeUtilities.Destroy(m_InternalLogLut); var format = GetLutFormat(); m_InternalLogLut = new RenderTexture(k_Lut3DSize, k_Lut3DSize, 0, format, RenderTextureReadWrite.Linear) { name = "Color Grading Log Lut", hideFlags = HideFlags.DontSave, filterMode = FilterMode.Bilinear, wrapMode = TextureWrapMode.Clamp, anisoLevel = 0, enableRandomWrite = true, volumeDepth = k_Lut3DSize, dimension = TextureDimension.Tex3D, autoGenerateMips = false, useMipMap = false }; m_InternalLogLut.Create(); } }
internal override void Render(PostProcessRenderContext context) { CheckOutput(width, height); LogHistogram logHistogram = context.logHistogram; PropertySheet propertySheet = context.propertySheets.Get(context.resources.shaders.lightMeter); propertySheet.ClearKeywords(); propertySheet.properties.SetBuffer(ShaderIDs.HistogramBuffer, logHistogram.data); Vector4 histogramScaleOffsetRes = logHistogram.GetHistogramScaleOffsetRes(context); histogramScaleOffsetRes.z = 1f / (float)width; histogramScaleOffsetRes.w = 1f / (float)height; propertySheet.properties.SetVector(ShaderIDs.ScaleOffsetRes, histogramScaleOffsetRes); if (context.logLut != null && showCurves) { propertySheet.EnableKeyword("COLOR_GRADING_HDR"); propertySheet.properties.SetTexture(ShaderIDs.Lut3D, context.logLut); } AutoExposure autoExposure = context.autoExposure; if (autoExposure != null) { float x = autoExposure.filtering.value.x; float y = autoExposure.filtering.value.y; y = Mathf.Clamp(y, 1.01f, 99f); x = Mathf.Clamp(x, 1f, y - 0.01f); Vector4 value = new Vector4(x * 0.01f, y * 0.01f, RuntimeUtilities.Exp2(autoExposure.minLuminance.value), RuntimeUtilities.Exp2(autoExposure.maxLuminance.value)); propertySheet.EnableKeyword("AUTO_EXPOSURE"); propertySheet.properties.SetVector(ShaderIDs.Params, value); } CommandBuffer command = context.command; command.BeginSample("LightMeter"); command.BlitFullscreenTriangle(BuiltinRenderTextureType.None, base.output, propertySheet, 0); command.EndSample("LightMeter"); }
public override void Render(PostProcessRenderContext context) { var cmd = context.command; cmd.BeginSample("BloomPyramid"); var sheet = context.propertySheets.Get(context.resources.shaders.bloom); // Apply auto exposure adjustment in the prefiltering pass sheet.properties.SetTexture(ShaderIDs.AutoExposureTex, context.autoExposureTexture); // Negative anamorphic ratio values distort vertically - positive is horizontal float ratio = Mathf.Clamp(settings.anamorphicRatio, -1, 1); float rw = ratio < 0 ? -ratio : 0f; float rh = ratio > 0 ? ratio : 0f; // Do bloom on a half-res buffer, full-res doesn't bring much and kills performances on // fillrate limited platforms int tw = Mathf.FloorToInt(context.screenWidth / (3f - rw)); int th = Mathf.FloorToInt(context.screenHeight / (1f - rh)); // Determine the iteration count int s = Mathf.Max(tw, th); float logs = Mathf.Log(s, 2f) + Mathf.Min(settings.diffusion.value, 10f) - 10f; int logs_i = Mathf.FloorToInt(logs); int iterations = Mathf.Clamp(logs_i, 1, k_MaxPyramidSize); float sampleScale = 0.5f + logs - logs_i; sheet.properties.SetFloat(ShaderIDs.SampleScale, sampleScale); // Prefiltering parameters float lthresh = Mathf.GammaToLinearSpace(settings.threshold.value); float knee = lthresh * settings.softKnee.value + 1e-5f; var threshold = new Vector4(lthresh, lthresh - knee, knee * 2f, 0.25f / knee); sheet.properties.SetVector(ShaderIDs.Threshold, threshold); int qualityOffset = settings.fastMode ? 1 : 0; // Downsample var lastDown = context.source; for (int i = 0; i < iterations; i++) { int mipDown = m_Pyramid[i].down; int mipUp = m_Pyramid[i].up; int pass = i == 0 ? (int)Pass.Prefilter13 + qualityOffset : (int)Pass.Downsample13 + qualityOffset; context.GetScreenSpaceTemporaryRT(cmd, mipDown, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw, th); context.GetScreenSpaceTemporaryRT(cmd, mipUp, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw, th); cmd.BlitFullscreenTriangle(lastDown, mipDown, sheet, pass); lastDown = mipDown; tw = Mathf.Max(tw / 2, 1); th = Mathf.Max(th / 2, 1); } // Upsample int lastUp = m_Pyramid[iterations - 1].down; for (int i = iterations - 2; i >= 0; i--) { int mipDown = m_Pyramid[i].down; int mipUp = m_Pyramid[i].up; cmd.SetGlobalTexture(ShaderIDs.BloomTex, mipDown); cmd.BlitFullscreenTriangle(lastUp, mipUp, sheet, (int)Pass.UpsampleTent + qualityOffset); lastUp = mipUp; } var linearColor = settings.color.value.linear; float intensity = RuntimeUtilities.Exp2(settings.intensity.value / 10f) - 1f; var shaderSettings = new Vector4(sampleScale, intensity, settings.dirtIntensity.value, iterations); // Debug overlays if (context.IsDebugOverlayEnabled(DebugOverlay.BloomThreshold)) { context.PushDebugOverlay(cmd, context.source, sheet, (int)Pass.DebugOverlayThreshold); } else if (context.IsDebugOverlayEnabled(DebugOverlay.BloomBuffer)) { sheet.properties.SetVector(ShaderIDs.ColorIntensity, new Vector4(linearColor.r, linearColor.g, linearColor.b, intensity)); context.PushDebugOverlay(cmd, m_Pyramid[0].up, sheet, (int)Pass.DebugOverlayTent + qualityOffset); } // Lens dirtiness // Keep the aspect ratio correct & center the dirt texture, we don't want it to be // stretched or squashed var dirtTexture = settings.dirtTexture.value == null ? RuntimeUtilities.blackTexture : settings.dirtTexture.value; var dirtRatio = (float)dirtTexture.width / (float)dirtTexture.height; var screenRatio = (float)context.screenWidth / (float)context.screenHeight; var dirtTileOffset = new Vector4(1f, 1f, 0f, 0f); if (dirtRatio > screenRatio) { dirtTileOffset.x = screenRatio / dirtRatio; dirtTileOffset.z = (1f - dirtTileOffset.x) * 0.5f; } else if (screenRatio > dirtRatio) { dirtTileOffset.y = dirtRatio / screenRatio; dirtTileOffset.w = (1f - dirtTileOffset.y) * 0.5f; } // Shader properties var uberSheet = context.uberSheet; uberSheet.EnableKeyword("BLOOM"); uberSheet.properties.SetVector(ShaderIDs.Bloom_DirtTileOffset, dirtTileOffset); uberSheet.properties.SetVector(ShaderIDs.Bloom_Settings, shaderSettings); uberSheet.properties.SetColor(ShaderIDs.Bloom_Color, linearColor); uberSheet.properties.SetTexture(ShaderIDs.Bloom_DirtTex, dirtTexture); cmd.SetGlobalTexture(ShaderIDs.BloomTex, lastUp); // Cleanup for (int i = 0; i < iterations; i++) { if (m_Pyramid[i].down != lastUp) { cmd.ReleaseTemporaryRT(m_Pyramid[i].down); } if (m_Pyramid[i].up != lastUp) { cmd.ReleaseTemporaryRT(m_Pyramid[i].up); } } cmd.EndSample("BloomPyramid"); context.bloomBufferNameID = lastUp; }
public override void Render(PostProcessRenderContext context) { var cmd = context.command; cmd.BeginSample("AutoExposureLookup"); // Prepare autoExpo texture pool CheckTexture(context.xrActiveEye, 0); CheckTexture(context.xrActiveEye, 1); // Make sure filtering values are correct to avoid apocalyptic consequences float lowPercent = settings.filtering.value.x; float highPercent = settings.filtering.value.y; const float kMinDelta = 1e-2f; highPercent = Mathf.Clamp(highPercent, 1f + kMinDelta, 99f); lowPercent = Mathf.Clamp(lowPercent, 1f, highPercent - kMinDelta); // Clamp min/max adaptation values as well float minLum = settings.minLuminance.value; float maxLum = settings.maxLuminance.value; settings.minLuminance.value = Mathf.Min(minLum, maxLum); settings.maxLuminance.value = Mathf.Max(minLum, maxLum); // Compute average luminance & auto exposure bool firstFrame = m_ResetHistory || !Application.isPlaying; string adaptation = null; if (firstFrame || settings.eyeAdaptation.value == EyeAdaptation.Fixed) { adaptation = "KAutoExposureAvgLuminance_fixed"; } else { adaptation = "KAutoExposureAvgLuminance_progressive"; } var compute = context.resources.computeShaders.autoExposure; int kernel = compute.FindKernel(adaptation); cmd.SetComputeBufferParam(compute, kernel, "_HistogramBuffer", context.logHistogram.data); cmd.SetComputeVectorParam(compute, "_Params1", new Vector4(lowPercent * 0.01f, highPercent * 0.01f, RuntimeUtilities.Exp2(settings.minLuminance.value), RuntimeUtilities.Exp2(settings.maxLuminance.value))); cmd.SetComputeVectorParam(compute, "_Params2", new Vector4(settings.speedDown.value, settings.speedUp.value, settings.keyValue.value, Time.deltaTime)); cmd.SetComputeVectorParam(compute, "_ScaleOffsetRes", context.logHistogram.GetHistogramScaleOffsetRes(context)); if (firstFrame) { // We don't want eye adaptation when not in play mode because the GameView isn't // animated, thus making it harder to tweak. Just use the final audo exposure value. m_CurrentAutoExposure = m_AutoExposurePool[context.xrActiveEye][0]; cmd.SetComputeTextureParam(compute, kernel, "_Destination", m_CurrentAutoExposure); cmd.DispatchCompute(compute, kernel, 1, 1, 1); // Copy current exposure to the other pingpong target to avoid adapting from black RuntimeUtilities.CopyTexture(cmd, m_AutoExposurePool[context.xrActiveEye][0], m_AutoExposurePool[context.xrActiveEye][1]); m_ResetHistory = false; } else { int pp = m_AutoExposurePingPong[context.xrActiveEye]; var src = m_AutoExposurePool[context.xrActiveEye][++pp % 2]; var dst = m_AutoExposurePool[context.xrActiveEye][++pp % 2]; cmd.SetComputeTextureParam(compute, kernel, "_Source", src); cmd.SetComputeTextureParam(compute, kernel, "_Destination", dst); cmd.DispatchCompute(compute, kernel, 1, 1, 1); m_AutoExposurePingPong[context.xrActiveEye] = ++pp % 2; m_CurrentAutoExposure = dst; } cmd.EndSample("AutoExposureLookup"); context.autoExposureTexture = m_CurrentAutoExposure; context.autoExposure = settings; }
public Matrix4x4 GetJitteredProjectionMatrix(Camera camera) { this.jitter = GenerateRandomOffset(); this.jitter *= jitterSpread; Matrix4x4 result = (jitteredMatrixFunc == null) ? ((!camera.orthographic) ? RuntimeUtilities.GetJitteredPerspectiveProjectionMatrix(camera, this.jitter) : RuntimeUtilities.GetJitteredOrthographicProjectionMatrix(camera, this.jitter)) : jitteredMatrixFunc(camera, this.jitter); Vector2 jitter = this.jitter; float x = jitter.x / (float)camera.pixelWidth; Vector2 jitter2 = this.jitter; this.jitter = new Vector2(x, jitter2.y / (float)camera.pixelHeight); return(result); }
public override void Release() { RuntimeUtilities.Destroy(m_GrainLookupRT); m_GrainLookupRT = null; m_SampleIndex = 0; }
public override void Interp(Texture from, Texture to, float t) { // Both are null, do nothing if (from == null && to == null) { value = null; return; } // Both aren't null we're ready to blend if (from != null && to != null) { value = TextureLerper.instance.Lerp(from, to, t); return; } // One of them is null, blend to/from a default value is applicable { Texture defaultTexture; switch (defaultState) { case TextureParameterDefault.Black: defaultTexture = RuntimeUtilities.blackTexture; break; case TextureParameterDefault.White: defaultTexture = RuntimeUtilities.whiteTexture; break; case TextureParameterDefault.Transparent: defaultTexture = RuntimeUtilities.transparentTexture; break; case TextureParameterDefault.Lut2D: // Find the current lut size int size = from != null ? from.height : to.height; defaultTexture = RuntimeUtilities.GetLutStrip(size); break; default: defaultTexture = null; break; } if (from == null) { from = defaultTexture; } if (to == null) { to = defaultTexture; } // defaultState could have been explicitly set to None if (from == null || to == null) { base.Interp(from, to, t); return; } value = TextureLerper.instance.Lerp(from, to, t); } }
void BuildCommandBuffers() { var context = m_CurrentContext; var sourceFormat = m_Camera.allowHDR ? RuntimeUtilities.defaultHDRRenderTextureFormat : RenderTextureFormat.Default; if (!RuntimeUtilities.isFloatingPointFormat(sourceFormat)) { m_NaNKilled = true; } context.Reset(); context.camera = m_Camera; context.sourceFormat = sourceFormat; // TODO: Investigate retaining command buffers on XR multi-pass right eye m_LegacyCmdBufferBeforeReflections.Clear(); m_LegacyCmdBufferBeforeLighting.Clear(); m_LegacyCmdBufferOpaque.Clear(); m_LegacyCmdBuffer.Clear(); SetupContext(context); context.command = m_LegacyCmdBufferOpaque; UpdateSettingsIfNeeded(context); // Lighting & opaque-only effects var aoBundle = GetBundle <AmbientOcclusion>(); var aoSettings = aoBundle.CastSettings <AmbientOcclusion>(); var aoRenderer = aoBundle.CastRenderer <AmbientOcclusionRenderer>(); bool aoSupported = aoSettings.IsEnabledAndSupported(context); bool aoAmbientOnly = aoRenderer.IsAmbientOnly(context); bool isAmbientOcclusionDeferred = aoSupported && aoAmbientOnly; bool isAmbientOcclusionOpaque = aoSupported && !aoAmbientOnly; var ssrBundle = GetBundle <ScreenSpaceReflections>(); var ssrSettings = ssrBundle.settings; var ssrRenderer = ssrBundle.renderer; bool isScreenSpaceReflectionsActive = ssrSettings.IsEnabledAndSupported(context); // Ambient-only AO is a special case and has to be done in separate command buffers if (isAmbientOcclusionDeferred) { var ao = aoRenderer.Get(); // Render as soon as possible - should be done async in SRPs when available context.command = m_LegacyCmdBufferBeforeReflections; ao.RenderAmbientOnly(context); // Composite with GBuffer right before the lighting pass context.command = m_LegacyCmdBufferBeforeLighting; ao.CompositeAmbientOnly(context); } else if (isAmbientOcclusionOpaque) { context.command = m_LegacyCmdBufferOpaque; aoRenderer.Get().RenderAfterOpaque(context); } bool isFogActive = fog.IsEnabledAndSupported(context); bool hasCustomOpaqueOnlyEffects = HasOpaqueOnlyEffects(context); int opaqueOnlyEffects = 0; opaqueOnlyEffects += isScreenSpaceReflectionsActive ? 1 : 0; opaqueOnlyEffects += isFogActive ? 1 : 0; opaqueOnlyEffects += hasCustomOpaqueOnlyEffects ? 1 : 0; // This works on right eye because it is resolved/populated at runtime var cameraTarget = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget); if (opaqueOnlyEffects > 0) { var cmd = m_LegacyCmdBufferOpaque; context.command = cmd; // We need to use the internal Blit method to copy the camera target or it'll fail // on tiled GPU as it won't be able to resolve int tempTarget0 = m_TargetPool.Get(); context.GetScreenSpaceTemporaryRT(cmd, tempTarget0, 0, sourceFormat); cmd.Blit(cameraTarget, tempTarget0); context.source = tempTarget0; int tempTarget1 = -1; if (opaqueOnlyEffects > 1) { tempTarget1 = m_TargetPool.Get(); context.GetScreenSpaceTemporaryRT(cmd, tempTarget1, 0, sourceFormat); context.destination = tempTarget1; } else { context.destination = cameraTarget; } if (isScreenSpaceReflectionsActive) { ssrRenderer.Render(context); opaqueOnlyEffects--; var prevSource = context.source; context.source = context.destination; context.destination = opaqueOnlyEffects == 1 ? cameraTarget : prevSource; } if (isFogActive) { fog.Render(context); opaqueOnlyEffects--; var prevSource = context.source; context.source = context.destination; context.destination = opaqueOnlyEffects == 1 ? cameraTarget : prevSource; } if (hasCustomOpaqueOnlyEffects) { RenderOpaqueOnly(context); } if (opaqueOnlyEffects > 1) { cmd.ReleaseTemporaryRT(tempTarget1); } cmd.ReleaseTemporaryRT(tempTarget0); } // Post-transparency stack // Same as before, first blit needs to use the builtin Blit command to properly handle // tiled GPUs int tempRt = m_TargetPool.Get(); context.GetScreenSpaceTemporaryRT(m_LegacyCmdBuffer, tempRt, 0, sourceFormat, RenderTextureReadWrite.sRGB); m_LegacyCmdBuffer.Blit(cameraTarget, tempRt, RuntimeUtilities.copyStdMaterial, stopNaNPropagation ? 1 : 0); if (!m_NaNKilled) { m_NaNKilled = stopNaNPropagation; } context.command = m_LegacyCmdBuffer; context.source = tempRt; context.destination = cameraTarget; Render(context); m_LegacyCmdBuffer.ReleaseTemporaryRT(tempRt); }
void DestroyDebugOverlayTarget() { RuntimeUtilities.Destroy(debugOverlayTarget); debugOverlayTarget = null; }
public void Release() { RuntimeUtilities.Destroy(m_AmbientOnlyAO); m_AmbientOnlyAO = null; }
// HDR color pipeline is rendered to a 2D strip lut (works on HDR platforms without compute // and 3D texture support). Precision is sliiiiiiightly lower than when using a 3D texture // LUT (33^3 -> 32^3) but most of the time it's imperceptible. void RenderHDRPipeline2D(PostProcessRenderContext context) { // For the same reasons as in RenderHDRPipeline3D, regen LUT on evey frame { CheckInternalStripLut(); // Lut setup var lutSheet = context.propertySheets.Get(context.resources.shaders.lut2DBaker); lutSheet.ClearKeywords(); lutSheet.properties.SetVector(ShaderIDs.Lut2D_Params, new Vector4(k_Lut2DSize, 0.5f / (k_Lut2DSize * k_Lut2DSize), 0.5f / k_Lut2DSize, k_Lut2DSize / (k_Lut2DSize - 1f))); var colorBalance = ColorUtilities.ComputeColorBalance(settings.temperature.value, settings.tint.value); lutSheet.properties.SetVector(ShaderIDs.ColorBalance, colorBalance); lutSheet.properties.SetVector(ShaderIDs.ColorFilter, settings.colorFilter.value); float hue = settings.hueShift.value / 360f; // Remap to [-0.5;0.5] float sat = settings.saturation.value / 100f + 1f; // Remap to [0;2] float con = settings.contrast.value / 100f + 1f; // Remap to [0;2] lutSheet.properties.SetVector(ShaderIDs.HueSatCon, new Vector3(hue, sat, con)); var channelMixerR = new Vector3(settings.mixerRedOutRedIn, settings.mixerRedOutGreenIn, settings.mixerRedOutBlueIn); var channelMixerG = new Vector3(settings.mixerGreenOutRedIn, settings.mixerGreenOutGreenIn, settings.mixerGreenOutBlueIn); var channelMixerB = new Vector3(settings.mixerBlueOutRedIn, settings.mixerBlueOutGreenIn, settings.mixerBlueOutBlueIn); lutSheet.properties.SetVector(ShaderIDs.ChannelMixerRed, channelMixerR / 100f); // Remap to [-2;2] lutSheet.properties.SetVector(ShaderIDs.ChannelMixerGreen, channelMixerG / 100f); lutSheet.properties.SetVector(ShaderIDs.ChannelMixerBlue, channelMixerB / 100f); var lift = ColorUtilities.ColorToLift(settings.lift.value * 0.2f); var gain = ColorUtilities.ColorToGain(settings.gain.value * 0.8f); var invgamma = ColorUtilities.ColorToInverseGamma(settings.gamma.value * 0.8f); lutSheet.properties.SetVector(ShaderIDs.Lift, lift); lutSheet.properties.SetVector(ShaderIDs.InvGamma, invgamma); lutSheet.properties.SetVector(ShaderIDs.Gain, gain); lutSheet.properties.SetTexture(ShaderIDs.Curves, GetCurveTexture(false)); var tonemapper = settings.tonemapper.value; if (tonemapper == Tonemapper.Custom) { lutSheet.EnableKeyword("TONEMAPPING_CUSTOM"); m_HableCurve.Init( settings.toneCurveToeStrength.value, settings.toneCurveToeLength.value, settings.toneCurveShoulderStrength.value, settings.toneCurveShoulderLength.value, settings.toneCurveShoulderAngle.value, settings.toneCurveGamma.value ); lutSheet.properties.SetVector(ShaderIDs.CustomToneCurve, m_HableCurve.uniforms.curve); lutSheet.properties.SetVector(ShaderIDs.ToeSegmentA, m_HableCurve.uniforms.toeSegmentA); lutSheet.properties.SetVector(ShaderIDs.ToeSegmentB, m_HableCurve.uniforms.toeSegmentB); lutSheet.properties.SetVector(ShaderIDs.MidSegmentA, m_HableCurve.uniforms.midSegmentA); lutSheet.properties.SetVector(ShaderIDs.MidSegmentB, m_HableCurve.uniforms.midSegmentB); lutSheet.properties.SetVector(ShaderIDs.ShoSegmentA, m_HableCurve.uniforms.shoSegmentA); lutSheet.properties.SetVector(ShaderIDs.ShoSegmentB, m_HableCurve.uniforms.shoSegmentB); } else if (tonemapper == Tonemapper.ACES) { lutSheet.EnableKeyword("TONEMAPPING_ACES"); } else if (tonemapper == Tonemapper.Neutral) { lutSheet.EnableKeyword("TONEMAPPING_NEUTRAL"); } // Generate the lut context.command.BeginSample("HdrColorGradingLut2D"); context.command.BlitFullscreenTriangle(BuiltinRenderTextureType.None, m_InternalLdrLut, lutSheet, (int)Pass.LutGenHDR2D); context.command.EndSample("HdrColorGradingLut2D"); } var lut = m_InternalLdrLut; var uberSheet = context.uberSheet; uberSheet.EnableKeyword("COLOR_GRADING_HDR_2D"); uberSheet.properties.SetVector(ShaderIDs.Lut2D_Params, new Vector3(1f / lut.width, 1f / lut.height, lut.height - 1f)); uberSheet.properties.SetTexture(ShaderIDs.Lut2D, lut); uberSheet.properties.SetFloat(ShaderIDs.PostExposure, RuntimeUtilities.Exp2(settings.postExposure.value)); }
public override void Render(PostProcessRenderContext context) { var cmd = context.command; cmd.BeginSample("AutoExposureLookup"); var sheet = context.propertySheets.Get(context.resources.shaders.autoExposure); sheet.ClearKeywords(); // Prepare autoExpo texture pool CheckTexture(context.xrActiveEye, 0); CheckTexture(context.xrActiveEye, 1); // Make sure filtering values are correct to avoid apocalyptic consequences float lowPercent = settings.filtering.value.x; float highPercent = settings.filtering.value.y; const float kMinDelta = 1e-2f; highPercent = Mathf.Clamp(highPercent, 1f + kMinDelta, 99f); lowPercent = Mathf.Clamp(lowPercent, 1f, highPercent - kMinDelta); // Clamp min/max adaptation values as well float minLum = settings.minLuminance.value; float maxLum = settings.maxLuminance.value; settings.minLuminance.value = Mathf.Min(minLum, maxLum); settings.maxLuminance.value = Mathf.Max(minLum, maxLum); // Compute auto exposure sheet.properties.SetBuffer(ShaderIDs.HistogramBuffer, context.logHistogram.data); sheet.properties.SetVector(ShaderIDs.Params, new Vector4(lowPercent * 0.01f, highPercent * 0.01f, RuntimeUtilities.Exp2(settings.minLuminance.value), RuntimeUtilities.Exp2(settings.maxLuminance.value))); sheet.properties.SetVector(ShaderIDs.Speed, new Vector2(settings.speedDown.value, settings.speedUp.value)); sheet.properties.SetVector(ShaderIDs.ScaleOffsetRes, context.logHistogram.GetHistogramScaleOffsetRes(context)); sheet.properties.SetFloat(ShaderIDs.ExposureCompensation, settings.keyValue.value); if (m_ResetHistory || !Application.isPlaying) { // We don't want eye adaptation when not in play mode because the GameView isn't // animated, thus making it harder to tweak. Just use the final audo exposure value. m_CurrentAutoExposure = m_AutoExposurePool[context.xrActiveEye][0]; cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, m_CurrentAutoExposure, sheet, (int)EyeAdaptation.Fixed); // Copy current exposure to the other pingpong target to avoid adapting from black RuntimeUtilities.CopyTexture(cmd, m_AutoExposurePool[context.xrActiveEye][0], m_AutoExposurePool[context.xrActiveEye][1]); m_ResetHistory = false; } else { int pp = m_AutoExposurePingPong[context.xrActiveEye]; var src = m_AutoExposurePool[context.xrActiveEye][++pp % 2]; var dst = m_AutoExposurePool[context.xrActiveEye][++pp % 2]; cmd.BlitFullscreenTriangle(src, dst, sheet, (int)settings.eyeAdaptation.value); m_AutoExposurePingPong[context.xrActiveEye] = ++pp % 2; m_CurrentAutoExposure = dst; } cmd.EndSample("AutoExposureLookup"); context.autoExposureTexture = m_CurrentAutoExposure; context.autoExposure = settings; }
public override void Interp(Texture from, Texture to, float t) { // Both are null, do nothing if (from == null && to == null) { value = null; return; } // Both aren't null we're ready to blend if (from != null && to != null) { value = TextureLerper.instance.Lerp(from, to, t); return; } // One of them is null, blend to/from a default value is applicable { if (defaultState == TextureParameterDefault.Lut2D) { int size = from != null ? from.height : to.height; Texture defaultTexture = RuntimeUtilities.GetLutStrip(size); if (from == null) { from = defaultTexture; } if (to == null) { to = defaultTexture; } } Color tgtColor; switch (defaultState) { case TextureParameterDefault.Black: tgtColor = Color.black; break; case TextureParameterDefault.White: tgtColor = Color.white; break; case TextureParameterDefault.Transparent: tgtColor = Color.clear; break; case TextureParameterDefault.Lut2D: { // Find the current lut size int size = from != null ? from.height : to.height; Texture defaultTexture = RuntimeUtilities.GetLutStrip(size); if (from == null) { from = defaultTexture; } if (to == null) { to = defaultTexture; } value = TextureLerper.instance.Lerp(from, to, t); // All done, return return; } default: // defaultState is none, so just interpolate the base and return base.Interp(from, to, t); return; } // If we made it this far, tgtColor contains the color we'll be lerping into (or out of) if (from == null) { // color -> texture lerp, invert ratio value = TextureLerper.instance.Lerp(to, tgtColor, 1f - t); } else { value = TextureLerper.instance.Lerp(from, tgtColor, t); } } }
void PushDownsampleCommands(PostProcessRenderContext context, CommandBuffer cmd) { // Make a copy of the depth texture, or reuse the resolved depth // buffer (it's only available in some specific situations). var useDepthCopy = !RuntimeUtilities.IsResolvedDepthAvailable(context.camera); if (useDepthCopy) { m_DepthCopy.PushAllocationCommand(cmd); cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, m_DepthCopy.id, m_PropertySheet, (int)Pass.DepthCopy); } // Temporary buffer allocations. m_LinearDepth.PushAllocationCommand(cmd); m_LowDepth1.PushAllocationCommand(cmd); m_LowDepth2.PushAllocationCommand(cmd); m_LowDepth3.PushAllocationCommand(cmd); m_LowDepth4.PushAllocationCommand(cmd); #if UNITY_2017_1_OR_NEWER m_TiledDepth1.PushAllocationCommand(cmd); m_TiledDepth2.PushAllocationCommand(cmd); m_TiledDepth3.PushAllocationCommand(cmd); m_TiledDepth4.PushAllocationCommand(cmd); #endif // 1st downsampling pass. var cs = context.resources.computeShaders.multiScaleAODownsample1; int kernel = cs.FindKernel("main"); cmd.SetComputeTextureParam(cs, kernel, "LinearZ", m_LinearDepth.id); cmd.SetComputeTextureParam(cs, kernel, "DS2x", m_LowDepth1.id); cmd.SetComputeTextureParam(cs, kernel, "DS4x", m_LowDepth2.id); cmd.SetComputeTextureParam(cs, kernel, "DS2xAtlas", m_TiledDepth1.id); cmd.SetComputeTextureParam(cs, kernel, "DS4xAtlas", m_TiledDepth2.id); cmd.SetComputeVectorParam(cs, "ZBufferParams", CalculateZBufferParams(context.camera)); cmd.SetComputeTextureParam(cs, kernel, "Depth", useDepthCopy ? m_DepthCopy.id : BuiltinRenderTextureType.ResolvedDepth ); cmd.DispatchCompute(cs, kernel, m_TiledDepth2.width, m_TiledDepth2.height, 1); if (useDepthCopy) { cmd.ReleaseTemporaryRT(m_DepthCopy.nameID); } // 2nd downsampling pass. cs = context.resources.computeShaders.multiScaleAODownsample2; kernel = cs.FindKernel("main"); cmd.SetComputeTextureParam(cs, kernel, "DS4x", m_LowDepth2.id); cmd.SetComputeTextureParam(cs, kernel, "DS8x", m_LowDepth3.id); cmd.SetComputeTextureParam(cs, kernel, "DS16x", m_LowDepth4.id); cmd.SetComputeTextureParam(cs, kernel, "DS8xAtlas", m_TiledDepth3.id); cmd.SetComputeTextureParam(cs, kernel, "DS16xAtlas", m_TiledDepth4.id); cmd.DispatchCompute(cs, kernel, m_TiledDepth4.width, m_TiledDepth4.height, 1); }
public void Destroy() { RuntimeUtilities.Destroy(m_RT); m_RT = null; }
// HDR color pipeline is rendered to a 3D lut; it requires Texture3D & compute shaders // support - Desktop / Consoles / Some high-end mobiles void RenderHDRPipeline3D(PostProcessRenderContext context) { // Unfortunately because AnimationCurve doesn't implement GetHashCode and we don't have // any reliable way to figure out if a curve data is different from another one we can't // skip regenerating the Lut if nothing has changed. So it has to be done on every // frame... // It's not a very expensive operation anyway (we're talking about filling a 33x33x33 // Lut on the GPU) but every little thing helps, especially on mobile. { CheckInternalLogLut(); // Lut setup var compute = context.resources.computeShaders.lut3DBaker; int kernel = 0; switch (settings.tonemapper.value) { case Tonemapper.None: kernel = compute.FindKernel("KGenLut3D_NoTonemap"); break; case Tonemapper.Neutral: kernel = compute.FindKernel("KGenLut3D_NeutralTonemap"); break; case Tonemapper.ACES: kernel = compute.FindKernel("KGenLut3D_AcesTonemap"); break; case Tonemapper.Custom: kernel = compute.FindKernel("KGenLut3D_CustomTonemap"); break; } int groupSizeXY = Mathf.CeilToInt(k_Lut3DSize / 8f); int groupSizeZ = Mathf.CeilToInt(k_Lut3DSize / (RuntimeUtilities.isAndroidOpenGL ? 2f : 8f)); var cmd = context.command; cmd.SetComputeTextureParam(compute, kernel, "_Output", m_InternalLogLut); cmd.SetComputeVectorParam(compute, "_Size", new Vector4(k_Lut3DSize, 1f / (k_Lut3DSize - 1f), 0f, 0f)); var colorBalance = ColorUtilities.ComputeColorBalance(settings.temperature.value, settings.tint.value); cmd.SetComputeVectorParam(compute, "_ColorBalance", colorBalance); cmd.SetComputeVectorParam(compute, "_ColorFilter", settings.colorFilter.value); float hue = settings.hueShift.value / 360f; // Remap to [-0.5;0.5] float sat = settings.saturation.value / 100f + 1f; // Remap to [0;2] float con = settings.contrast.value / 100f + 1f; // Remap to [0;2] cmd.SetComputeVectorParam(compute, "_HueSatCon", new Vector4(hue, sat, con, 0f)); var channelMixerR = new Vector4(settings.mixerRedOutRedIn, settings.mixerRedOutGreenIn, settings.mixerRedOutBlueIn, 0f); var channelMixerG = new Vector4(settings.mixerGreenOutRedIn, settings.mixerGreenOutGreenIn, settings.mixerGreenOutBlueIn, 0f); var channelMixerB = new Vector4(settings.mixerBlueOutRedIn, settings.mixerBlueOutGreenIn, settings.mixerBlueOutBlueIn, 0f); cmd.SetComputeVectorParam(compute, "_ChannelMixerRed", channelMixerR / 100f); // Remap to [-2;2] cmd.SetComputeVectorParam(compute, "_ChannelMixerGreen", channelMixerG / 100f); cmd.SetComputeVectorParam(compute, "_ChannelMixerBlue", channelMixerB / 100f); var lift = ColorUtilities.ColorToLift(settings.lift.value * 0.2f); var gain = ColorUtilities.ColorToGain(settings.gain.value * 0.8f); var invgamma = ColorUtilities.ColorToInverseGamma(settings.gamma.value * 0.8f); cmd.SetComputeVectorParam(compute, "_Lift", new Vector4(lift.x, lift.y, lift.z, 0f)); cmd.SetComputeVectorParam(compute, "_InvGamma", new Vector4(invgamma.x, invgamma.y, invgamma.z, 0f)); cmd.SetComputeVectorParam(compute, "_Gain", new Vector4(gain.x, gain.y, gain.z, 0f)); cmd.SetComputeTextureParam(compute, kernel, "_Curves", GetCurveTexture(true)); if (settings.tonemapper.value == Tonemapper.Custom) { m_HableCurve.Init( settings.toneCurveToeStrength.value, settings.toneCurveToeLength.value, settings.toneCurveShoulderStrength.value, settings.toneCurveShoulderLength.value, settings.toneCurveShoulderAngle.value, settings.toneCurveGamma.value ); cmd.SetComputeVectorParam(compute, "_CustomToneCurve", m_HableCurve.uniforms.curve); cmd.SetComputeVectorParam(compute, "_ToeSegmentA", m_HableCurve.uniforms.toeSegmentA); cmd.SetComputeVectorParam(compute, "_ToeSegmentB", m_HableCurve.uniforms.toeSegmentB); cmd.SetComputeVectorParam(compute, "_MidSegmentA", m_HableCurve.uniforms.midSegmentA); cmd.SetComputeVectorParam(compute, "_MidSegmentB", m_HableCurve.uniforms.midSegmentB); cmd.SetComputeVectorParam(compute, "_ShoSegmentA", m_HableCurve.uniforms.shoSegmentA); cmd.SetComputeVectorParam(compute, "_ShoSegmentB", m_HableCurve.uniforms.shoSegmentB); } // Generate the lut context.command.BeginSample("HdrColorGradingLut3D"); cmd.DispatchCompute(compute, kernel, groupSizeXY, groupSizeXY, groupSizeZ); context.command.EndSample("HdrColorGradingLut3D"); } var lut = m_InternalLogLut; var uberSheet = context.uberSheet; uberSheet.EnableKeyword("COLOR_GRADING_HDR_3D"); uberSheet.properties.SetTexture(ShaderIDs.Lut3D, lut); uberSheet.properties.SetVector(ShaderIDs.Lut3D_Params, new Vector2(1f / lut.width, lut.width - 1f)); uberSheet.properties.SetFloat(ShaderIDs.PostExposure, RuntimeUtilities.Exp2(settings.postExposure.value)); context.logLut = lut; }
public override void Render(PostProcessRenderContext context) { var cmd = context.command; cmd.BeginSample("BloomPyramid"); var sheet = context.propertySheets.Get(context.resources.shaders.bloom); // Apply auto exposure adjustment in the prefiltering pass sheet.properties.SetTexture(ShaderIDs.AutoExposureTex, context.autoExposureTexture); // Do bloom on a half-res buffer, full-res doesn't bring much and kills performances on // fillrate limited platforms int tw = context.width / 2; int th = context.height / 2; // Determine the iteration count int s = Mathf.Max(tw, th); float logs = Mathf.Log(s, 2f) + Mathf.Min(settings.diffusion.value, 10f) - 10f; int logs_i = Mathf.FloorToInt(logs); int iterations = Mathf.Clamp(logs_i, 1, k_MaxPyramidSize); float sampleScale = 0.5f + logs - logs_i; sheet.properties.SetFloat(ShaderIDs.SampleScale, sampleScale); // Prefiltering parameters float lthresh = Mathf.GammaToLinearSpace(settings.threshold.value); float knee = lthresh * settings.softKnee.value + 1e-5f; var threshold = new Vector4(lthresh, lthresh - knee, knee * 2f, 0.25f / knee); sheet.properties.SetVector(ShaderIDs.Threshold, threshold); int qualityOffset = settings.mobileOptimized ? 1 : 0; // Downsample var last = context.source; for (int i = 0; i < iterations; i++) { int mipDown = m_Pyramid[i].down; int mipUp = m_Pyramid[i].up; int pass = i == 0 ? (int)Pass.Prefilter13 + qualityOffset : (int)Pass.Downsample13 + qualityOffset; cmd.GetTemporaryRT(mipDown, tw, th, 0, FilterMode.Bilinear, context.sourceFormat); cmd.GetTemporaryRT(mipUp, tw, th, 0, FilterMode.Bilinear, context.sourceFormat); cmd.BlitFullscreenTriangle(last, mipDown, sheet, pass); last = mipDown; tw = Mathf.Max(tw / 2, 1); th = Mathf.Max(th / 2, 1); } // Upsample last = m_Pyramid[iterations - 1].down; for (int i = iterations - 2; i >= 0; i--) { int mipDown = m_Pyramid[i].down; int mipUp = m_Pyramid[i].up; cmd.SetGlobalTexture(ShaderIDs.BloomTex, mipDown); cmd.BlitFullscreenTriangle(last, mipUp, sheet, (int)Pass.UpsampleTent + qualityOffset); last = mipUp; } var shaderSettings = new Vector4( sampleScale, RuntimeUtilities.Exp2(settings.intensity.value / 10f) - 1f, settings.lensIntensity.value, iterations ); var dirtTexture = settings.lensTexture.value == null ? RuntimeUtilities.blackTexture : settings.lensTexture.value; var uberSheet = context.uberSheet; uberSheet.EnableKeyword("BLOOM"); uberSheet.properties.SetVector(ShaderIDs.Bloom_Settings, shaderSettings); uberSheet.properties.SetColor(ShaderIDs.Bloom_Color, settings.color.value.linear); uberSheet.properties.SetTexture(ShaderIDs.Bloom_DirtTex, dirtTexture); cmd.SetGlobalTexture(ShaderIDs.BloomTex, m_Pyramid[0].up); // Cleanup for (int i = 0; i < iterations; i++) { cmd.ReleaseTemporaryRT(m_Pyramid[i].down); cmd.ReleaseTemporaryRT(m_Pyramid[i].up); } cmd.EndSample("BloomPyramid"); }
public override void Release() { RuntimeUtilities.Destroy(m_InternalSpectralLut); m_InternalSpectralLut = null; }
private void BuildCommandBuffers() { PostProcessRenderContext currentContext = m_CurrentContext; RenderTextureFormat renderTextureFormat = (!m_Camera.allowHDR) ? RenderTextureFormat.Default : RuntimeUtilities.defaultHDRRenderTextureFormat; if (!RuntimeUtilities.isFloatingPointFormat(renderTextureFormat)) { m_NaNKilled = true; } currentContext.Reset(); currentContext.camera = m_Camera; currentContext.sourceFormat = renderTextureFormat; m_LegacyCmdBufferBeforeReflections.Clear(); m_LegacyCmdBufferBeforeLighting.Clear(); m_LegacyCmdBufferOpaque.Clear(); m_LegacyCmdBuffer.Clear(); SetupContext(currentContext); currentContext.command = m_LegacyCmdBufferOpaque; TextureLerper.instance.BeginFrame(currentContext); UpdateSettingsIfNeeded(currentContext); PostProcessBundle bundle = GetBundle <AmbientOcclusion>(); AmbientOcclusion ambientOcclusion = bundle.CastSettings <AmbientOcclusion>(); AmbientOcclusionRenderer ambientOcclusionRenderer = bundle.CastRenderer <AmbientOcclusionRenderer>(); bool flag = ambientOcclusion.IsEnabledAndSupported(currentContext); bool flag2 = ambientOcclusionRenderer.IsAmbientOnly(currentContext); bool flag3 = flag && flag2; bool flag4 = flag && !flag2; PostProcessBundle bundle2 = GetBundle <ScreenSpaceReflections>(); PostProcessEffectSettings settings = bundle2.settings; PostProcessEffectRenderer renderer = bundle2.renderer; bool flag5 = settings.IsEnabledAndSupported(currentContext); if (flag3) { IAmbientOcclusionMethod ambientOcclusionMethod = ambientOcclusionRenderer.Get(); currentContext.command = m_LegacyCmdBufferBeforeReflections; ambientOcclusionMethod.RenderAmbientOnly(currentContext); currentContext.command = m_LegacyCmdBufferBeforeLighting; ambientOcclusionMethod.CompositeAmbientOnly(currentContext); } else if (flag4) { currentContext.command = m_LegacyCmdBufferOpaque; ambientOcclusionRenderer.Get().RenderAfterOpaque(currentContext); } bool flag6 = fog.IsEnabledAndSupported(currentContext); bool flag7 = HasOpaqueOnlyEffects(currentContext); int num = 0; num += (flag5 ? 1 : 0); num += (flag6 ? 1 : 0); num += (flag7 ? 1 : 0); RenderTargetIdentifier renderTargetIdentifier = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget); if (num > 0) { CommandBuffer commandBuffer = currentContext.command = m_LegacyCmdBufferOpaque; int nameID = m_TargetPool.Get(); currentContext.GetScreenSpaceTemporaryRT(commandBuffer, nameID, 0, renderTextureFormat); commandBuffer.BuiltinBlit(renderTargetIdentifier, nameID, RuntimeUtilities.copyStdMaterial, stopNaNPropagation ? 1 : 0); currentContext.source = nameID; int nameID2 = -1; if (num > 1) { nameID2 = m_TargetPool.Get(); currentContext.GetScreenSpaceTemporaryRT(commandBuffer, nameID2, 0, renderTextureFormat); currentContext.destination = nameID2; } else { currentContext.destination = renderTargetIdentifier; } if (flag5) { renderer.Render(currentContext); num--; RenderTargetIdentifier source = currentContext.source; currentContext.source = currentContext.destination; currentContext.destination = ((num != 1) ? source : renderTargetIdentifier); } if (flag6) { fog.Render(currentContext); num--; RenderTargetIdentifier source2 = currentContext.source; currentContext.source = currentContext.destination; currentContext.destination = ((num != 1) ? source2 : renderTargetIdentifier); } if (flag7) { RenderOpaqueOnly(currentContext); } if (num > 1) { commandBuffer.ReleaseTemporaryRT(nameID2); } commandBuffer.ReleaseTemporaryRT(nameID); } int nameID3 = m_TargetPool.Get(); currentContext.GetScreenSpaceTemporaryRT(m_LegacyCmdBuffer, nameID3, 0, renderTextureFormat, RenderTextureReadWrite.sRGB); m_LegacyCmdBuffer.BuiltinBlit(renderTargetIdentifier, nameID3, RuntimeUtilities.copyStdMaterial, stopNaNPropagation ? 1 : 0); if (!m_NaNKilled) { m_NaNKilled = stopNaNPropagation; } currentContext.command = m_LegacyCmdBuffer; currentContext.source = nameID3; currentContext.destination = renderTargetIdentifier; Render(currentContext); m_LegacyCmdBuffer.ReleaseTemporaryRT(nameID3); }
public void Release() { RuntimeUtilities.Destroy(m_Result); m_Result = null; }
public override void Interp(Texture from, Texture to, float t) { if (from == null && to == null) { value = null; return; } if (from != null && to != null) { value = TextureLerper.instance.Lerp(from, to, t); return; } if (defaultState == TextureParameterDefault.Lut2D) { int size = (!(from != null)) ? to.height : from.height; Texture lutStrip = RuntimeUtilities.GetLutStrip(size); if (from == null) { from = lutStrip; } if (to == null) { to = lutStrip; } } Color to2; switch (defaultState) { case TextureParameterDefault.Black: to2 = Color.black; break; case TextureParameterDefault.White: to2 = Color.white; break; case TextureParameterDefault.Transparent: to2 = Color.clear; break; case TextureParameterDefault.Lut2D: { int size2 = (!(from != null)) ? to.height : from.height; Texture lutStrip2 = RuntimeUtilities.GetLutStrip(size2); if (from == null) { from = lutStrip2; } if (to == null) { to = lutStrip2; } value = TextureLerper.instance.Lerp(from, to, t); return; } default: base.Interp(from, to, t); return; } if (from == null) { value = TextureLerper.instance.Lerp(to, to2, 1f - t); } else { value = TextureLerper.instance.Lerp(from, to2, t); } }