using System;
using UnityEngine.Rendering;
namespace UnityEngine.Rendering
{
public partial class ProbeReferenceVolume
{
internal static class ShaderIDs
{
// Adaptive Probe Volume
public static readonly int _APVResIndex = Shader.PropertyToID("_APVResIndex");
public static readonly int _APVResCellIndices = Shader.PropertyToID("_APVResCellIndices");
public static readonly int _APVResL0_L1Rx = Shader.PropertyToID("_APVResL0_L1Rx");
public static readonly int _APVResL1G_L1Ry = Shader.PropertyToID("_APVResL1G_L1Ry");
public static readonly int _APVResL1B_L1Rz = Shader.PropertyToID("_APVResL1B_L1Rz");
public static readonly int _APVResL2_0 = Shader.PropertyToID("_APVResL2_0");
public static readonly int _APVResL2_1 = Shader.PropertyToID("_APVResL2_1");
public static readonly int _APVResL2_2 = Shader.PropertyToID("_APVResL2_2");
public static readonly int _APVResL2_3 = Shader.PropertyToID("_APVResL2_3");
public static readonly int _APVProbeOcclusion = Shader.PropertyToID("_APVProbeOcclusion");
public static readonly int _APVResValidity = Shader.PropertyToID("_APVResValidity");
public static readonly int _SkyOcclusionTexL0L1 = Shader.PropertyToID("_SkyOcclusionTexL0L1");
public static readonly int _SkyShadingDirectionIndicesTex = Shader.PropertyToID("_SkyShadingDirectionIndicesTex");
public static readonly int _SkyPrecomputedDirections = Shader.PropertyToID("_SkyPrecomputedDirections");
public static readonly int _AntiLeakData = Shader.PropertyToID("_AntiLeakData");
}
ComputeBuffer m_EmptyIndexBuffer = null;
///
/// Bind the global APV resources
///
/// Command buffer
/// True if APV is enabled
public void BindAPVRuntimeResources(CommandBuffer cmdBuffer, bool isProbeVolumeEnabled)
{
bool needToBindNeutral = true;
var refVolume = ProbeReferenceVolume.instance;
// Do this only if probe volume is enabled
if (isProbeVolumeEnabled && m_ProbeReferenceVolumeInit)
{
ProbeReferenceVolume.RuntimeResources rr = refVolume.GetRuntimeResources();
bool validResources = rr.index != null && rr.L0_L1rx != null && rr.L1_G_ry != null && rr.L1_B_rz != null;
validResources &= (refVolume.shBands == ProbeVolumeSHBands.SphericalHarmonicsL2 && rr.L2_0 != null) || refVolume.shBands == ProbeVolumeSHBands.SphericalHarmonicsL1;
if (validResources)
{
cmdBuffer.SetGlobalBuffer(ShaderIDs._APVResIndex, rr.index);
cmdBuffer.SetGlobalBuffer(ShaderIDs._APVResCellIndices, rr.cellIndices);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL0_L1Rx, rr.L0_L1rx);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL1G_L1Ry, rr.L1_G_ry);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL1B_L1Rz, rr.L1_B_rz);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResValidity, rr.Validity);
cmdBuffer.SetGlobalTexture(ShaderIDs._SkyOcclusionTexL0L1, rr.SkyOcclusionL0L1 ?? (RenderTargetIdentifier)CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalTexture(ShaderIDs._SkyShadingDirectionIndicesTex, rr.SkyShadingDirectionIndices ?? (RenderTargetIdentifier)CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalBuffer(ShaderIDs._SkyPrecomputedDirections, rr.SkyPrecomputedDirections);
cmdBuffer.SetGlobalBuffer(ShaderIDs._AntiLeakData, rr.QualityLeakReductionData);
if (refVolume.shBands == ProbeVolumeSHBands.SphericalHarmonicsL2)
{
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL2_0, rr.L2_0);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL2_1, rr.L2_1);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL2_2, rr.L2_2);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL2_3, rr.L2_3);
}
cmdBuffer.SetGlobalTexture(ShaderIDs._APVProbeOcclusion, rr.ProbeOcclusion ?? (RenderTargetIdentifier)CoreUtils.whiteVolumeTexture);
needToBindNeutral = false;
}
}
if (needToBindNeutral)
{
// Lazy init the empty buffer. We use sizeof(uint3) so that this buffer can be
// used with uint and uint3 bindings without triggering validation errors.
if (m_EmptyIndexBuffer == null)
m_EmptyIndexBuffer = new ComputeBuffer(1, sizeof(uint) * 3, ComputeBufferType.Structured);
cmdBuffer.SetGlobalBuffer(ShaderIDs._APVResIndex, m_EmptyIndexBuffer);
cmdBuffer.SetGlobalBuffer(ShaderIDs._APVResCellIndices, m_EmptyIndexBuffer);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL0_L1Rx, CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL1G_L1Ry, CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL1B_L1Rz, CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResValidity, CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalTexture(ShaderIDs._SkyOcclusionTexL0L1, CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalTexture(ShaderIDs._SkyShadingDirectionIndicesTex, CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalBuffer(ShaderIDs._SkyPrecomputedDirections, m_EmptyIndexBuffer);
cmdBuffer.SetGlobalBuffer(ShaderIDs._AntiLeakData, m_EmptyIndexBuffer);
if (refVolume.shBands == ProbeVolumeSHBands.SphericalHarmonicsL2)
{
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL2_0, CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL2_1, CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL2_2, CoreUtils.blackVolumeTexture);
cmdBuffer.SetGlobalTexture(ShaderIDs._APVResL2_3, CoreUtils.blackVolumeTexture);
}
cmdBuffer.SetGlobalTexture(ShaderIDs._APVProbeOcclusion, CoreUtils.whiteVolumeTexture);
}
}
///
/// Update the constant buffer used by Probe Volumes in shaders.
///
/// A command buffer used to perform the data update.
/// probe volume options from the active volume stack
/// TAA frame index
/// Are rendering layers supported
/// True if successful
public bool UpdateShaderVariablesProbeVolumes(CommandBuffer cmd, ProbeVolumesOptions probeVolumeOptions, int taaFrameIndex, bool supportRenderingLayers = false)
{
bool enableProbeVolumes = DataHasBeenLoaded();
if (enableProbeVolumes)
{
ProbeVolumeShadingParameters parameters;
parameters.normalBias = probeVolumeOptions.normalBias.value;
parameters.viewBias = probeVolumeOptions.viewBias.value;
parameters.scaleBiasByMinDistanceBetweenProbes = probeVolumeOptions.scaleBiasWithMinProbeDistance.value;
parameters.samplingNoise = probeVolumeOptions.samplingNoise.value;
parameters.weight = probeVolumeOptions.intensityMultiplier.value;
parameters.leakReductionMode = probeVolumeOptions.leakReductionMode.value;
parameters.frameIndexForNoise = taaFrameIndex * (probeVolumeOptions.animateSamplingNoise.value ? 1 : 0);
parameters.reflNormalizationLowerClamp = 0.005f;
parameters.reflNormalizationUpperClamp = probeVolumeOptions.occlusionOnlyReflectionNormalization.value ? 1.0f : 7.0f;
parameters.skyOcclusionIntensity = skyOcclusion ? probeVolumeOptions.skyOcclusionIntensityMultiplier.value : 0.0f;
parameters.skyOcclusionShadingDirection = skyOcclusion && skyOcclusionShadingDirection;
parameters.regionCount = m_CurrentBakingSet.bakedMaskCount;
parameters.regionLayerMasks = supportRenderingLayers ? m_CurrentBakingSet.bakedLayerMasks : 0xFFFFFFFF;
parameters.worldOffset = probeVolumeOptions.worldOffset.value;
UpdateConstantBuffer(cmd, parameters);
}
return enableProbeVolumes;
}
}
}