632 lines
20 KiB
C#
632 lines
20 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Rendering.Universal;
|
|
|
|
namespace HorizonBasedAmbientOcclusion.Universal
|
|
{
|
|
[ExecuteInEditMode, VolumeComponentMenu("Lighting/HBAO")]
|
|
public class HBAO : VolumeComponent, IPostProcessComponent
|
|
{
|
|
public enum Preset
|
|
{
|
|
FastestPerformance,
|
|
FastPerformance,
|
|
Normal,
|
|
HighQuality,
|
|
HighestQuality,
|
|
Custom
|
|
}
|
|
|
|
public enum Mode
|
|
{
|
|
Normal,
|
|
LitAO
|
|
}
|
|
|
|
public enum RenderingPath
|
|
{
|
|
Forward,
|
|
Deferred
|
|
}
|
|
|
|
public enum Quality
|
|
{
|
|
Lowest,
|
|
Low,
|
|
Medium,
|
|
High,
|
|
Highest
|
|
}
|
|
|
|
public enum Resolution
|
|
{
|
|
Full,
|
|
Half
|
|
}
|
|
|
|
public enum NoiseType
|
|
{
|
|
Dither,
|
|
InterleavedGradientNoise,
|
|
SpatialDistribution
|
|
}
|
|
|
|
public enum Deinterleaving
|
|
{
|
|
Disabled,
|
|
x4
|
|
}
|
|
|
|
public enum DebugMode
|
|
{
|
|
Disabled,
|
|
AOOnly,
|
|
ColorBleedingOnly,
|
|
SplitWithoutAOAndWithAO,
|
|
SplitWithAOAndAOOnly,
|
|
SplitWithoutAOAndAOOnly,
|
|
ViewNormals
|
|
}
|
|
|
|
public enum BlurType
|
|
{
|
|
None,
|
|
Narrow,
|
|
Medium,
|
|
Wide,
|
|
ExtraWide
|
|
}
|
|
|
|
public enum PerPixelNormals
|
|
{
|
|
Reconstruct2Samples,
|
|
Reconstruct4Samples,
|
|
Camera
|
|
}
|
|
|
|
public enum VarianceClipping
|
|
{
|
|
Disabled,
|
|
_4Tap,
|
|
_8Tap
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class PresetParameter : VolumeParameter<Preset>
|
|
{
|
|
public PresetParameter(Preset value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class ModeParameter : VolumeParameter<Mode>
|
|
{
|
|
public ModeParameter(Mode value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class RenderingPathParameter : VolumeParameter<RenderingPath>
|
|
{
|
|
public RenderingPathParameter(RenderingPath value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class QualityParameter : VolumeParameter<Quality>
|
|
{
|
|
public QualityParameter(Quality value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class DeinterleavingParameter : VolumeParameter<Deinterleaving>
|
|
{
|
|
public DeinterleavingParameter(Deinterleaving value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class ResolutionParameter : VolumeParameter<Resolution>
|
|
{
|
|
public ResolutionParameter(Resolution value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class NoiseTypeParameter : VolumeParameter<NoiseType>
|
|
{
|
|
public NoiseTypeParameter(NoiseType value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class DebugModeParameter : VolumeParameter<DebugMode>
|
|
{
|
|
public DebugModeParameter(DebugMode value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class PerPixelNormalsParameter : VolumeParameter<PerPixelNormals>
|
|
{
|
|
public PerPixelNormalsParameter(PerPixelNormals value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class VarianceClippingParameter : VolumeParameter<VarianceClipping>
|
|
{
|
|
public VarianceClippingParameter(VarianceClipping value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class BlurTypeParameter : VolumeParameter<BlurType>
|
|
{
|
|
public BlurTypeParameter(BlurType value, bool overrideState = false)
|
|
: base(value, overrideState) { }
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class MinMaxFloatParameter : VolumeParameter<Vector2>
|
|
{
|
|
public float min;
|
|
public float max;
|
|
|
|
public MinMaxFloatParameter(Vector2 value, float min, float max, bool overrideState = false)
|
|
: base(value, overrideState)
|
|
{
|
|
this.min = min;
|
|
this.max = max;
|
|
}
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Field)]
|
|
public class SettingsGroup : Attribute
|
|
{
|
|
public bool isExpanded = true;
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Field)]
|
|
public class ParameterDisplayName : Attribute
|
|
{
|
|
public string name;
|
|
|
|
public ParameterDisplayName(string name)
|
|
{
|
|
this.name = name;
|
|
}
|
|
}
|
|
|
|
public class Presets : SettingsGroup { }
|
|
public class GeneralSettings : SettingsGroup { }
|
|
public class AOSettings : SettingsGroup { }
|
|
public class TemporalFilterSettings : SettingsGroup { }
|
|
public class BlurSettings : SettingsGroup { }
|
|
public class ColorBleedingSettings : SettingsGroup { }
|
|
|
|
[Presets]
|
|
public PresetParameter preset = new PresetParameter(Preset.Normal);
|
|
|
|
[Tooltip("The mode of the AO.")]
|
|
[GeneralSettings, Space(6)]
|
|
public ModeParameter mode = new ModeParameter(Mode.Normal);
|
|
[Tooltip("The rendering path used for AO. Temporary settings as for now rendering path is internal to renderer settings.")]
|
|
[GeneralSettings, Space(6)]
|
|
public RenderingPathParameter renderingPath = new RenderingPathParameter(RenderingPath.Forward);
|
|
[Tooltip("The quality of the AO.")]
|
|
[GeneralSettings, Space(6)]
|
|
public QualityParameter quality = new QualityParameter(Quality.Medium);
|
|
[Tooltip("The deinterleaving factor.")]
|
|
[GeneralSettings]
|
|
public DeinterleavingParameter deinterleaving = new DeinterleavingParameter(Deinterleaving.Disabled);
|
|
[Tooltip("The resolution at which the AO is calculated.")]
|
|
[GeneralSettings]
|
|
public ResolutionParameter resolution = new ResolutionParameter(Resolution.Full);
|
|
[Tooltip("The type of noise to use.")]
|
|
[GeneralSettings, Space(10)]
|
|
public NoiseTypeParameter noiseType = new NoiseTypeParameter(NoiseType.Dither);
|
|
[Tooltip("The debug mode actually displayed on screen.")]
|
|
[GeneralSettings, Space(10)]
|
|
public DebugModeParameter debugMode = new DebugModeParameter(DebugMode.Disabled);
|
|
|
|
[Tooltip("AO radius: this is the distance outside which occluders are ignored.")]
|
|
[AOSettings, Space(6)]
|
|
public ClampedFloatParameter radius = new ClampedFloatParameter(0.8f, 0.25f, 5f);
|
|
[Tooltip("Maximum radius in pixels: this prevents the radius to grow too much with close-up " +
|
|
"object and impact on performances.")]
|
|
[AOSettings]
|
|
public ClampedFloatParameter maxRadiusPixels = new ClampedFloatParameter(128f, 16f, 256f);
|
|
[Tooltip("For low-tessellated geometry, occlusion variations tend to appear at creases and " +
|
|
"ridges, which betray the underlying tessellation. To remove these artifacts, we use " +
|
|
"an angle bias parameter which restricts the hemisphere.")]
|
|
[AOSettings]
|
|
public ClampedFloatParameter bias = new ClampedFloatParameter(0.05f, 0f, 0.5f);
|
|
[Tooltip("This value allows to scale up the ambient occlusion values.")]
|
|
[AOSettings]
|
|
public ClampedFloatParameter intensity = new ClampedFloatParameter(0f, 0, 4f);
|
|
[Tooltip("Enable/disable MultiBounce approximation.")]
|
|
[AOSettings]
|
|
public BoolParameter useMultiBounce = new BoolParameter(false);
|
|
[Tooltip("MultiBounce approximation influence.")]
|
|
[AOSettings]
|
|
public ClampedFloatParameter multiBounceInfluence = new ClampedFloatParameter(1f, 0f, 1f);
|
|
[Tooltip("How much AO affect direct lighting.")]
|
|
[AOSettings]
|
|
public ClampedFloatParameter directLightingStrength = new ClampedFloatParameter(0.25f, 0, 1f);
|
|
[Tooltip("The amount of AO offscreen samples are contributing.")]
|
|
[AOSettings]
|
|
public ClampedFloatParameter offscreenSamplesContribution = new ClampedFloatParameter(0f, 0f, 1f);
|
|
[Tooltip("The max distance to display AO.")]
|
|
[AOSettings, Space(10)]
|
|
public FloatParameter maxDistance = new FloatParameter(150f);
|
|
[Tooltip("The distance before max distance at which AO start to decrease.")]
|
|
[AOSettings]
|
|
public FloatParameter distanceFalloff = new FloatParameter(50f);
|
|
[Tooltip("The type of per pixel normals to use.")]
|
|
[AOSettings, Space(10)]
|
|
#if URP_10_0_0_OR_NEWER
|
|
public PerPixelNormalsParameter perPixelNormals = new PerPixelNormalsParameter(PerPixelNormals.Camera);
|
|
#else
|
|
public PerPixelNormalsParameter perPixelNormals = new PerPixelNormalsParameter(PerPixelNormals.Reconstruct4Samples);
|
|
#endif
|
|
[Tooltip("This setting allow you to set the base color if the AO, the alpha channel value is unused.")]
|
|
[AOSettings, Space(10)]
|
|
public ColorParameter baseColor = new ColorParameter(Color.black);
|
|
|
|
[TemporalFilterSettings, ParameterDisplayName("Enabled"), Space(6)]
|
|
public BoolParameter temporalFilterEnabled = new BoolParameter(false);
|
|
[Tooltip("The type of variance clipping to use.")]
|
|
[TemporalFilterSettings]
|
|
public VarianceClippingParameter varianceClipping = new VarianceClippingParameter(VarianceClipping._4Tap);
|
|
|
|
[Tooltip("The type of blur to use.")]
|
|
[BlurSettings, ParameterDisplayName("Type"), Space(6)]
|
|
public BlurTypeParameter blurType = new BlurTypeParameter(BlurType.Medium);
|
|
|
|
[Tooltip("This parameter controls the depth-dependent weight of the bilateral filter, to " +
|
|
"avoid bleeding across edges. A zero sharpness is a pure Gaussian blur. Increasing " +
|
|
"the blur sharpness removes bleeding by using lower weights for samples with large " +
|
|
"depth delta from the current pixel.")]
|
|
[BlurSettings, Space(10)]
|
|
public ClampedFloatParameter sharpness = new ClampedFloatParameter(8f, 0f, 16f);
|
|
|
|
[ColorBleedingSettings, ParameterDisplayName("Enabled"), Space(6)]
|
|
public BoolParameter colorBleedingEnabled = new BoolParameter(false);
|
|
[Tooltip("This value allows to control the saturation of the color bleeding.")]
|
|
[ColorBleedingSettings, Space(10)]
|
|
public ClampedFloatParameter saturation = new ClampedFloatParameter(1f, 0f, 4f);
|
|
[Tooltip("Use masking on emissive pixels")]
|
|
[ColorBleedingSettings]
|
|
public ClampedFloatParameter brightnessMask = new ClampedFloatParameter(1f, 0f, 1f);
|
|
[Tooltip("Brightness level where masking starts/ends")]
|
|
[ColorBleedingSettings]
|
|
public MinMaxFloatParameter brightnessMaskRange = new MinMaxFloatParameter(new Vector2(0f, 0.5f), 0f, 2f);
|
|
|
|
public void EnableHBAO(bool enable)
|
|
{
|
|
intensity.overrideState = enable;
|
|
}
|
|
|
|
public Preset GetCurrentPreset()
|
|
{
|
|
return preset.value;
|
|
}
|
|
|
|
public void ApplyPreset(Preset preset)
|
|
{
|
|
if (preset == Preset.Custom)
|
|
{
|
|
this.preset.Override(preset);
|
|
return;
|
|
}
|
|
|
|
var actualDebugMode = debugMode.value;
|
|
var actualDebugModeOverride = debugMode.overrideState;
|
|
SetAllOverridesTo(false);
|
|
debugMode.overrideState = actualDebugModeOverride;
|
|
debugMode.value = actualDebugMode;
|
|
|
|
switch (preset)
|
|
{
|
|
case Preset.FastestPerformance:
|
|
SetQuality(Quality.Lowest);
|
|
SetAoRadius(0.5f);
|
|
SetAoMaxRadiusPixels(64.0f);
|
|
SetBlurType(BlurType.ExtraWide);
|
|
break;
|
|
case Preset.FastPerformance:
|
|
SetQuality(Quality.Low);
|
|
SetAoRadius(0.5f);
|
|
SetAoMaxRadiusPixels(64.0f);
|
|
SetBlurType(BlurType.Wide);
|
|
break;
|
|
case Preset.HighQuality:
|
|
SetQuality(Quality.High);
|
|
SetAoRadius(1.0f);
|
|
break;
|
|
case Preset.HighestQuality:
|
|
SetQuality(Quality.Highest);
|
|
SetAoRadius(1.2f);
|
|
SetAoMaxRadiusPixels(256.0f);
|
|
SetBlurType(BlurType.Narrow);
|
|
break;
|
|
case Preset.Normal:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
this.preset.Override(preset);
|
|
}
|
|
|
|
public Mode GetMode()
|
|
{
|
|
return mode.value;
|
|
}
|
|
|
|
public void SetMode(Mode mode)
|
|
{
|
|
this.mode.Override(mode);
|
|
}
|
|
|
|
public RenderingPath GetRenderingPath()
|
|
{
|
|
return renderingPath.value;
|
|
}
|
|
|
|
public void SetRenderingPath(RenderingPath renderingPath)
|
|
{
|
|
this.renderingPath.Override(renderingPath);
|
|
}
|
|
|
|
public Quality GetQuality()
|
|
{
|
|
return quality.value;
|
|
}
|
|
|
|
public void SetQuality(Quality quality)
|
|
{
|
|
this.quality.Override(quality);
|
|
}
|
|
|
|
public Deinterleaving GetDeinterleaving()
|
|
{
|
|
return deinterleaving.value;
|
|
}
|
|
|
|
public void SetDeinterleaving(Deinterleaving deinterleaving)
|
|
{
|
|
this.deinterleaving.Override(deinterleaving);
|
|
}
|
|
|
|
public Resolution GetResolution()
|
|
{
|
|
return resolution.value;
|
|
}
|
|
|
|
public void SetResolution(Resolution resolution)
|
|
{
|
|
this.resolution.Override(resolution);
|
|
}
|
|
|
|
public NoiseType GetNoiseType()
|
|
{
|
|
return noiseType.value;
|
|
}
|
|
|
|
public void SetNoiseType(NoiseType noiseType)
|
|
{
|
|
this.noiseType.Override(noiseType);
|
|
}
|
|
|
|
public DebugMode GetDebugMode()
|
|
{
|
|
return debugMode.value;
|
|
}
|
|
|
|
public void SetDebugMode(DebugMode debugMode)
|
|
{
|
|
this.debugMode.Override(debugMode);
|
|
}
|
|
|
|
public float GetAoRadius()
|
|
{
|
|
return radius.value;
|
|
}
|
|
|
|
public void SetAoRadius(float radius)
|
|
{
|
|
this.radius.Override(Mathf.Clamp(radius, this.radius.min, this.radius.max));
|
|
}
|
|
|
|
public float GetAoMaxRadiusPixels()
|
|
{
|
|
return maxRadiusPixels.value;
|
|
}
|
|
|
|
public void SetAoMaxRadiusPixels(float maxRadiusPixels)
|
|
{
|
|
this.maxRadiusPixels.Override(Mathf.Clamp(maxRadiusPixels, this.maxRadiusPixels.min, this.maxRadiusPixels.max));
|
|
}
|
|
|
|
public float GetAoBias()
|
|
{
|
|
return bias.value;
|
|
}
|
|
|
|
public void SetAoBias(float bias)
|
|
{
|
|
this.bias.Override(Mathf.Clamp(bias, this.bias.min, this.bias.max));
|
|
}
|
|
|
|
public float GetAoOffscreenSamplesContribution()
|
|
{
|
|
return offscreenSamplesContribution.value;
|
|
}
|
|
|
|
public void SetAoOffscreenSamplesContribution(float offscreenSamplesContribution)
|
|
{
|
|
this.offscreenSamplesContribution.Override(Mathf.Clamp(offscreenSamplesContribution, this.offscreenSamplesContribution.min, this.offscreenSamplesContribution.max));
|
|
}
|
|
|
|
public float GetAoMaxDistance()
|
|
{
|
|
return maxDistance.value;
|
|
}
|
|
|
|
public void SetAoMaxDistance(float maxDistance)
|
|
{
|
|
this.maxDistance.Override(maxDistance);
|
|
}
|
|
|
|
public float GetAoDistanceFalloff()
|
|
{
|
|
return distanceFalloff.value;
|
|
}
|
|
|
|
public void SetAoDistanceFalloff(float distanceFalloff)
|
|
{
|
|
this.distanceFalloff.Override(distanceFalloff);
|
|
}
|
|
|
|
public PerPixelNormals GetAoPerPixelNormals()
|
|
{
|
|
return perPixelNormals.value;
|
|
}
|
|
|
|
public void SetAoPerPixelNormals(PerPixelNormals perPixelNormals)
|
|
{
|
|
this.perPixelNormals.Override(perPixelNormals);
|
|
}
|
|
|
|
public Color GetAoColor()
|
|
{
|
|
return baseColor.value;
|
|
}
|
|
|
|
public void SetAoColor(Color baseColor)
|
|
{
|
|
this.baseColor.Override(baseColor);
|
|
}
|
|
|
|
public float GetAoIntensity()
|
|
{
|
|
return intensity.value;
|
|
}
|
|
|
|
public void SetAoIntensity(float intensity)
|
|
{
|
|
this.intensity.Override(Mathf.Clamp(intensity, this.intensity.min, this.intensity.max));
|
|
}
|
|
|
|
public bool UseMultiBounce()
|
|
{
|
|
return useMultiBounce.value;
|
|
}
|
|
|
|
public void EnableMultiBounce(bool enabled = true)
|
|
{
|
|
useMultiBounce.Override(enabled);
|
|
}
|
|
|
|
public float GetAoMultiBounceInfluence()
|
|
{
|
|
return multiBounceInfluence.value;
|
|
}
|
|
|
|
public void SetAoMultiBounceInfluence(float multiBounceInfluence)
|
|
{
|
|
this.multiBounceInfluence.Override(Mathf.Clamp(multiBounceInfluence, this.multiBounceInfluence.min, this.multiBounceInfluence.max));
|
|
}
|
|
|
|
public bool IsTemporalFilterEnabled()
|
|
{
|
|
return temporalFilterEnabled.value;
|
|
}
|
|
|
|
public void EnableTemporalFilter(bool enabled = true)
|
|
{
|
|
temporalFilterEnabled.Override(enabled);
|
|
}
|
|
|
|
public VarianceClipping GetTemporalFilterVarianceClipping()
|
|
{
|
|
return varianceClipping.value;
|
|
}
|
|
|
|
public void SetTemporalFilterVarianceClipping(VarianceClipping varianceClipping)
|
|
{
|
|
this.varianceClipping.Override(varianceClipping);
|
|
}
|
|
|
|
public BlurType GetBlurType()
|
|
{
|
|
return blurType.value;
|
|
}
|
|
|
|
public void SetBlurType(BlurType blurType)
|
|
{
|
|
this.blurType.Override(blurType);
|
|
}
|
|
|
|
public float GetBlurSharpness()
|
|
{
|
|
return sharpness.value;
|
|
}
|
|
|
|
public void SetBlurSharpness(float sharpness)
|
|
{
|
|
this.sharpness.Override(Mathf.Clamp(sharpness, this.sharpness.min, this.sharpness.max));
|
|
}
|
|
|
|
public bool IsColorBleedingEnabled()
|
|
{
|
|
return colorBleedingEnabled.value;
|
|
}
|
|
|
|
public void EnableColorBleeding(bool enabled = true)
|
|
{
|
|
colorBleedingEnabled.Override(enabled);
|
|
}
|
|
|
|
public float GetColorBleedingSaturation()
|
|
{
|
|
return saturation.value;
|
|
}
|
|
|
|
public void SetColorBleedingSaturation(float saturation)
|
|
{
|
|
this.saturation.Override(Mathf.Clamp(saturation, this.saturation.min, this.saturation.max));
|
|
}
|
|
|
|
public float GetColorBleedingBrightnessMask()
|
|
{
|
|
return brightnessMask.value;
|
|
}
|
|
|
|
public void SetColorBleedingBrightnessMask(float brightnessMask)
|
|
{
|
|
this.brightnessMask.Override(Mathf.Clamp(brightnessMask, this.brightnessMask.min, this.brightnessMask.max));
|
|
}
|
|
|
|
public Vector2 GetColorBleedingBrightnessMaskRange()
|
|
{
|
|
return brightnessMaskRange.value;
|
|
}
|
|
|
|
public void SetColorBleedingBrightnessMaskRange(Vector2 brightnessMaskRange)
|
|
{
|
|
brightnessMaskRange.x = Mathf.Clamp(brightnessMaskRange.x, this.brightnessMaskRange.min, this.brightnessMaskRange.max);
|
|
brightnessMaskRange.y = Mathf.Clamp(brightnessMaskRange.y, this.brightnessMaskRange.min, this.brightnessMaskRange.max);
|
|
brightnessMaskRange.x = Mathf.Min(brightnessMaskRange.x, brightnessMaskRange.y);
|
|
this.brightnessMaskRange.Override(brightnessMaskRange);
|
|
}
|
|
|
|
public bool IsActive() => intensity.overrideState && intensity.value > 0;
|
|
|
|
public bool IsTileCompatible() => true;
|
|
}
|
|
}
|