Thanks for answering!
I’m a shader beginner, I don’t understand much about geometry shaders.
What I want to do is a glare effect, placing these “stars” in the most luminous places.
In this format:

My Code:
Shader "Hidden/ScreenSpaceLensFlare"
{
Properties
{
//_MainTexCamera ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType" = "Opaque" }
ZTest Always Cull Off ZWrite Off
HLSLINCLUDE
#include "../../ShaderLibrary/Common.hlsl"
ENDHLSL
Pass
{
HLSLPROGRAM
#pragma target 3.5
#pragma vertex DefaultPassVertex
#pragma fragment frag
#include "../../ShaderLibrary/UnityInput.hlsl"
//#include "../../ShaderLibrary/Light.hlsl"
TEXTURE2D(_PostFXSource);
SAMPLER(sampler_PostFXSource);
TEXTURE2D(_DirtyTexture);
SAMPLER(sampler_DirtyTexture);
TEXTURE2D(_Spectral);
SAMPLER(sampler_Spectral);
TEXTURE2D(_CameraDeep);
SAMPLER(sampler_CameraDeep);
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings {
float4 positionCS : SV_POSITION;
float2 fxUV : VAR_FX_UV;
};
Varyings DefaultPassVertex(uint vertexID : SV_VertexID) {
Varyings output;
output.positionCS = float4(
vertexID <= 1 ? -1.0 : 3.0,
vertexID == 1 ? 3.0 : -1.0,
0.0, 1.0
);
output.fxUV = float2(
vertexID <= 1 ? 0.0 : 2.0,
vertexID == 1 ? 2.0 : 0.0
);
if (_ProjectionParams.x < 0.0) {
output.fxUV.y = 1.0 - output.fxUV.y;
}
return output;
}
float _Intensity = 1;
float _PixelColumns = 64;
float _PixelRows = 64;
float _Glare = 0;
int _Debug = 0;
float4 GetSource(float2 fxUV) {
return SAMPLE_TEXTURE2D(_PostFXSource, sampler_PostFXSource, fxUV);
}
static const float ghosts[15] = {
-0.07014, 0.08258, -0.09, 0.020, -0.0310625, 0.0320625, -0.025414, -0.065258, 0.051, 0.031, 0.011, 0.02866, 0.0567777765, 0.071578, 0.067891,
};
float4 Glarator(float2 fxUV,int y) : SV_Target
{
float4 color = float4(0, 0, 0, 0);
float2 uv = fxUV - 0.5;
for (int i = 0; i < y; i++) {
float projection = ghosts[i];
float4 colorScene = GetSource(fxUV * projection + 0.52);
float4 colorChannel = -colorScene;// + pow(colorScene, 4);
float greyscale = (colorScene.r + colorScene.g + colorScene.b) / 3.0f;
colorChannel = float4(greyscale, greyscale, greyscale, colorScene.a);
color += colorChannel * (projection * projection);
}
return color;
}
float4 GetSourceThreshold(float2 fxUV, float thr) {
return SAMPLE_TEXTURE2D(_PostFXSource, sampler_PostFXSource, (fxUV - 0.5) / thr + 0.5);
}
float3 textureDistorted(float2 fxUV) {
float2 direction = normalize(fxUV - 0.5);
float r = GetSourceThreshold(fxUV * direction * float3(0, 0, 0.1),20).r;
float g = GetSourceThreshold(fxUV * direction * float3(0, 0, 0.1),20).g;
float b = GetSourceThreshold(fxUV * direction * float3(0, 0, 0.1),20).b;
return float3(r, g, b);
}
float lightIntensity(float2 fxUV, float thr) {
float4 colorChannel = GetSourceThreshold(fxUV, thr);
colorChannel = ((+pow(colorChannel, 4)) * 1) / 333;
float greyscale = (colorChannel.r + colorChannel.g + colorChannel.b) / 3.0f;
return greyscale;
}
float4 frag(Varyings i) : SV_Target
{
float4 colorChannel = GetSource(i.fxUV);
float2 uvFX = i.fxUV.xy;
float4 result = float4(0, 0, 0, 0);
if (_Glare == 1) {
uvFX.x *= _PixelColumns;
uvFX.y *= _PixelRows;
uvFX.x = floor(uvFX.x);
uvFX.y = floor(uvFX.y);
uvFX.x /= _PixelColumns;
uvFX.y /= _PixelRows;
float greyscale = lightIntensity(uvFX, 1);
float4 r = float4(greyscale, greyscale, greyscale, 1);
//r = pow(r, 10);
result += normalize(r);
}
if (_Debug == 0)
return float4(colorChannel.rgb + result, colorChannel.a);
else {
return float4(result.rgb, 1);
}
}
ENDHLSL
}
}
}
I found a project where an effect similar to what I want is done:
https://github.com/keijiro/KinoStreak
This is the keijiro code:
// Kino/Streak - Anamorphic lens flare effect for Unity
// https://github.com/keijiro/KinoStreak
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_TexelSize;
sampler2D _HighTex;
float4 _HighTex_TexelSize;
float _Threshold;
float _Stretch;
float _Intensity;
half3 _Color;
// Prefilter: Shrink horizontally and apply threshold.
half4 frag_prefilter(v2f_img i) : SV_Target
{
// Actually this should be 1, but we assume you need more blur...
const float vscale = 1.5;
const float dy = _MainTex_TexelSize.y * vscale / 2;
half3 c0 = tex2D(_MainTex, float2(i.uv.x, i.uv.y - dy));
half3 c1 = tex2D(_MainTex, float2(i.uv.x, i.uv.y + dy));
half3 c = (c0 + c1) / 2;
float br = max(c.r, max(c.g, c.b));
c *= max(0, br - _Threshold) / max(br, 1e-5);
return half4(c, 1);
}
// Downsampler
half4 frag_down(v2f_img i) : SV_Target
{
// Actually this should be 1, but we assume you need more blur...
const float hscale = 1.25;
const float dx = _MainTex_TexelSize.x * hscale;
float u0 = i.uv.x - dx * 5;
float u1 = i.uv.x - dx * 3;
float u2 = i.uv.x - dx * 1;
float u3 = i.uv.x + dx * 1;
float u4 = i.uv.x + dx * 3;
float u5 = i.uv.x + dx * 5;
half3 c0 = tex2D(_MainTex, float2(u0, i.uv.y));
half3 c1 = tex2D(_MainTex, float2(u1, i.uv.y));
half3 c2 = tex2D(_MainTex, float2(u2, i.uv.y));
half3 c3 = tex2D(_MainTex, float2(u3, i.uv.y));
half3 c4 = tex2D(_MainTex, float2(u4, i.uv.y));
half3 c5 = tex2D(_MainTex, float2(u5, i.uv.y));
// Simple box filter
half3 c = (c0 + c1 + c2 + c3 + c4 + c5) / 6;
return half4(c, 1);
}
// Upsampler
half4 frag_up(v2f_img i) : SV_Target
{
half3 c0 = tex2D(_MainTex, i.uv) / 4;
half3 c1 = tex2D(_MainTex, i.uv) / 2;
half3 c2 = tex2D(_MainTex, i.uv) / 4;
half3 c3 = tex2D(_HighTex, i.uv);
return half4(lerp(c3, c0 + c1 + c2, _Stretch), 1);
}
// Final composition
half4 frag_composite(v2f_img i) : SV_Target
{
half3 c0 = tex2D(_MainTex, i.uv) / 4;
half3 c1 = tex2D(_MainTex, i.uv) / 2;
half3 c2 = tex2D(_MainTex, i.uv) / 4;
half3 c3 = tex2D(_HighTex, i.uv);
half3 cf = (c0 + c1 + c2) * _Color * _Intensity * 5;
return half4(cf + c3, 1);
}
But he creates the glares in just one direction.
I also didn’t understand what are these Downsampler and Upsampler