105 lines
4.9 KiB
HLSL
105 lines
4.9 KiB
HLSL
#ifndef RGI_PROBING
|
|
#define RGI_PROBING
|
|
|
|
// Copyright 2022-2026 Kronnect - All Rights Reserved.
|
|
|
|
// APV/Sky ambient sampling
|
|
// Used by both Raycast (fallback) and Compose (subtraction)
|
|
#define USES_APV (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
|
|
|
|
#if USES_APV
|
|
#include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl"
|
|
#endif
|
|
|
|
#if UNITY_VERSION >= 600000
|
|
#ifndef AMBIENT_PROBE_BUFFER
|
|
#define AMBIENT_PROBE_BUFFER 0
|
|
#endif
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/AmbientProbe.hlsl"
|
|
#endif
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
|
|
|
half3 SampleAmbientLighting(float3 posWS, half3 rayDirWS, float2 positionSS) {
|
|
#if USES_APV
|
|
half3 viewDirWS = normalize(posWS - _WorldSpaceCameraPos);
|
|
half4 probeOcclusion;
|
|
half3 bakeDiffuseLighting;
|
|
EvaluateAdaptiveProbeVolume(posWS, rayDirWS, viewDirWS, positionSS, 0xFFFFFFFF, bakeDiffuseLighting, probeOcclusion);
|
|
return bakeDiffuseLighting * probeOcclusion.rgb;
|
|
#else
|
|
half3 ambient = SampleSH(rayDirWS);
|
|
// Apply time-of-day intensity when using realtime ambient probe
|
|
half hasMainLight = dot(_MainLightColor.rgb, half3(1.0h, 1.0h, 1.0h));
|
|
if (hasMainLight > 0.0h)
|
|
{
|
|
half mainLightY = _MainLightPosition.y;
|
|
half timeOfDayIntensity = saturate(mainLightY * 1.5 + 0.2);
|
|
ambient *= lerp(1, timeOfDayIntensity, REALTIME_AMBIENT_PROBE);
|
|
}
|
|
return ambient;
|
|
#endif
|
|
}
|
|
|
|
// Traditional reflection probe sampling with box projection support
|
|
half3 SampleProbe(TEXTURECUBE(_ProbeCube), SAMPLER(_SamplerCube), half4 probeHDRData, half3 rayDirWS, float3 positionWS, float4 probePosition, float4 boxMin, float4 boxMax) {
|
|
half3 sampleVector = rayDirWS;
|
|
#if _REFLECTION_PROBE_BOX_PROJECTION
|
|
if (probePosition.w > 0.0) {
|
|
sampleVector = BoxProjectedCubemapDirection(rayDirWS, positionWS, probePosition, boxMin, boxMax);
|
|
}
|
|
#endif
|
|
|
|
half4 probeSample = SAMPLE_TEXTURECUBE_LOD(_ProbeCube, _SamplerCube, sampleVector, 0);
|
|
probeSample.rgb = DecodeHDREnvironment(probeSample, probeHDRData);
|
|
return probeSample.rgb;
|
|
}
|
|
|
|
#if _FALLBACK_PROBE_ATLAS && USE_CLUSTER_LIGHT_LOOP
|
|
// Samples reflection probes from atlas using cluster-based iteration (Forward+/Deferred+)
|
|
// Adapted from CalculateIrradianceFromReflectionProbes from UniversalRP/ShaderLibrary/GlobalIllumination.hlsl
|
|
// Returns both irradiance and weight for blending with APV/Sky ambient
|
|
half3 SampleReflectionProbesWithWeight(half3 reflectVector, float3 positionWS, float2 normalizedScreenSpaceUV, out half outWeight)
|
|
{
|
|
half3 irradiance = half3(0.0h, 0.0h, 0.0h);
|
|
half mip = 0.5; //PerceptualRoughnessToMipmapLevel(perceptualRoughness);
|
|
float totalWeight = 0.0f;
|
|
|
|
uint probeIndex;
|
|
ClusterIterator it = ClusterInit(normalizedScreenSpaceUV, positionWS, 1);
|
|
[loop] while (ClusterNext(it, probeIndex) && totalWeight < 0.99f)
|
|
{
|
|
probeIndex -= URP_FP_PROBES_BEGIN;
|
|
float weight = CalculateProbeWeight(positionWS, urp_ReflProbes_BoxMin[probeIndex], urp_ReflProbes_BoxMax[probeIndex]);
|
|
weight = min(weight, 1.0f - totalWeight);
|
|
|
|
half3 sampleVector = reflectVector;
|
|
if (_REFLECTION_PROBE_BOX_PROJECTION)
|
|
{
|
|
sampleVector = BoxProjectedCubemapDirection(reflectVector, positionWS, urp_ReflProbes_ProbePosition[probeIndex], urp_ReflProbes_BoxMin[probeIndex], urp_ReflProbes_BoxMax[probeIndex]);
|
|
}
|
|
|
|
uint maxMip = (uint)abs(urp_ReflProbes_ProbePosition[probeIndex].w) - 1;
|
|
half probeMip = min(mip, maxMip);
|
|
float2 uv = saturate(PackNormalOctQuadEncode(sampleVector) * 0.5 + 0.5);
|
|
|
|
float mip0 = floor(probeMip);
|
|
float mip1 = mip0 + 1;
|
|
float mipBlend = probeMip - mip0;
|
|
float4 scaleOffset0 = urp_ReflProbes_MipScaleOffset[probeIndex * 7 + (uint)mip0];
|
|
float4 scaleOffset1 = urp_ReflProbes_MipScaleOffset[probeIndex * 7 + (uint)mip1];
|
|
|
|
half3 irradiance0 = SAMPLE_TEXTURE2D_LOD(urp_ReflProbes_Atlas, sampler_LinearClamp, uv * scaleOffset0.xy + scaleOffset0.zw, 0.0).rgb;
|
|
half3 irradiance1 = SAMPLE_TEXTURE2D_LOD(urp_ReflProbes_Atlas, sampler_LinearClamp, uv * scaleOffset1.xy + scaleOffset1.zw, 0.0).rgb;
|
|
irradiance += weight * lerp(irradiance0, irradiance1, mipBlend);
|
|
totalWeight += weight;
|
|
}
|
|
|
|
outWeight = saturate(totalWeight);
|
|
return irradiance;
|
|
}
|
|
#endif // _FALLBACK_PROBE_ATLAS
|
|
|
|
#endif // RGI_PROBING
|
|
|
|
|