You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

438 lines
16 KiB

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Random.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ScreenCoordOverride.hlsl"
TEXTURE2D(_LensFlareScreenSpaceSpectralLut);
TEXTURE2D_X(_LensFlareScreenSpaceStreakTex);
TEXTURE2D_X(_LensFlareScreenSpaceBloomMipTexture);
TEXTURE2D_X(_LensFlareScreenSpaceResultTexture);
float4 _LensFlareScreenSpaceBloomMipTexture_TexelSize;
float4 _LensFlareScreenSpaceStreakTex_TexelSize;
float4 _LensFlareScreenSpaceParams1;
float4 _LensFlareScreenSpaceParams2;
float4 _LensFlareScreenSpaceParams3;
float4 _LensFlareScreenSpaceParams4;
float4 _LensFlareScreenSpaceParams5;
int _LensFlareScreenSpaceMipLevel;
float3 _LensFlareScreenSpaceTintColor;
#define LensFlareScreenSpaceIntensity _LensFlareScreenSpaceParams1.x
#define LensFlareScreenSpaceFirstIntensity _LensFlareScreenSpaceParams1.y
#define LensFlareScreenSpaceSecondaryIntensity _LensFlareScreenSpaceParams1.z
#define LensFlareScreenSpacePolarIntensity _LensFlareScreenSpaceParams1.w
#define LensFlareScreenSpaceVignetteIntensity _LensFlareScreenSpaceParams2.x
#define LensFlareScreenSpaceStartingPosition _LensFlareScreenSpaceParams2.y
#define LensFlareScreenSpaceScale _LensFlareScreenSpaceParams2.z
#define LensFlareScreenSpaceCount _LensFlareScreenSpaceParams3.x
#define LensFlareScreenSpaceCountDimmer _LensFlareScreenSpaceParams3.y
#define LensFlareScreenSpaceChromaIntensity _LensFlareScreenSpaceParams3.z
#define LensFlareScreenSpaceChromaSample _LensFlareScreenSpaceParams3.w
#define LensFlareScreenSpaceStreakIntensity _LensFlareScreenSpaceParams4.x
#define LensFlareScreenSpaceStreakLength _LensFlareScreenSpaceParams4.y
#define LensFlareScreenSpaceStreakOrientation _LensFlareScreenSpaceParams4.z
#define LensFlareScreenSpaceStreakThreshold _LensFlareScreenSpaceParams4.w
#define LensFlareScreenSpaceRatio _LensFlareScreenSpaceParams5.x
#define LensFlareScreenSpaceWarpedScaleX _LensFlareScreenSpaceParams5.y
#define LensFlareScreenSpaceWarpedScaleY _LensFlareScreenSpaceParams5.z
#define REGULAR_FLARE_MULTIPLIER 0.1
#define STREAK_FLARE_MULTIPLIER 1
struct AttributesSSLF
{
uint vertexID : SV_VertexID;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VaryingsSSLF
{
float4 positionCS : SV_POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
float2 GetAnamorphism()
{
float f = frac(LensFlareScreenSpaceStreakOrientation);
bool even = ((floor(LensFlareScreenSpaceStreakOrientation) % 2) == 0);
float x = even ? -(1.0 - f) : -(1.0 - (1.0 - f));
float y = even ? f : -(1.0 - f);
return float2(x, y);
}
float map01To(float value, float min, float max)
{
return (max - min) * (value - 0.5);
}
float map01(float value, float min, float max)
{
float r = rcp(max - min);
return Remap01(value, r, min * r);
}
float2 scaleUV(float2 uv, float2 center, float scale, bool invert, bool polar)
{
if (polar)
{
scale = rcp(scale);
// Correctly map the UV before doing polar conversion
uv = float2(LensFlareScreenSpaceWarpedScaleX * map01To(uv.x, -scale, scale), LensFlareScreenSpaceWarpedScaleY * map01To(uv.y, -scale, scale));
// Polar coordinate conversion
float x = SafeSqrt(SafePositivePow(uv.x, 2) + SafePositivePow(uv.y, 2));
float x1 = map01(x, 0.0, sqrt(2.0));
float y = FastAtan2(uv.x, uv.y);
float y1 = 1.0 - map01(y, -PI, PI);
uv = float2(y1, invert ? (1.0 - x1) : x1);
}
else
{
// First, we substract the center before scaling
uv -= center;
uv *= 1.0 / scale;
// Then, we add center back
uv += center;
if (invert)
{
uv = 1.0 - uv;
}
}
return uv;
}
float3 GetFlareTexture(float2 uv, float scale, float intensity, bool polar, bool regularFlarePass)
{
bool invert = scale < 0.0;
bool distortUV = (scale != 1 || polar);
float signScale = sign(scale);
bool chromaticAberration = (LensFlareScreenSpaceChromaIntensity > 0);
//Chromatic
float2 coords = 2.0 * uv - 1.0;
float2 end = uv - coords * dot(coords, coords) * LensFlareScreenSpaceChromaIntensity;
float2 diff = end - uv;
if (distortUV)
uv = scaleUV(uv, float2(0.5, 0.5), abs(scale), invert, polar);
#if defined (HDRP_LENS_FLARE_SCREEN_SPACE)
// HDRP Implementation taken from UberPost shader
int samples = 1;
if (chromaticAberration)
{
samples = int(length(_PostProcessScreenSize.xy * diff / 2.0));
samples = clamp(samples, 3, (int)LensFlareScreenSpaceChromaSample);
}
float2 delta = diff / samples;
float3 sum = 0.0;
float3 filterSum = 0.0;
float3 filter = 0.0;
for (int i = 0; i < samples; i++)
{
float3 s = 0.0;
// Depending on if we are computing regular flares or streaks, we sample a different texture.
if (regularFlarePass)
{
s = SAMPLE_TEXTURE2D_X_LOD(_LensFlareScreenSpaceBloomMipTexture, s_linear_clamp_sampler, ClampAndScaleUVForBilinearPostProcessTexture(SCREEN_COORD_REMOVE_SCALEBIAS(uv)), 0.0).xyz;
}
else
{
s = SAMPLE_TEXTURE2D_X_LOD(_LensFlareScreenSpaceStreakTex, s_linear_clamp_sampler, ClampAndScaleUVForBilinearPostProcessTexture(SCREEN_COORD_REMOVE_SCALEBIAS(uv)), 0.0).xyz;
}
s *= _LensFlareScreenSpaceTintColor;
UNITY_BRANCH
if (chromaticAberration)
{
float t = (i + 0.5) / samples;
filter = SAMPLE_TEXTURE2D_LOD(_LensFlareScreenSpaceSpectralLut, s_linear_clamp_sampler, saturate(float2(t, 0.0)), 0.0).xyz;
}
else
{
filter = 1.0;
}
sum += s * filter;
filterSum += filter;
uv += signScale * delta;
}
float3 result = sum / filterSum;
#endif
#if defined (URP_LENS_FLARE_SCREEN_SPACE)
// Taken from URP UberPost Implementation
float3 result = 0.0;
// If chromaticAberration Intenisty is zero, we do only one sample.
if (chromaticAberration)
{
diff = diff / 3.0;
float r, g, b;
if (regularFlarePass)
{
r = SAMPLE_TEXTURE2D_X(_LensFlareScreenSpaceBloomMipTexture, sampler_LinearClamp, ClampAndScaleUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS(uv), _LensFlareScreenSpaceBloomMipTexture_TexelSize.xy) ).x;
g = SAMPLE_TEXTURE2D_X(_LensFlareScreenSpaceBloomMipTexture, sampler_LinearClamp, ClampAndScaleUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS((diff + uv)), _LensFlareScreenSpaceBloomMipTexture_TexelSize.xy) ).y;
b = SAMPLE_TEXTURE2D_X(_LensFlareScreenSpaceBloomMipTexture, sampler_LinearClamp, ClampAndScaleUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS((diff * 2.0 + uv)), _LensFlareScreenSpaceBloomMipTexture_TexelSize.xy)).z;
}
else
{
r = SAMPLE_TEXTURE2D_X(_LensFlareScreenSpaceStreakTex, sampler_LinearClamp, ClampAndScaleUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS(uv)) ).x;
g = SAMPLE_TEXTURE2D_X(_LensFlareScreenSpaceStreakTex, sampler_LinearClamp, ClampAndScaleUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS((diff + uv)) )).y;
b = SAMPLE_TEXTURE2D_X(_LensFlareScreenSpaceStreakTex, sampler_LinearClamp, ClampAndScaleUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS((diff * 2.0 + uv)))).z;
}
result = float3(r, g, b);
}
else
{
if (regularFlarePass)
{
result = SAMPLE_TEXTURE2D_X(_LensFlareScreenSpaceBloomMipTexture, sampler_LinearClamp, ClampAndScaleUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS(uv))).xyz;
}
else
{
result = SAMPLE_TEXTURE2D_X(_LensFlareScreenSpaceStreakTex, sampler_LinearClamp, ClampAndScaleUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS(uv))).xyz;
}
}
result *= _LensFlareScreenSpaceTintColor;
#endif
return result * intensity;
}
VaryingsSSLF vert(AttributesSSLF input)
{
VaryingsSSLF output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
float4 positionCS = float4(2.0, 2.0, 1.0, 1.0) * GetQuadVertexPosition(input.vertexID) - float4(1.0, 1.0, 0.0, 0.0);
float2 uv = GetQuadTexCoord(input.vertexID);
uv.y = 1.0 - uv.y;
output.positionCS = positionCS;
output.texcoord = uv;
return output;
}
// Prefilter: Shrink horizontally and apply threshold.
float4 FragmentPrefilter(VaryingsSSLF input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord;
#if defined (HDRP_LENS_FLARE_SCREEN_SPACE)
uv /= _RTHandlePostProcessScale.xy;
#endif
float dy = GetAnamorphism().x * _LensFlareScreenSpaceBloomMipTexture_TexelSize.y;
float dx = GetAnamorphism().y * _LensFlareScreenSpaceBloomMipTexture_TexelSize.x;
float2 u0 = saturate(float2(uv.x - dx, uv.y - dy));
float2 u1 = saturate(float2(uv.x + dx, uv.y + dy));
#if defined (HDRP_LENS_FLARE_SCREEN_SPACE)
float3 c0 = SAMPLE_TEXTURE2D_X_LOD(_LensFlareScreenSpaceBloomMipTexture, s_linear_clamp_sampler, ClampAndScaleUVForBilinearPostProcessTexture(SCREEN_COORD_REMOVE_SCALEBIAS(u0)), 0.0).xyz;
float3 c1 = SAMPLE_TEXTURE2D_X_LOD(_LensFlareScreenSpaceBloomMipTexture, s_linear_clamp_sampler, ClampAndScaleUVForBilinearPostProcessTexture(SCREEN_COORD_REMOVE_SCALEBIAS(u1)), 0.0).xyz;
#endif
#if defined (URP_LENS_FLARE_SCREEN_SPACE)
float3 c0 = SAMPLE_TEXTURE2D_X(_LensFlareScreenSpaceBloomMipTexture, sampler_LinearClamp, ClampUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS(u0), _LensFlareScreenSpaceBloomMipTexture_TexelSize.xy)).xyz;
float3 c1 = SAMPLE_TEXTURE2D_X(_LensFlareScreenSpaceBloomMipTexture, sampler_LinearClamp, ClampUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS(u1), _LensFlareScreenSpaceBloomMipTexture_TexelSize.xy)).xyz;
#endif
float3 c = (c0 + c1) / 2.0;
float br = max(c.r, max(c.g, c.b));
c *= max(br - LensFlareScreenSpaceStreakThreshold, 0.0) / max(br, 1e-4);
return float4(c, 1.0);
}
#if defined (HDRP_LENS_FLARE_SCREEN_SPACE)
float3 SampleScaled(TEXTURE2D_X(tex), float2 uv)
{
return SAMPLE_TEXTURE2D_X(tex, s_linear_clamp_sampler, ClampAndScaleUVForBilinearPostProcessTexture(SCREEN_COORD_REMOVE_SCALEBIAS(uv))).xyz;
}
#endif
#if defined (URP_LENS_FLARE_SCREEN_SPACE)
float3 SampleScaled(TEXTURE2D_X(tex), float2 uv)
{
return SAMPLE_TEXTURE2D_X(tex, sampler_LinearClamp, ClampUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS(uv))).xyz;
}
#endif
//Downsampler Pass
float4 FragmentDownsample(VaryingsSSLF input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord.xy;
#if defined (HDRP_LENS_FLARE_SCREEN_SPACE)
uv /= _RTHandlePostProcessScale.xy;
#endif
float dy = GetAnamorphism().y * _LensFlareScreenSpaceStreakTex_TexelSize.y * LensFlareScreenSpaceStreakLength * ((float)_LensFlareScreenSpaceMipLevel + 1.0) / LensFlareScreenSpaceRatio;
float dx = GetAnamorphism().x * _LensFlareScreenSpaceStreakTex_TexelSize.x * LensFlareScreenSpaceStreakLength * ((float)_LensFlareScreenSpaceMipLevel + 1.0) / LensFlareScreenSpaceRatio;
float2 u0 = saturate(float2(uv.x - dx * 5.0, uv.y - dy * 5.0));
float2 u1 = saturate(float2(uv.x - dx * 3.0, uv.y - dy * 3.0));
float2 u2 = saturate(float2(uv.x - dx * 1.0, uv.y - dy * 1.0));
float2 u3 = saturate(float2(uv.x + dx * 1.0, uv.y + dy * 1.0));
float2 u4 = saturate(float2(uv.x + dx * 3.0, uv.y + dy * 3.0));
float2 u5 = saturate(float2(uv.x + dx * 5.0, uv.y + dy * 5.0));
float3 c0 = 1.0 * SampleScaled(_LensFlareScreenSpaceStreakTex, u0) / 12.0;
float3 c1 = 2.0 * SampleScaled(_LensFlareScreenSpaceStreakTex, u1) / 12.0;
float3 c2 = 3.0 * SampleScaled(_LensFlareScreenSpaceStreakTex, u2) / 12.0;
float3 c3 = 3.0 * SampleScaled(_LensFlareScreenSpaceStreakTex, u3) / 12.0;
float3 c4 = 2.0 * SampleScaled(_LensFlareScreenSpaceStreakTex, u4) / 12.0;
float3 c5 = 1.0 * SampleScaled(_LensFlareScreenSpaceStreakTex, u5) / 12.0;
return float4((c0 + c1 + c2 + c3 + c4 + c5), 1.0);
}
//Upsampler Pass
float4 FragmentUpsample(VaryingsSSLF input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord;
#if defined (HDRP_LENS_FLARE_SCREEN_SPACE)
uv /= _RTHandlePostProcessScale.xy;
#endif
float dy = GetAnamorphism().y * _LensFlareScreenSpaceStreakTex_TexelSize.y * LensFlareScreenSpaceStreakLength * 1.5 * ((float)_LensFlareScreenSpaceMipLevel + 1.0) / LensFlareScreenSpaceRatio;
float dx = GetAnamorphism().x * _LensFlareScreenSpaceStreakTex_TexelSize.x * LensFlareScreenSpaceStreakLength * 1.5 * ((float)_LensFlareScreenSpaceMipLevel + 1.0) / LensFlareScreenSpaceRatio;
float2 u0 = saturate(float2(uv.x - dx, uv.y - dy));
float2 u1 = saturate(float2(uv.x, uv.y));
float2 u2 = saturate(float2(uv.x + dx, uv.y + dy));
float3 c0 = 1.0 * SampleScaled(_LensFlareScreenSpaceStreakTex, u0) / 4.0;
float3 c1 = 2.0 * SampleScaled(_LensFlareScreenSpaceStreakTex, u1) / 4.0;
float3 c2 = 1.0 * SampleScaled(_LensFlareScreenSpaceStreakTex, u2) / 4.0;
return float4(c0 + c1 + c2, 1.0);
}
// Final composition
float4 FragmentComposition(VaryingsSSLF input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord;
float3 streakFlare = 0.0;
float3 regularFlare = 0.0;
#if defined (HDRP_LENS_FLARE_SCREEN_SPACE)
uv /= _RTHandlePostProcessScale.xy;
#endif
// Streaks
if (LensFlareScreenSpaceStreakIntensity > 0.0)
{
streakFlare = GetFlareTexture(uv, 1, LensFlareScreenSpaceStreakIntensity * STREAK_FLARE_MULTIPLIER, false, false);
}
// Vignette Parameters
float vignettePow = 2.0;
float vignetteScale = 1.0;
float vignetteSquaredness = 2.0; // 1.0 and lower means more star shaped, 2.0 ellipsis, above more squared
// Vignette textures
float2 uvVignette = scaleUV(uv, float2(0.5, 0.5), vignetteScale, false, false);
float vignetteX = saturate(SafePositivePow(abs(2.0 * uvVignette.x - 1.0), (vignetteSquaredness)));
float vignetteY = saturate(SafePositivePow(abs(2.0 * uvVignette.y - 1.0), (vignetteSquaredness)));
float vignetteRound = saturate(SafePositivePow((vignetteX + vignetteY), (vignettePow)));
// Texture to have flares only on the edges of the screen
vignetteRound = lerp(1, vignetteRound, LensFlareScreenSpaceVignetteIntensity);
// Regular Flare
if (LensFlareScreenSpaceIntensity > 0.0)
{
float3 classic = 0.0;
float3 classicInv = 0.0;
float3 polarInv = 0.0;
// The scale of the texture scales with (index + start)^scale
for (int i = 0; i < LensFlareScreenSpaceCount; ++i)
{
float scale = SafePositivePow(abs((i + LensFlareScreenSpaceStartingPosition)), LensFlareScreenSpaceScale);
float currentSampleDimmer = SafePositivePow(LensFlareScreenSpaceCountDimmer, i);
if (LensFlareScreenSpaceSecondaryIntensity > 0.0)
{
classic += GetFlareTexture(uv, -scale, LensFlareScreenSpaceSecondaryIntensity * REGULAR_FLARE_MULTIPLIER * currentSampleDimmer, false, true);
}
if (LensFlareScreenSpaceFirstIntensity > 0.0)
{
classicInv += GetFlareTexture(uv, scale, LensFlareScreenSpaceFirstIntensity * REGULAR_FLARE_MULTIPLIER * currentSampleDimmer, false, true);
}
if (LensFlareScreenSpacePolarIntensity > 0.0)
{
polarInv += GetFlareTexture(uv, -scale, LensFlareScreenSpacePolarIntensity * REGULAR_FLARE_MULTIPLIER * currentSampleDimmer, true, true);
}
}
// Compositing
regularFlare += (classicInv + classic) * vignetteRound; // VignetteRound is to avoid having flare in the middle of the screen.
regularFlare += polarInv * vignetteX; // VignetteX is to prevent discontinuities because polar doesn't tile properly.
}
float4 final = float4(regularFlare + streakFlare, 1.0);
final *= LensFlareScreenSpaceIntensity;
return final;
}
// Write Result to Bloom
real4 FragmentWrite(VaryingsSSLF input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord;
#if defined (HDRP_LENS_FLARE_SCREEN_SPACE)
uv /= _RTHandlePostProcessScale.xy;
#endif
return float4(SampleScaled(_LensFlareScreenSpaceResultTexture, uv), 1.0);
}