Rasagar/Library/PackageCache/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/ExposureCommon.hlsl
2024-08-26 23:07:20 +03:00

135 lines
4.7 KiB
HLSL

#ifndef EXPOSURE_COMMON_INCLUDED
#define EXPOSURE_COMMON_INCLUDED
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/PhysicalCamera.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
TEXTURE2D(_ExposureWeightMask);
TEXTURE2D_X(_SourceTexture);
TEXTURE2D(_PreviousExposureTexture);
RW_TEXTURE2D(float2, _OutputTexture);
TEXTURE2D(_ExposureCurveTexture);
CBUFFER_START(cb)
float4 _ExposureParams;
float4 _ExposureParams2;
float4 _ProceduralMaskParams;
float4 _ProceduralMaskParams2;
float4 _HistogramExposureParams;
float4 _AdaptationParams;
uint4 _Variants;
CBUFFER_END
#define ParamEV100 _ExposureParams.y
#define ParamExposureCompensation _ExposureParams.x
#define ParamAperture _ExposureParams.y
#define ParamShutterSpeed _ExposureParams.z
#define ParamISO _ExposureParams.w
#define ParamSpeedLightToDark _AdaptationParams.x
#define ParamSpeedDarkToLight _AdaptationParams.y
#define ParamExposureLimitMin _ExposureParams.y
#define ParamExposureLimitMax _ExposureParams.z
#define ParamCurveMin _ExposureParams2.x
#define ParamCurveMax _ExposureParams2.y
#define LensImperfectionExposureScale _ExposureParams2.z
#define MeterCalibrationConstant _ExposureParams2.w
#define ParamSourceBuffer _Variants.x
#define ParamMeteringMode _Variants.y
#define ParamAdaptationMode _Variants.z
#define ParamEvaluateMode _Variants.w
#define ProceduralCenter _ProceduralMaskParams.xy // Transformed in screen space on CPU
#define ProceduralRadii _ProceduralMaskParams.zw
#define ProceduralSoftness _ProceduralMaskParams2.x
#define ProceduralMin _ProceduralMaskParams2.y
#define ProceduralMax _ProceduralMaskParams2.z
float GetPreviousExposureEV100()
{
return _PreviousExposureTexture[uint2(0u, 0u)].y;
}
float WeightSample(uint2 pixel, float2 sourceSize, float luminance)
{
UNITY_BRANCH
switch (ParamMeteringMode)
{
case 1u:
{
// Spot metering
float screenDiagonal = 0.5f * (sourceSize.x + sourceSize.y);
const float kRadius = 0.075 * screenDiagonal;
const float2 kCenter = sourceSize * 0.5f;
float d = length(kCenter - pixel) - kRadius;
return 1.0 - saturate(d);
}
case 2u:
{
// Center-weighted
float screenDiagonal = 0.5f * (sourceSize.x + sourceSize.y);
const float2 kCenter = sourceSize * 0.5f;
return 1.0 - saturate(pow(length(kCenter - pixel) / screenDiagonal, 1.0));
}
case 3u:
{
// Mask weigthing
return SAMPLE_TEXTURE2D_LOD(_ExposureWeightMask, s_linear_clamp_sampler, pixel * rcp(sourceSize), 0.0).x;
}
case 4u:
{
// Procedural.
float radius = max(ProceduralRadii.x, ProceduralRadii.y);
float2 ellipseScale = float2(radius / ProceduralRadii.x, radius / ProceduralRadii.y);
float dist = length(ProceduralCenter * ellipseScale - pixel * ellipseScale);
return (luminance > ProceduralMin && luminance < ProceduralMax) ? saturate(1.0 - PositivePow((dist / radius), ProceduralSoftness)) : 0.0f;
}
default:
{
// Global average
return 1.0;
}
}
}
float SampleLuminance(float2 uv)
{
if (ParamSourceBuffer == 1)
{
// Color buffer
float prevExposure = ConvertEV100ToExposure(GetPreviousExposureEV100(), LensImperfectionExposureScale);
float3 color = SAMPLE_TEXTURE2D_X_LOD(_SourceTexture, s_linear_clamp_sampler, uv, 0.0).xyz;
return Luminance(color / prevExposure);
}
else
{
return 1.0f;
}
}
float AdaptExposure(float exposure)
{
if (ParamAdaptationMode == 1)
{
return ComputeLuminanceAdaptation(GetPreviousExposureEV100(), exposure, ParamSpeedDarkToLight, ParamSpeedLightToDark, unity_DeltaTime.x);
}
else
{
return exposure;
}
}
float CurveRemap(float inEV, out float limitMin, out float limitMax)
{
float remap = saturate((inEV - ParamCurveMin) / (ParamCurveMax - ParamCurveMin));
float3 curveSample = SAMPLE_TEXTURE2D_LOD(_ExposureCurveTexture, s_linear_clamp_sampler, float2(remap, 0.0), 0.0).xyz;
limitMin = curveSample.y;
limitMax = curveSample.z;
return curveSample.x;
}
#endif