563 lines
26 KiB
C#
563 lines
26 KiB
C#
using System;
|
|
using UnityEngine.Experimental.Rendering;
|
|
using UnityEngine.Serialization;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
/// <summary>
|
|
/// A volume component that holds settings for the ambient occlusion.
|
|
/// </summary>
|
|
[Serializable, VolumeComponentMenu("Lighting/Ambient Occlusion")]
|
|
[HelpURL(Documentation.baseURL + Documentation.version + Documentation.subURL + "Override-Ambient-Occlusion" + Documentation.endURL)]
|
|
public sealed class AmbientOcclusion : VolumeComponentWithQuality
|
|
{
|
|
/// <summary>
|
|
/// Enable ray traced ambient occlusion.
|
|
/// </summary>
|
|
public BoolParameter rayTracing = new BoolParameter(false);
|
|
|
|
/// <summary>
|
|
/// Controls the strength of the ambient occlusion effect. Increase this value to produce darker areas.
|
|
/// </summary>
|
|
public ClampedFloatParameter intensity = new ClampedFloatParameter(0f, 0f, 4f);
|
|
/// <summary>
|
|
/// Controls how much the ambient occlusion affects direct lighting.
|
|
/// </summary>
|
|
public ClampedFloatParameter directLightingStrength = new ClampedFloatParameter(0f, 0f, 1f);
|
|
/// <summary>
|
|
/// Sampling radius. Bigger the radius, wider AO will be achieved, risking to lose fine details and increasing cost of the effect due to increasing cache misses.
|
|
/// </summary>
|
|
public ClampedFloatParameter radius = new ClampedFloatParameter(2.0f, 0.25f, 5.0f);
|
|
|
|
/// <summary>
|
|
/// Moving this factor closer to 0 will increase the amount of accepted samples during temporal accumulation, increasing the ghosting, but reducing the temporal noise.
|
|
/// </summary>
|
|
public ClampedFloatParameter spatialBilateralAggressiveness = new ClampedFloatParameter(0.15f, 0.0f, 1.0f);
|
|
|
|
|
|
/// <summary>
|
|
/// Whether the results are accumulated over time or not. This can get higher quality results at a cheaper cost, but it can lead to temporal artifacts such as ghosting.
|
|
/// </summary>
|
|
public BoolParameter temporalAccumulation = new BoolParameter(true);
|
|
|
|
// Temporal only parameters
|
|
/// <summary>
|
|
/// Moving this factor closer to 0 will increase the amount of accepted samples during temporal accumulation, increasing the ghosting, but reducing the temporal noise.
|
|
/// </summary>
|
|
public ClampedFloatParameter ghostingReduction = new ClampedFloatParameter(0.5f, 0.0f, 1.0f);
|
|
|
|
// Non-temporal only parameters
|
|
/// <summary>
|
|
/// Modify the non-temporal blur to change how sharp features are preserved. Lower values leads to blurrier/softer results, higher values gets a sharper result, but with the risk of noise.
|
|
/// </summary>
|
|
public ClampedFloatParameter blurSharpness = new ClampedFloatParameter(0.1f, 0.0f, 1.0f);
|
|
|
|
// Ray tracing parameters
|
|
/// <summary>
|
|
/// Defines the layers that ray traced ambient occlusion should include.
|
|
/// </summary>
|
|
public LayerMaskParameter layerMask = new LayerMaskParameter(-1);
|
|
|
|
/// <summary>
|
|
/// Controls the length of ray traced ambient occlusion rays.
|
|
/// </summary>
|
|
public float rayLength
|
|
{
|
|
get
|
|
{
|
|
if (!UsesQualitySettings())
|
|
return m_RayLength.value;
|
|
else
|
|
return GetLightingQualitySettings().RTAORayLength[(int)quality.value];
|
|
}
|
|
set { m_RayLength.value = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Number of samples for evaluating the effect.
|
|
/// </summary>
|
|
public int sampleCount
|
|
{
|
|
get
|
|
{
|
|
if (!UsesQualitySettings())
|
|
return m_SampleCount.value;
|
|
else
|
|
return GetLightingQualitySettings().RTAOSampleCount[(int)quality.value];
|
|
}
|
|
set { m_SampleCount.value = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Defines if the ray traced ambient occlusion should be denoised.
|
|
/// </summary>
|
|
public bool denoise
|
|
{
|
|
get
|
|
{
|
|
if (!UsesQualitySettings())
|
|
return m_Denoise.value;
|
|
else
|
|
return GetLightingQualitySettings().RTAODenoise[(int)quality.value];
|
|
}
|
|
set { m_Denoise.value = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Controls the radius of the ray traced ambient occlusion denoiser.
|
|
/// </summary>
|
|
public float denoiserRadius
|
|
{
|
|
get
|
|
{
|
|
if (!UsesQualitySettings())
|
|
return m_DenoiserRadius.value;
|
|
else
|
|
return GetLightingQualitySettings().RTAODenoiserRadius[(int)quality.value];
|
|
}
|
|
set { m_DenoiserRadius.value = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Number of steps to take along one signed direction during horizon search (this is the number of steps in positive and negative direction). Increasing the value can lead to detection
|
|
/// of finer details, but is not a guarantee of higher quality otherwise. Also note that increasing this value will lead to higher cost.
|
|
/// </summary>
|
|
public int stepCount
|
|
{
|
|
get
|
|
{
|
|
if (!UsesQualitySettings())
|
|
return m_StepCount.value;
|
|
else
|
|
return GetLightingQualitySettings().AOStepCount[(int)quality.value];
|
|
}
|
|
set { m_StepCount.value = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// If this option is set to true, the effect runs at full resolution. This will increases quality, but also decreases performance significantly.
|
|
/// </summary>
|
|
public bool fullResolution
|
|
{
|
|
get
|
|
{
|
|
if (!UsesQualitySettings())
|
|
return m_FullResolution.value;
|
|
else
|
|
return GetLightingQualitySettings().AOFullRes[(int)quality.value];
|
|
}
|
|
set { m_FullResolution.value = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// This field imposes a maximum radius in pixels that will be considered. It is very important to keep this as tight as possible to preserve good performance.
|
|
/// Note that the pixel value specified for this field is the value used for 1080p when *not* running the effect at full resolution, it will be scaled accordingly
|
|
/// for other resolutions.
|
|
/// </summary>
|
|
public int maximumRadiusInPixels
|
|
{
|
|
get
|
|
{
|
|
if (!UsesQualitySettings())
|
|
return m_MaximumRadiusInPixels.value;
|
|
else
|
|
return GetLightingQualitySettings().AOMaximumRadiusPixels[(int)quality.value];
|
|
}
|
|
set { m_MaximumRadiusInPixels.value = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// This upsample method preserves sharp edges better, however may result in visible aliasing and it is slightly more expensive.
|
|
/// </summary>
|
|
public bool bilateralUpsample
|
|
{
|
|
get
|
|
{
|
|
if (!UsesQualitySettings())
|
|
return m_BilateralUpsample.value;
|
|
else
|
|
return GetLightingQualitySettings().AOBilateralUpsample[(int)quality.value];
|
|
}
|
|
set { m_BilateralUpsample.value = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Number of directions searched for occlusion at each each pixel when temporal accumulation is disabled.
|
|
/// </summary>
|
|
public int directionCount
|
|
{
|
|
get
|
|
{
|
|
if (!UsesQualitySettings())
|
|
return m_DirectionCount.value;
|
|
else
|
|
return GetLightingQualitySettings().AODirectionCount[(int)quality.value];
|
|
}
|
|
set { m_DirectionCount.value = value; }
|
|
}
|
|
|
|
// SSAO
|
|
[SerializeField, FormerlySerializedAs("stepCount")]
|
|
private ClampedIntParameter m_StepCount = new ClampedIntParameter(6, 2, 32);
|
|
[SerializeField, FormerlySerializedAs("fullResolution")]
|
|
private BoolParameter m_FullResolution = new BoolParameter(false);
|
|
[SerializeField, FormerlySerializedAs("maximumRadiusInPixels")]
|
|
private ClampedIntParameter m_MaximumRadiusInPixels = new ClampedIntParameter(40, 16, 256);
|
|
// Temporal only parameter
|
|
[AdditionalProperty]
|
|
[SerializeField, FormerlySerializedAs("bilateralUpsample")]
|
|
private BoolParameter m_BilateralUpsample = new BoolParameter(true);
|
|
// Non-temporal only parameters
|
|
[SerializeField, FormerlySerializedAs("directionCount")]
|
|
private ClampedIntParameter m_DirectionCount = new ClampedIntParameter(2, 1, 6);
|
|
|
|
// RTAO
|
|
[SerializeField, FormerlySerializedAs("rayLength")]
|
|
private MinFloatParameter m_RayLength = new MinFloatParameter(50.0f, 0.01f);
|
|
[SerializeField, FormerlySerializedAs("sampleCount")]
|
|
private ClampedIntParameter m_SampleCount = new ClampedIntParameter(1, 1, 64);
|
|
[SerializeField, FormerlySerializedAs("denoise")]
|
|
private BoolParameter m_Denoise = new BoolParameter(true);
|
|
[SerializeField, FormerlySerializedAs("denoiserRadius")]
|
|
private ClampedFloatParameter m_DenoiserRadius = new ClampedFloatParameter(1.0f, 0.001f, 1.0f);
|
|
}
|
|
|
|
partial class AmbientOcclusionSystem
|
|
{
|
|
RenderPipelineResources m_Resources;
|
|
RenderPipelineSettings m_Settings;
|
|
|
|
private bool m_HistoryReady = false;
|
|
private bool m_RunningFullRes = false;
|
|
|
|
readonly HDRaytracingAmbientOcclusion m_RaytracingAmbientOcclusion = new HDRaytracingAmbientOcclusion();
|
|
|
|
internal AmbientOcclusionSystem(HDRenderPipelineAsset hdAsset, RenderPipelineResources defaultResources)
|
|
{
|
|
m_Settings = hdAsset.currentPlatformRenderPipelineSettings;
|
|
m_Resources = defaultResources;
|
|
}
|
|
|
|
internal void InitRaytracing(HDRenderPipeline renderPipeline)
|
|
{
|
|
m_RaytracingAmbientOcclusion.Init(renderPipeline);
|
|
}
|
|
|
|
internal float EvaluateSpecularOcclusionFlag(HDCamera hdCamera)
|
|
{
|
|
AmbientOcclusion ssoSettings = hdCamera.volumeStack.GetComponent<AmbientOcclusion>();
|
|
bool enableRTAO = hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && ssoSettings.rayTracing.value;
|
|
if (enableRTAO)
|
|
return m_RaytracingAmbientOcclusion.EvaluateRTSpecularOcclusionFlag(hdCamera, ssoSettings);
|
|
else
|
|
return 1.0f;
|
|
}
|
|
|
|
internal bool IsActive(HDCamera camera, AmbientOcclusion settings) => camera.frameSettings.IsEnabled(FrameSettingsField.SSAO) && settings.intensity.value > 0f;
|
|
|
|
struct RenderAOParameters
|
|
{
|
|
public ComputeShader gtaoCS;
|
|
public int gtaoKernel;
|
|
public ComputeShader spatialDenoiseAOCS;
|
|
public int denoiseKernelSpatial;
|
|
public ComputeShader temporalDenoiseAOCS;
|
|
public int denoiseKernelTemporal;
|
|
public ComputeShader copyHistoryAOCS;
|
|
public int denoiseKernelCopyHistory;
|
|
public ComputeShader upsampleAndBlurAOCS;
|
|
public int upsampleAndBlurKernel;
|
|
public int upsampleAOKernel;
|
|
|
|
public Vector2 runningRes;
|
|
public int viewCount;
|
|
public bool historyReady;
|
|
public int outputWidth;
|
|
public int outputHeight;
|
|
public bool fullResolution;
|
|
public bool runAsync;
|
|
public bool temporalAccumulation;
|
|
public bool bilateralUpsample;
|
|
|
|
public ShaderVariablesAmbientOcclusion cb;
|
|
}
|
|
|
|
RenderAOParameters PrepareRenderAOParameters(HDCamera camera, Vector2 historySize, in HDUtils.PackedMipChainInfo depthMipInfo)
|
|
{
|
|
var parameters = new RenderAOParameters();
|
|
|
|
ref var cb = ref parameters.cb;
|
|
|
|
// Grab current settings
|
|
var settings = camera.volumeStack.GetComponent<AmbientOcclusion>();
|
|
parameters.fullResolution = settings.fullResolution;
|
|
|
|
if (parameters.fullResolution)
|
|
{
|
|
parameters.runningRes = new Vector2(camera.actualWidth, camera.actualHeight);
|
|
cb._AOBufferSize = new Vector4(camera.actualWidth, camera.actualHeight, 1.0f / camera.actualWidth, 1.0f / camera.actualHeight);
|
|
}
|
|
else
|
|
{
|
|
parameters.runningRes = new Vector2(camera.actualWidth, camera.actualHeight) * 0.5f;
|
|
cb._AOBufferSize = new Vector4(camera.actualWidth * 0.5f, camera.actualHeight * 0.5f, 2.0f / camera.actualWidth, 2.0f / camera.actualHeight);
|
|
}
|
|
|
|
float invHalfTanFOV = -camera.mainViewConstants.projMatrix[1, 1];
|
|
float aspectRatio = parameters.runningRes.y / parameters.runningRes.x;
|
|
uint frameCount = camera.GetCameraFrameCount();
|
|
|
|
cb._AOParams0 = new Vector4(
|
|
parameters.fullResolution ? 0.0f : 1.0f,
|
|
parameters.runningRes.y * invHalfTanFOV * 0.25f,
|
|
settings.radius.value,
|
|
settings.stepCount
|
|
);
|
|
|
|
cb._AOParams1 = new Vector4(
|
|
settings.intensity.value,
|
|
1.0f / (settings.radius.value * settings.radius.value),
|
|
(frameCount / 6) % 4,
|
|
(frameCount % 6)
|
|
);
|
|
|
|
|
|
// We start from screen space position, so we bake in this factor the 1 / resolution as well.
|
|
cb._AODepthToViewParams = new Vector4(
|
|
2.0f / (invHalfTanFOV * aspectRatio * parameters.runningRes.x),
|
|
2.0f / (invHalfTanFOV * parameters.runningRes.y),
|
|
1.0f / (invHalfTanFOV * aspectRatio),
|
|
1.0f / invHalfTanFOV
|
|
);
|
|
|
|
float scaleFactor = (parameters.runningRes.x * parameters.runningRes.y) / (540.0f * 960.0f);
|
|
float radInPixels = Mathf.Max(16, settings.maximumRadiusInPixels * Mathf.Sqrt(scaleFactor));
|
|
|
|
cb._AOParams2 = new Vector4(
|
|
historySize.x,
|
|
historySize.y,
|
|
1.0f / (settings.stepCount + 1.0f),
|
|
radInPixels
|
|
);
|
|
|
|
float stepSize = m_RunningFullRes ? 1 : 0.5f;
|
|
|
|
float blurTolerance = 1.0f - settings.blurSharpness.value;
|
|
float maxBlurTolerance = 0.25f;
|
|
float minBlurTolerance = -2.5f;
|
|
blurTolerance = minBlurTolerance + (blurTolerance * (maxBlurTolerance - minBlurTolerance));
|
|
|
|
float bTolerance = 1f - Mathf.Pow(10f, blurTolerance) * stepSize;
|
|
bTolerance *= bTolerance;
|
|
const float upsampleTolerance = -7.0f; // TODO: Expose?
|
|
float uTolerance = Mathf.Pow(10f, upsampleTolerance);
|
|
float noiseFilterWeight = 1f / (Mathf.Pow(10f, 0.0f) + uTolerance);
|
|
|
|
cb._AOParams3 = new Vector4(
|
|
bTolerance,
|
|
uTolerance,
|
|
noiseFilterWeight,
|
|
stepSize
|
|
);
|
|
|
|
float upperNudgeFactor = 1.0f - settings.ghostingReduction.value;
|
|
const float maxUpperNudgeLimit = 5.0f;
|
|
const float minUpperNudgeLimit = 0.25f;
|
|
upperNudgeFactor = minUpperNudgeLimit + (upperNudgeFactor * (maxUpperNudgeLimit - minUpperNudgeLimit));
|
|
cb._AOParams4 = new Vector4(
|
|
settings.directionCount,
|
|
upperNudgeFactor,
|
|
minUpperNudgeLimit,
|
|
settings.spatialBilateralAggressiveness.value * 15.0f
|
|
);
|
|
|
|
cb._FirstTwoDepthMipOffsets = new Vector4(depthMipInfo.mipLevelOffsets[1].x, depthMipInfo.mipLevelOffsets[1].y, depthMipInfo.mipLevelOffsets[2].x, depthMipInfo.mipLevelOffsets[2].y);
|
|
|
|
parameters.bilateralUpsample = settings.bilateralUpsample;
|
|
parameters.gtaoCS = m_Resources.shaders.GTAOCS;
|
|
parameters.gtaoCS.shaderKeywords = null;
|
|
parameters.temporalAccumulation = settings.temporalAccumulation.value && camera.frameSettings.IsEnabled(FrameSettingsField.MotionVectors);
|
|
|
|
if (parameters.temporalAccumulation)
|
|
{
|
|
parameters.gtaoCS.EnableKeyword("TEMPORAL");
|
|
}
|
|
if (parameters.fullResolution)
|
|
{
|
|
parameters.gtaoCS.EnableKeyword("FULL_RES");
|
|
}
|
|
else
|
|
{
|
|
parameters.gtaoCS.EnableKeyword("HALF_RES");
|
|
}
|
|
|
|
parameters.gtaoKernel = parameters.gtaoCS.FindKernel("GTAOMain");
|
|
|
|
parameters.upsampleAndBlurAOCS = m_Resources.shaders.GTAOBlurAndUpsample;
|
|
|
|
parameters.spatialDenoiseAOCS = m_Resources.shaders.GTAOSpatialDenoiseCS;
|
|
parameters.spatialDenoiseAOCS.shaderKeywords = null;
|
|
if (parameters.temporalAccumulation)
|
|
parameters.spatialDenoiseAOCS.EnableKeyword("TO_TEMPORAL");
|
|
parameters.denoiseKernelSpatial = parameters.spatialDenoiseAOCS.FindKernel("SpatialDenoise");
|
|
|
|
parameters.temporalDenoiseAOCS = m_Resources.shaders.GTAOTemporalDenoiseCS;
|
|
parameters.temporalDenoiseAOCS.shaderKeywords = null;
|
|
if (parameters.fullResolution)
|
|
parameters.temporalDenoiseAOCS.EnableKeyword("FULL_RES");
|
|
else
|
|
parameters.temporalDenoiseAOCS.EnableKeyword("HALF_RES");
|
|
|
|
parameters.denoiseKernelTemporal = parameters.temporalDenoiseAOCS.FindKernel("TemporalDenoise");
|
|
|
|
parameters.copyHistoryAOCS = m_Resources.shaders.GTAOCopyHistoryCS;
|
|
parameters.denoiseKernelCopyHistory = parameters.copyHistoryAOCS.FindKernel("GTAODenoise_CopyHistory");
|
|
|
|
parameters.upsampleAndBlurKernel = parameters.upsampleAndBlurAOCS.FindKernel("BlurUpsample");
|
|
parameters.upsampleAOKernel = parameters.upsampleAndBlurAOCS.FindKernel(settings.bilateralUpsample ? "BilateralUpsampling" : "BoxUpsampling");
|
|
|
|
parameters.outputWidth = camera.actualWidth;
|
|
parameters.outputHeight = camera.actualHeight;
|
|
|
|
parameters.viewCount = camera.viewCount;
|
|
parameters.historyReady = m_HistoryReady;
|
|
m_HistoryReady = true; // assumes that if this is called, then render is done as well.
|
|
|
|
parameters.runAsync = camera.frameSettings.SSAORunsAsync();
|
|
|
|
return parameters;
|
|
}
|
|
|
|
static void RenderAO(in RenderAOParameters parameters,
|
|
RTHandle packedDataTexture,
|
|
RTHandle depthTexture,
|
|
RTHandle normalBuffer,
|
|
CommandBuffer cmd)
|
|
{
|
|
ConstantBuffer.Push(cmd, parameters.cb, parameters.gtaoCS, HDShaderIDs._ShaderVariablesAmbientOcclusion);
|
|
cmd.SetComputeTextureParam(parameters.gtaoCS, parameters.gtaoKernel, HDShaderIDs._AOPackedData, packedDataTexture);
|
|
cmd.SetComputeTextureParam(parameters.gtaoCS, parameters.gtaoKernel, HDShaderIDs._NormalBufferTexture, normalBuffer);
|
|
cmd.SetComputeTextureParam(parameters.gtaoCS, parameters.gtaoKernel, HDShaderIDs._CameraDepthTexture, depthTexture);
|
|
|
|
const int groupSizeX = 8;
|
|
const int groupSizeY = 8;
|
|
int threadGroupX = ((int)parameters.runningRes.x + (groupSizeX - 1)) / groupSizeX;
|
|
int threadGroupY = ((int)parameters.runningRes.y + (groupSizeY - 1)) / groupSizeY;
|
|
|
|
cmd.DispatchCompute(parameters.gtaoCS, parameters.gtaoKernel, threadGroupX, threadGroupY, parameters.viewCount);
|
|
}
|
|
|
|
static void DenoiseAO(in RenderAOParameters parameters,
|
|
RTHandle packedDataTex,
|
|
RTHandle packedDataBlurredTex,
|
|
RTHandle packedHistoryTex,
|
|
RTHandle packedHistoryOutputTex,
|
|
RTHandle motionVectors,
|
|
RTHandle aoOutputTex,
|
|
CommandBuffer cmd)
|
|
{
|
|
const int groupSizeX = 8;
|
|
const int groupSizeY = 8;
|
|
int threadGroupX = ((int)parameters.runningRes.x + (groupSizeX - 1)) / groupSizeX;
|
|
int threadGroupY = ((int)parameters.runningRes.y + (groupSizeY - 1)) / groupSizeY;
|
|
|
|
if (parameters.temporalAccumulation || parameters.fullResolution)
|
|
{
|
|
var blurCS = parameters.spatialDenoiseAOCS;
|
|
ConstantBuffer.Set<ShaderVariablesAmbientOcclusion>(cmd, blurCS, HDShaderIDs._ShaderVariablesAmbientOcclusion);
|
|
|
|
// Spatial
|
|
cmd.SetComputeTextureParam(blurCS, parameters.denoiseKernelSpatial, HDShaderIDs._AOPackedData, packedDataTex);
|
|
if (parameters.temporalAccumulation)
|
|
{
|
|
cmd.SetComputeTextureParam(blurCS, parameters.denoiseKernelSpatial, HDShaderIDs._AOPackedBlurred, packedDataBlurredTex);
|
|
}
|
|
else
|
|
{
|
|
cmd.SetComputeTextureParam(blurCS, parameters.denoiseKernelSpatial, HDShaderIDs._OcclusionTexture, aoOutputTex);
|
|
}
|
|
|
|
cmd.DispatchCompute(blurCS, parameters.denoiseKernelSpatial, threadGroupX, threadGroupY, parameters.viewCount);
|
|
}
|
|
|
|
if (parameters.temporalAccumulation)
|
|
{
|
|
if (!parameters.historyReady)
|
|
{
|
|
cmd.SetComputeTextureParam(parameters.copyHistoryAOCS, parameters.denoiseKernelCopyHistory, HDShaderIDs._InputTexture, packedDataTex);
|
|
cmd.SetComputeTextureParam(parameters.copyHistoryAOCS, parameters.denoiseKernelCopyHistory, HDShaderIDs._OutputTexture, packedHistoryTex);
|
|
cmd.DispatchCompute(parameters.copyHistoryAOCS, parameters.denoiseKernelCopyHistory, threadGroupX, threadGroupY, parameters.viewCount);
|
|
}
|
|
|
|
var blurCS = parameters.temporalDenoiseAOCS;
|
|
ConstantBuffer.Set<ShaderVariablesAmbientOcclusion>(cmd, blurCS, HDShaderIDs._ShaderVariablesAmbientOcclusion);
|
|
|
|
// Temporal
|
|
cmd.SetComputeTextureParam(blurCS, parameters.denoiseKernelTemporal, HDShaderIDs._AOPackedData, packedDataTex);
|
|
cmd.SetComputeTextureParam(blurCS, parameters.denoiseKernelTemporal, HDShaderIDs._AOPackedBlurred, packedDataBlurredTex);
|
|
cmd.SetComputeTextureParam(blurCS, parameters.denoiseKernelTemporal, HDShaderIDs._AOPackedHistory, packedHistoryTex);
|
|
cmd.SetComputeTextureParam(blurCS, parameters.denoiseKernelTemporal, HDShaderIDs._AOOutputHistory, packedHistoryOutputTex);
|
|
cmd.SetComputeTextureParam(blurCS, parameters.denoiseKernelTemporal, HDShaderIDs._CameraMotionVectorsTexture, motionVectors);
|
|
cmd.SetComputeTextureParam(blurCS, parameters.denoiseKernelTemporal, HDShaderIDs._OcclusionTexture, aoOutputTex);
|
|
cmd.DispatchCompute(blurCS, parameters.denoiseKernelTemporal, threadGroupX, threadGroupY, parameters.viewCount);
|
|
}
|
|
}
|
|
|
|
static void UpsampleAO(in RenderAOParameters parameters,
|
|
RTHandle depthTexture,
|
|
RTHandle input,
|
|
RTHandle output,
|
|
CommandBuffer cmd)
|
|
{
|
|
bool blurAndUpsample = !parameters.temporalAccumulation;
|
|
|
|
ConstantBuffer.Set<ShaderVariablesAmbientOcclusion>(cmd, parameters.upsampleAndBlurAOCS, HDShaderIDs._ShaderVariablesAmbientOcclusion);
|
|
|
|
if (blurAndUpsample)
|
|
{
|
|
cmd.SetComputeTextureParam(parameters.upsampleAndBlurAOCS, parameters.upsampleAndBlurKernel, HDShaderIDs._AOPackedData, input);
|
|
cmd.SetComputeTextureParam(parameters.upsampleAndBlurAOCS, parameters.upsampleAndBlurKernel, HDShaderIDs._OcclusionTexture, output);
|
|
cmd.SetComputeTextureParam(parameters.upsampleAndBlurAOCS, parameters.upsampleAndBlurKernel, HDShaderIDs._CameraDepthTexture, depthTexture);
|
|
|
|
const int groupSizeX = 8;
|
|
const int groupSizeY = 8;
|
|
int threadGroupX = ((int)(parameters.runningRes.x) + (groupSizeX - 1)) / groupSizeX;
|
|
int threadGroupY = ((int)(parameters.runningRes.y) + (groupSizeY - 1)) / groupSizeY;
|
|
cmd.DispatchCompute(parameters.upsampleAndBlurAOCS, parameters.upsampleAndBlurKernel, threadGroupX, threadGroupY, parameters.viewCount);
|
|
}
|
|
else
|
|
{
|
|
cmd.SetComputeTextureParam(parameters.upsampleAndBlurAOCS, parameters.upsampleAOKernel, HDShaderIDs._AOPackedData, input);
|
|
cmd.SetComputeTextureParam(parameters.upsampleAndBlurAOCS, parameters.upsampleAOKernel, HDShaderIDs._OcclusionTexture, output);
|
|
cmd.SetComputeTextureParam(parameters.upsampleAndBlurAOCS, parameters.upsampleAOKernel, HDShaderIDs._CameraDepthTexture, depthTexture);
|
|
|
|
const int groupSizeX = 8;
|
|
const int groupSizeY = 8;
|
|
int threadGroupX = ((int)parameters.runningRes.x + (groupSizeX - 1)) / groupSizeX;
|
|
int threadGroupY = ((int)parameters.runningRes.y + (groupSizeY - 1)) / groupSizeY;
|
|
cmd.DispatchCompute(parameters.upsampleAndBlurAOCS, parameters.upsampleAOKernel, threadGroupX, threadGroupY, parameters.viewCount);
|
|
}
|
|
}
|
|
|
|
internal void UpdateShaderVariableGlobalCB(ref ShaderVariablesGlobal cb, HDCamera hdCamera)
|
|
{
|
|
var settings = hdCamera.volumeStack.GetComponent<AmbientOcclusion>();
|
|
bool aoEnabled = false;
|
|
if (IsActive(hdCamera, settings))
|
|
{
|
|
aoEnabled = true;
|
|
// If raytraced AO is enabled but raytracing state is wrong then we disable it.
|
|
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && settings.rayTracing.value && !HDRenderPipeline.currentPipeline.GetRayTracingState())
|
|
{
|
|
aoEnabled = false;
|
|
}
|
|
}
|
|
|
|
if (aoEnabled)
|
|
cb._AmbientOcclusionParam = new Vector4(0f, 0f, 0f, settings.directLightingStrength.value);
|
|
else
|
|
cb._AmbientOcclusionParam = Vector4.zero;
|
|
}
|
|
}
|
|
}
|