Simple Light Leak Shader
- TreyM
- Topic Author
Less
More
5 years 8 months ago - 5 years 8 months ago #1
by TreyM
Simple Light Leak Shader was created by TreyM
This is my first shader, so go easy. I'm no pro. What this shader is doing is emulating the effect of light leaks from a cheap camera/lens. It uses 6 textures which are then rotated and flipped to give 12 total variations.
You can adjust the width of the beam, the hue, and the overall intensity/transparency of the effect.
The textures are not the best quality, but I was trying to keep the file size small. If requested I can make some higher quality textures.
Shader with textures: Mediafire link
Shader code:
You can adjust the width of the beam, the hue, and the overall intensity/transparency of the effect.
The textures are not the best quality, but I was trying to keep the file size small. If requested I can make some higher quality textures.
Shader with textures: Mediafire link
Shader code:
Warning: Spoiler!
////////////////////////////////////////////////////
// Simple Light Leak Overlay Shader //
// Author: TreyM //
////////////////////////////////////////////////////
#include "ReShade.fxh"
// UI ELEMENTS /////////////////////////////////////
////////////////////////////////////////////////////
uniform int LightLeak <
ui_type = "combo";
ui_min = 0; ui_max=12;
ui_items =
"Off\0Ping Bottom\0Ping Left\0Ping Top\0Ping Right\0Streak Right\0"
"Streak Left\0Upward Spot\0Downward Spot\0Bottom Rght\0Bottom Left\0"
"Top Left\0Top Right\0";
ui_tooltip =
"Various light leak overlays for stylizing images\n"
"Some light leaks cannot color shift";
> = 1;
uniform int Hue_Shift <
ui_type = "drag";
ui_min = -100; ui_max = 100;
ui_label = "Hue";
ui_tooltip =
"Drag left or right to shift light leak color\n\n"
"< - > Drag to change value\nDouble-click for manual input";
> = 0;
uniform int Leak_Alpha <
ui_type = "drag";
ui_min = 0; ui_max = 100;
ui_label = "Intensity";
ui_tooltip =
"Drag left or right to adjust\nlight leak opacity\n\n"
"< - > Drag to change value\nDouble-click for manual input";
> = 100;
uniform int Leak_Gamma <
ui_type = "drag";
ui_min = 0; ui_max = 100;
ui_label = "Width";
ui_tooltip =
"Drag left or right to adjust\nlight leak contrast\n\n"
"< - > Drag to change value\nDouble-click for manual input";
> = 50;
////////////////////////////////////////////////////
// TEXTURES ////////////////////////////////////////
////////////////////////////////////////////////////
texture Leak1 <source="leak1.jpg";> { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
texture Leak2 <source="leak2.jpg";> { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
texture Leak3 <source="leak3.jpg";> { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
texture Leak4 <source="leak4.jpg";> { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
texture Leak5 <source="leak5.jpg";> { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format=RGBA8; };
////////////////////////////////////////////////////
// SAMPLERS ////////////////////////////////////////
////////////////////////////////////////////////////
sampler sBrightPing { Texture = Leak1; };
sampler sMagentaStreak { Texture = Leak2; };
sampler sWarmSpot { Texture = Leak3; };
sampler sSidePing { Texture = Leak4; };
sampler sCornerPing { Texture = Leak5; };
////////////////////////////////////////////////////
// COLOR FUNCTIONS /////////////////////////////////
////////////////////////////////////////////////////
#ifndef BlendScreenf
#define BlendScreenf(base, blend) (1.0 - ((1.0 - base) * (1.0 - blend)))
#endif
#ifndef Blend
#define Blend(base, blend, funcf) float3(funcf(base.r, blend.r), funcf(base.g, blend.g), funcf(base.b, blend.b))
#endif
#ifndef BlendScreen
#define BlendScreen(base, blend) Blend(base, blend, BlendScreenf)
#endif
float3 rgb2hsv(float3 c) {
float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g));
float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
float3 hsv2rgb(float3 c) {
float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
////////////////////////////////////////////////////
// PIXEL SHADER ////////////////////////////////////
////////////////////////////////////////////////////
float4 PS_LeaksPass(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
{
float3 leak;
float3 original = tex2D(ReShade::BackBuffer, texcoord).rgb;
if(LightLeak == 0) {
return float4(original, 1.0);
}
else if(LightLeak == 1) {
leak = tex2D(sBrightPing, texcoord).rgb;
}
else if(LightLeak == 2) {
leak = tex2D(sSidePing, texcoord).rgb;
}
else if(LightLeak == 3) {
leak = tex2D(sBrightPing, float2(texcoord.x, 1.0-texcoord.y)).rgb;
}
else if(LightLeak == 4) {
leak = tex2D(sSidePing, float2(1.0-texcoord.x, texcoord.y)).rgb;
}
else if(LightLeak == 5) {
leak = tex2D(sMagentaStreak, texcoord).rgb;
}
else if(LightLeak == 6) {
leak = tex2D(sMagentaStreak, float2(1.0-texcoord.x, texcoord.y)).rgb;
}
else if(LightLeak == 7) {
leak = tex2D(sWarmSpot, texcoord).rgb;
}
else if(LightLeak == 8) {
leak = tex2D(sWarmSpot, float2(texcoord.x, 1.0-texcoord.y)).rgb;
}
else if(LightLeak == 9) {
leak = tex2D(sCornerPing, texcoord).rgb;
}
else if(LightLeak == 10) {
leak = tex2D(sCornerPing, float2(1.0-texcoord.x, texcoord.y)).rgb;
}
else if(LightLeak == 11) {
leak = tex2D(sCornerPing, float2(1.0-texcoord.x, 1.0-texcoord.y)).rgb;
}
else if(LightLeak == 12) {
leak = tex2D(sCornerPing, float2(texcoord.x, 1.0-texcoord.y)).rgb;
}
// Hue shifting, if statement avoids division by zero
if(Hue_Shift != 0) {
leak.rgb = rgb2hsv(leak.rgb);
leak.r = frac((Hue_Shift * 0.005) + leak.r);
leak.rgb = hsv2rgb(leak.rgb);
}
// Gamma adjustments to control intensity
leak = pow(leak, lerp(10.0, 1.0, (Leak_Gamma * 0.01)));
// Do the blend and take transparency into account
float3 mix = BlendScreen(original, lerp(0.0, leak, (Leak_Alpha * 0.01)));
// Final output
return float4(mix, 1.0);
}
////////////////////////////////////////////////////
// TECHNIQUE ///////////////////////////////////////
////////////////////////////////////////////////////
technique LightLeaks {
pass LeaksPass {
VertexShader = PostProcessVS;
PixelShader = PS_LeaksPass;
}
}
////////////////////////////////////////////////////
Last edit: 5 years 8 months ago by TreyM.
The following user(s) said Thank You: Wicked Sick, piltrafus, WalterDasTrevas, Ryukou36, GP-Unity, Rudy102, AssassinsDecree, 8qX6a6mQhWSUBycMHgr7wgXCoTATys
Please Log in or Create an account to join the conversation.
- Deathmedic
Less
More
looks good, though it's a bit to static I think, if it reacted to brightness it would be great.
Please Log in or Create an account to join the conversation.
- TreyM
- Topic Author
Less
More
It's not meant for gameplay. It's meant for static screenshots. In the real world, light leaks are not static images, so this is not designed to work for moving imagery.
Please Log in or Create an account to join the conversation.