A game about forced loneliness, made by TACStudios
1#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" 2#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl" 3#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Random.hlsl" 4#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl" 5#include "Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareDataSRP.cs.hlsl" 6#include "Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareOcclusionPermutation.cs.hlsl" 7 8struct AttributesLensFlare 9{ 10 uint vertexID : SV_VertexID; 11 12#ifndef FLARE_PREVIEW 13 UNITY_VERTEX_INPUT_INSTANCE_ID 14#endif 15}; 16 17struct VaryingsLensFlare 18{ 19 float4 positionCS : SV_POSITION; 20 float2 texcoord : TEXCOORD0; 21 float2 screenPos : TEXCOORD1; 22#if defined(FLARE_HAS_OCCLUSION) || defined(FLARE_COMPUTE_OCCLUSION) 23 float occlusion : TEXCOORD2; 24#endif 25 26#ifndef FLARE_PREVIEW 27 UNITY_VERTEX_OUTPUT_STEREO 28#endif 29}; 30 31TEXTURE2D(_FlareTex); 32SAMPLER(sampler_FlareTex); 33 34TEXTURE2D(_FlareOcclusionRemapTex); 35SAMPLER(sampler_FlareOcclusionRemapTex); 36 37#if defined(FLARE_HAS_OCCLUSION) 38TEXTURE2D_ARRAY(_FlareOcclusionTex); 39SAMPLER(sampler_FlareOcclusionTex); 40#endif 41 42#ifdef HDRP_FLARE 43uint _FlareOcclusionPermutation; 44 45TEXTURE2D_X(_FlareSunOcclusionTex); 46SAMPLER(sampler_FlareSunOcclusionTex); 47#endif 48 49float4 _FlareColorValue; 50float4 _FlareData0; // x: localCos0, y: localSin0, zw: PositionOffsetXY 51float4 _FlareData1; // x: OcclusionRadius, y: OcclusionSampleCount, z: ScreenPosZ, w: ScreenRatio 52 // Fragment Shader: 53 // x: LensFlareType, y: ElementIndex 54float4 _FlareData2; // xy: ScreenPos, zw: FlareSize 55float4 _FlareData3; // x: Allow Offscreen, y: Edge Offset, z: Falloff, w: invSideCount 56 // For Ring: 57 // w: RingThickness 58float4 _FlareData4; // x: SDF Roundness, y: Poly Radius, z: PolyParam0, w: PolyParam1 59 // For Ring: 60 // x: noiseAmplitude, y: noiseFrequency, z: noiseSparsity, w: noiseSpeed 61float4 _FlareData5; // x: ConstantColor, y: Intensity, z: shapeCutOffSpeed, w: cutoffRadius 62 63TEXTURE2D(_FlareRadialTint); 64SAMPLER(sampler_FlareRadialTint); 65int _ViewId; // Used for XR index, for SinglePass and Multipass 66 67#ifdef FLARE_PREVIEW 68float4 _FlarePreviewData; 69 70#define _ScreenSize _FlarePreviewData.xy; 71#define _FlareScreenRatio _FlarePreviewData.z; 72#endif 73 74float4 _FlareOcclusionIndex; 75 76#define _LocalCos0 _FlareData0.x 77#define _LocalSin0 _FlareData0.y 78#define _PositionTranslate _FlareData0.zw 79 80// Vertex _FlareData1 81#define _OcclusionRadius _FlareData1.x 82#define _OcclusionSampleCount _FlareData1.y 83#define _ScreenPosZ _FlareData1.z 84#ifndef _FlareScreenRatio 85#define _FlareScreenRatio _FlareData1.w 86#endif 87 88// Fragment _FlareData1 89#define _FlareType ((int)_FlareData1.x) 90#define _FlareElementIndex ((int)_FlareData1.y) 91#define _FlareHoopFactor _FlareData1.z 92 93#define _ScreenPos _FlareData2.xy 94#define _FlareSize _FlareData2.zw 95 96#define _OcclusionOffscreen _FlareData3.x 97#define _FlareEdgeOffset _FlareData3.y 98#define _FlareFalloff _FlareData3.z 99#define _FlareShapeInvSide _FlareData3.w 100#define _FlareRingThickness _FlareData3.w 101 102#define _FlareSDFRoundness _FlareData4.x 103#define _FlareSDFPolyRadius _FlareData4.y 104#define _FlareSDFPolyParam0 _FlareData4.z 105#define _FlareSDFPolyParam1 _FlareData4.w 106 107// For Ring only 108#define _FlareNoiseAmplitude _FlareData4.x 109#define _FlareNoiseFrequency _FlareData4.y 110#define _FlareNoiseSpeed _FlareData4.z 111 112#define _IsFlareColorRadial (_FlareData5.x == 1.0f) 113#define _IsFlareColorAngular (_FlareData5.x == 2.0f) 114 115#define _FlareIntensity _FlareData5.y 116#define _FlareCutoffSpeed _FlareData5.z 117#define _FlareCutoffRadius _FlareData5.w 118 119void Rotate(out float2 rot, float2 v, float cos0, float sin0) 120{ 121 rot = float2(v.x * cos0 - v.y * sin0, 122 v.x * sin0 + v.y * cos0); 123} 124 125// Disables LOAD_TEXTURE2D_ARRAY_LOD-related implicit vector-truncation warnings. 126#pragma warning (disable : 3206) 127 128#if defined(FLARE_COMPUTE_OCCLUSION) || defined(FLARE_OPENGL3_OR_OPENGLCORE) 129float GetLinearDepthValue(float2 uv) 130{ 131 float depth; 132 133#if defined(HDRP_FLARE) || defined(FLARE_PREVIEW) 134 if (_ViewId >= 0) 135 { 136 depth = LOAD_TEXTURE2D_ARRAY_LOD(_CameraDepthTexture, uint2(uv * _ScreenSize.xy), _ViewId, 0).x; 137 } 138 else 139 { 140 depth = LOAD_TEXTURE2D_X_LOD(_CameraDepthTexture, uint2(uv * _ScreenSize.xy), 0).x; 141 } 142 143#else 144 depth = LOAD_TEXTURE2D_X_LOD(_CameraDepthTexture, uint2(uv * GetScaledScreenParams().xy), 0).x; 145 146 if (_ViewId >= 0) 147 { 148#if defined(DISABLE_TEXTURE2D_X_ARRAY) 149 // This should never happen in theory since _ViewId can only be >= 0 IF xr is enabled and so DISABLE_TEXTURE2D_X_ARRAY is disabled. 150 // We just have to manage the DISABLE_TEXTURE2D_X_ARRAY variant here for avoiding warnings. 151 // HDRP does not need this because it never uses DISABLE_TEXTURE2D_X_ARRAY. 152 depth = LOAD_TEXTURE2D_LOD(_CameraDepthTexture, int2(uv * GetScaledScreenParams().xy), 0).x; 153#else 154 depth = LOAD_TEXTURE2D_ARRAY_LOD(_CameraDepthTexture, int2(uv * GetScaledScreenParams().xy), _ViewId, 0).x; 155#endif 156 } 157 else 158 depth = LOAD_TEXTURE2D_X_LOD(_CameraDepthTexture, uint2(uv * GetScaledScreenParams().xy), 0).x; 159 160#endif 161 162 return LinearEyeDepth(depth, _ZBufferParams); 163} 164 165float GetOcclusion(float ratio) 166{ 167 if (_OcclusionSampleCount == 0.0f) 168 return 1.0f; 169 170 float contrib = 0.0f; 171 float sample_Contrib = 1.0f / _OcclusionSampleCount; 172 float2 ratioScale = float2(1.0f / ratio, 1.0); 173 174 for (uint i = 0; i < (uint)_OcclusionSampleCount; i++) 175 { 176 float2 dir = _OcclusionRadius * SampleDiskUniform(Hash(2 * i + 0), Hash(2 * i + 1)); 177 float2 pos0 = _ScreenPos.xy + dir; 178 float2 pos = pos0 * 0.5f + 0.5f; 179#ifdef UNITY_UV_STARTS_AT_TOP 180 pos.y = 1.0f - pos.y; 181#endif 182 183 if (all(pos >= 0) && all(pos <= 1)) 184 { 185 float depth0 = GetLinearDepthValue(pos); 186 187#if UNITY_REVERSED_Z 188 if (depth0 > _ScreenPosZ) 189#else 190 if (depth0 < _ScreenPosZ) 191#endif 192 { 193 float occlusionValue = 1.0f; 194 195#ifdef HDRP_FLARE 196 if ((_FlareOcclusionPermutation & LENSFLAREOCCLUSIONPERMUTATION_FOG_OPACITY) != 0) 197 { 198 float fogOcclusion; 199 if (_ViewId >= 0) 200 fogOcclusion = SAMPLE_TEXTURE2D_ARRAY_LOD(_FlareSunOcclusionTex, sampler_FlareSunOcclusionTex, pos * _RTHandleScale.xy, _ViewId, 0).x; 201 else 202 fogOcclusion = SAMPLE_TEXTURE2D_X_LOD(_FlareSunOcclusionTex, sampler_FlareSunOcclusionTex, pos * _RTHandleScale.xy, 0).x; 203 occlusionValue *= saturate(fogOcclusion); 204 } 205#endif 206 207 contrib += sample_Contrib * occlusionValue; 208 } 209 } 210 else if (_OcclusionOffscreen > 0.0f) 211 { 212 contrib += sample_Contrib; 213 } 214 } 215 216 contrib = SAMPLE_TEXTURE2D_LOD(_FlareOcclusionRemapTex, sampler_FlareOcclusionRemapTex, float2(saturate(contrib), 0.0f), 0).x; 217 contrib = saturate(contrib); 218 219 return contrib; 220} 221#endif 222 223#if defined(FLARE_COMPUTE_OCCLUSION) 224VaryingsLensFlare vertOcclusion(AttributesLensFlare input, uint instanceID : SV_InstanceID) 225{ 226 VaryingsLensFlare output; 227 228 UNITY_SETUP_INSTANCE_ID(input); 229 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); 230 231#if defined(HDRP_FLARE) || defined(FLARE_PREVIEW) 232 float screenRatio = _FlareScreenRatio; 233#else 234 float2 screenParam = GetScaledScreenParams().xy; 235 float screenRatio = screenParam.y / screenParam.x; 236#endif 237 238 float2 quadPos = 2.0f * GetQuadVertexPosition(input.vertexID).xy - 1.0f; 239 float2 uv = GetQuadTexCoord(input.vertexID); 240 uv.x = 1.0f - uv.x; 241 output.positionCS.xy = quadPos; 242 243 output.texcoord.xy = uv; 244 245 output.positionCS.z = 1.0f; 246 output.positionCS.w = 1.0f; 247 248 float occlusion = GetOcclusion(screenRatio); 249 250 if (_OcclusionOffscreen < 0.0f && // No lens flare off screen 251 (any(_ScreenPos.xy < -1) || any(_ScreenPos.xy >= 1))) 252 occlusion = 0.0f; 253 254 output.occlusion = occlusion; 255 output.screenPos = output.positionCS.xy; 256 257 return output; 258} 259 260float4 fragOcclusion(VaryingsLensFlare input) : SV_Target 261{ 262 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); 263 264 return float4(input.occlusion.xxx, 1.0f); 265} 266#else 267VaryingsLensFlare vert(AttributesLensFlare input, uint instanceID : SV_InstanceID) 268{ 269 VaryingsLensFlare output; 270 271#ifndef FLARE_PREVIEW 272 UNITY_SETUP_INSTANCE_ID(input); 273 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); 274#endif 275 276#if defined(HDRP_FLARE) || defined(FLARE_PREVIEW) 277 float screenRatio = _FlareScreenRatio; 278#else 279 float2 screenParam = GetScaledScreenParams().xy; 280 float screenRatio = screenParam.y / screenParam.x; 281#endif 282 283 float4 posPreScale = float4(2.0f, 2.0f, 1.0f, 1.0f) * GetQuadVertexPosition(input.vertexID) - float4(1.0f, 1.0f, 0.0f, 0.0); 284 float2 uv = GetQuadTexCoord(input.vertexID); 285 uv.x = 1.0f - uv.x; 286 287 output.texcoord.xy = uv; 288 289 posPreScale.xy *= _FlareSize; 290 float2 local; 291 Rotate(local, posPreScale.xy, _LocalCos0, _LocalSin0); 292 293 local.x *= screenRatio; 294 295 output.positionCS.xy = local + _ScreenPos + _PositionTranslate; 296 output.positionCS.z = 1.0f; 297 output.positionCS.w = 1.0f; 298 299#if defined(FLARE_HAS_OCCLUSION) 300 float occlusion; 301 302 if (_OcclusionOffscreen < 0.0f && // No lens flare off screen 303 (any(_ScreenPos.xy < -1.0f) || any(_ScreenPos.xy > 1.0f))) 304 { 305 occlusion = 0.0f; 306 } 307 else 308 { 309#if defined(FLARE_OPENGL3_OR_OPENGLCORE) 310 311#if defined(HDRP_FLARE) || defined(FLARE_PREVIEW) 312 float screenRatio = _FlareScreenRatio; 313#else 314 float2 screenParam = GetScaledScreenParams().xy; 315 float screenRatio = screenParam.y / screenParam.x; 316#endif 317 318 occlusion = GetOcclusion(screenRatio); 319 320#else // defined(FLARE_OPENGL3_OR_OPENGLCORE) 321 322 if (_ViewId >= 0) 323 occlusion = LOAD_TEXTURE2D_ARRAY_LOD(_FlareOcclusionTex, uint2(_FlareOcclusionIndex.x, 0), _ViewId, 0).x; 324 else 325 occlusion = LOAD_TEXTURE2D_ARRAY_LOD(_FlareOcclusionTex, uint2(_FlareOcclusionIndex.x, 0), 0, 0).x; 326 327#endif // defined(FLARE_OPENGL3_OR_OPENGLCORE) 328 } 329 330 output.occlusion = occlusion; 331#endif 332 output.screenPos = output.positionCS.xy; 333 334 return output; 335} 336#endif 337 338// Resets LOAD_TEXTURE2D_ARRAY_LOD-related implicit vector-truncation warnings. 339#pragma warning (default : 3206) 340 341// Constrains: x in [0.0f, 1.0f] 342float InverseGradient(float x) 343{ 344 // Before: 345 346 // Do *not* simplify as 1.0f - x 347 //return x * (1.0f - x) / (x + eps); 348 // Kind of equivalent of (without the edge smoothness control): 349 //if (0.0f < x && x < 1.0f) 350 // return 1.0f - x; 351 //else 352 // return 0.0f; 353 354 // After: 355 356 // Larger eps give smoother boundary-edges 357 const float eps = 1e-3f; 358 // cf. https://www.desmos.com/calculator/0hprry9l90 359 // Rescale to always have the max at 1.0f; 360 // 361 // The max of 'x * (1.0f - x) / (x + eps)' 362 // Is when x == sqrt(eps (1 + eps)) - eps 363 // which is => 1 + 2*eps - 2*sqrt(eps*(1 + eps)) 364 // We can rescale by scaling with 1/maxValue 365 // => x*(1 - x)/(x + eps)*(1/(1 + 2*eps - 2*sqrt(eps*(1 + eps)))) 366 // Simplifed as: 367 // Compile-time variables: 368 const float eps2 = 2.0f * eps; 369 const float scale = 2.0f * sqrt(eps * (1.0f + eps)); 370 const float a = scale - eps2 - 1.0f; 371 const float b = a * eps; 372 373 //return x * (x - 1.0f) / (a * x + b); 374 // to: 375 return mad(x, x, -x) * rcp(mad(a, x, b)); 376} 377 378float CircleSDF(float2 center, float2 pos, float r) 379{ 380 return length(pos - center) - r; 381} 382 383float SDFBlocker(float2 pos, float2 screenPos, float ar, float r) 384{ 385 float2 localPos = _ScreenPos - screenPos; 386 localPos.y = -localPos.y; 387 388 float2 offset = localPos * _FlareCutoffSpeed; 389 390 float2 rot; 391 Rotate(rot, offset, _LocalCos0, _LocalSin0); 392 393 pos.y *= ar; 394 395 return CircleSDF(pos, rot, _FlareCutoffRadius * r); 396} 397 398float ComputeCircle(float2 uv, float2 screenPos) 399{ 400 float2 v = 2.0f * uv - 1.0f; 401 402 float radius = 1.0f; 403 float sdfBlocker = SDFBlocker(v, screenPos, _FlareSize.y / _FlareSize.x, radius); 404 float sdfSrc = CircleSDF(v, float2(0.0f, 0.0f), radius); 405 406 float sdf = max(sdfSrc, sdfBlocker); 407 408 sdf = saturate(sdf / ((_FlareEdgeOffset - radius))); 409 410#if defined(FLARE_INVERSE_SDF) 411 sdf = saturate(sdf); 412 sdf = InverseGradient(sdf); 413#endif 414 415 sdf = pow(saturate(sdf), _FlareFalloff); 416 417 return sdf; 418} 419 420// Modfied from ref: https://www.shadertoy.com/view/MtKcWW 421// https://www.shadertoy.com/view/3tGBDt 422float ComputePolygon(float2 uv_, float2 screenPos) 423{ 424 float2 v = 2.0f * uv_ - 1.0f; 425 426 float r = _FlareSDFPolyRadius; 427 float an = _FlareSDFPolyParam0; 428 float he = _FlareSDFPolyParam1; 429 430 float bn = an * floor((atan2(v.y, v.x) + 0.5f * an) / an); 431 float cos0 = cos(bn); 432 float sin0 = sin(bn); 433 float2 p = float2( cos0 * v.x + sin0 * v.y, 434 -sin0 * v.x + cos0 * v.y); 435 436 // side of polygon 437 float sdf = length(p - float2(r, clamp(p.y, -he, he))) * sign(p.x - r) - _FlareSDFRoundness; 438 439 float sdfBlocker = SDFBlocker(v, screenPos, _FlareSize.y / _FlareSize.x, r); 440 sdf = max(sdf, sdfBlocker); 441 442 sdf *= _FlareEdgeOffset; 443 444#if defined(FLARE_INVERSE_SDF) 445 sdf = saturate(-sdf); 446 sdf = InverseGradient(sdf); 447#else 448 sdf = saturate(-sdf); 449#endif 450 451 sdf = pow(saturate(sdf), _FlareFalloff); 452 453 return sdf; 454} 455 456float4 Interpolation_C2_InterpAndDeriv(float2 x) 457{ 458 return x.xyxy * x.xyxy * (x.xyxy * (x.xyxy * (x.xyxy * float2(6.0f, 0.0f).xxyy + float2(-15.0f, 30.0f).xxyy) + float2(10.0f, -60.0f).xxyy) + float2(0.0f, 30.0f).xxyy); 459} 460 461// Generates a random number for each of the 4 cell corners 462float4 NoiseHash2D(float2 gridcell) 463{ 464 float2 kOffset = float2(26.0f, 161.0f); 465 float kDomain = 71.0f; 466 float kLargeFloat = 1.0f / 951.135664f; 467 468 float4 P = float4(gridcell.xy, gridcell.xy + 1.0f); 469 P = P - floor(P * (1.0f / kDomain)) * kDomain; // truncate the domain 470 P += kOffset.xyxy; // offset to interesting part of the noise 471 P *= P; // calculate and return the hash 472 return frac(P.xzxz * P.yyww * kLargeFloat); 473} 474 475float GenerateValueNoise2D(float2 coordinate) 476{ 477 float2 i = floor(coordinate); 478 float2 f = coordinate - i; 479 480 float4 hash = NoiseHash2D(i); 481 482 float4 blend = Interpolation_C2_InterpAndDeriv(f); 483 float4 res0 = lerp(hash.xyxz, hash.zwyw, blend.yyxx); 484 float2 resDelta = res0.yw - res0.xz; 485 486 float noise = res0.x + resDelta.x * blend.x; 487 488 return noise; 489} 490 491float ComputeRing(float2 uv_, float2 screenPos) 492{ 493 float2 pos = 2.0f * uv_ - 1.0f; 494 495#ifndef FLARE_PREVIEW 496 float iTime = _Time.y; 497#else 498 float iTime = 0; 499#endif 500 501 float r = 1.0f; 502 503 float ang = FastAtan2(pos.y, pos.x); 504 505 float2 sc; 506 float noiseAng = ang * _FlareNoiseFrequency; 507 sincos(noiseAng, sc.x, sc.y); 508 509 float noise = abs(abs(GenerateValueNoise2D(_FlareNoiseAmplitude * sc + _FlareElementIndex.xx + _FlareNoiseSpeed * iTime))); 510 511 float sdfBlocker = CircleSDF(pos, float2(0.0f, 0.0f), r); 512 float sdf; 513 sdf = abs(CircleSDF(pos, 0.0f.xx, (1.0f - _FlareRingThickness))) - _FlareRingThickness; 514 sdf = max(noise * sdf, sdfBlocker); 515 516 sdf = saturate(sdf / ((_FlareEdgeOffset - r))); 517 518#if defined(FLARE_INVERSE_SDF) 519 sdf = saturate(sdf); 520 sdf = InverseGradient(sdf); 521#endif 522 523 sdf = pow(saturate(sdf), _FlareFalloff); 524 525 float sdfBlockerCutoff = SDFBlocker(pos, screenPos, _FlareSize.y / _FlareSize.x, 1.0f); 526 sdf *= saturate(-sdfBlockerCutoff > 0.0f); 527 528 return sdf; 529} 530 531float4 GetFlareShape(float2 uv, float2 screenPos) 532{ 533 float4 flareColor = 1.0f; 534 535 float shape; 536 537 if (_FlareType == SRPLENSFLARETYPE_CIRCLE) 538 shape = ComputeCircle(uv, screenPos); 539 else if (_FlareType == SRPLENSFLARETYPE_POLYGON) 540 shape = ComputePolygon(uv, screenPos); 541 else if (_FlareType == SRPLENSFLARETYPE_RING) 542 shape = ComputeRing(uv, screenPos); 543 else if (_FlareType == SRPLENSFLARETYPE_IMAGE) 544 { 545 shape = 1.0f; 546 flareColor = SAMPLE_TEXTURE2D(_FlareTex, sampler_FlareTex, uv); 547 float sdfBlocker = SDFBlocker(2.0f * uv - 1.0f, screenPos, _FlareSize.y / _FlareSize.x, 1.0f); 548 flareColor *= saturate(-sdfBlocker > 0.0f); 549 } 550 else 551 { 552 // Not possible, if the code execute this lines, we have a bug on the code 553 // SRPLENSFLARETYPE_LENS_FLARE_DATA_SRP should never be executed 554 shape = -1.0f; 555 } 556 557#if defined(HDRP_FLARE) || defined(FLARE_PREVIEW) 558 float screenRatio = _FlareScreenRatio; 559#else 560 float2 screenParam = GetScaledScreenParams().xy; 561 float screenRatio = screenParam.y / screenParam.x; 562#endif 563 564 float2 pos = 2.0f * uv - 1.0f; 565 if (_IsFlareColorRadial) 566 { 567 float radius = length(pos); 568 if (_FlareType == SRPLENSFLARETYPE_RING) 569 { 570 float offset = 1.0f - _FlareRingThickness; 571 float a = (1.0f / clamp(2.0f * _FlareRingThickness, _FlareRingThickness, 1.0f)); 572 float b = 1.0f - a; 573 radius = saturate(a * radius + b); 574 } 575 float4 grad = SAMPLE_TEXTURE2D_LOD(_FlareRadialTint, sampler_FlareRadialTint, float2(saturate(radius), 0.0f), 0); 576 flareColor *= grad; 577 } 578 else if (_IsFlareColorAngular) 579 { 580 float angle01 = (atan2(pos.y, pos.x) + PI) / TWO_PI; 581 float4 grad = SAMPLE_TEXTURE2D_LOD(_FlareRadialTint, sampler_FlareRadialTint, float2(saturate(angle01), 0.0f), 0); 582 flareColor *= grad; 583 } 584 flareColor *= _FlareColorValue; 585 flareColor.rgb *= _FlareIntensity; 586 587#ifdef FLARE_ADDITIVE_BLEND 588 float4 finalValue = float4(flareColor.rgb * shape, shape * flareColor.a); 589#elif defined(FLARE_SCREEN_BLEND) 590 float4 finalValue = float4(flareColor.rgb * shape, shape * flareColor.a); 591#elif defined(FLARE_PREMULTIPLIED_BLEND) 592 float4 finalValue = float4(flareColor.rgb * shape, shape * flareColor.a); 593#elif defined(FLARE_LERP_BLEND) 594 float4 finalValue = float4(flareColor.rgb, shape * flareColor.a); 595#else 596 float4 finalValue = flareColor * shape; 597#endif 598 599 return finalValue; 600} 601 602float4 frag(VaryingsLensFlare input) : SV_Target 603{ 604#ifndef FLARE_PREVIEW 605 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); 606#endif 607 608#if defined(FLARE_HAS_OCCLUSION) 609 if (input.occlusion > 0.0f) 610 { 611 float4 col = GetFlareShape(input.texcoord, input.screenPos.xy); 612 613 return col * input.occlusion; 614 } 615 else 616 { 617 return float4(0.0f, 0.0f, 0.0f, 0.0f); 618 } 619#else 620 float4 col = GetFlareShape(input.texcoord, input.screenPos.xy); 621 622 return col; 623#endif 624}