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}