slang-shaders/test/nonfunctional/shaders/mame/mame_bloom.slang
2019-03-27 16:28:59 -05:00

232 lines
7.9 KiB
Plaintext

#version 450
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz,ImJezze
//-----------------------------------------------------------------------------
// Bloom Effect
//-----------------------------------------------------------------------------
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OutputSize;
} params;
#include "mame_parameters.inc"
float Level0Weight = global.level0weight;
float Level1Weight = global.level1weight;
float Level2Weight = global.level2weight;
float Level3Weight = global.level3weight;
float Level4Weight = global.level4weight;
float Level5Weight = global.level5weight;
float Level6Weight = global.level6weight;
float Level7Weight = global.level7weight;
float Level8Weight = global.level8weight;
int BloomBlendMode = int(global.bloomblendmode); // 0 brighten, 1 darken
float BloomScale = global.bloomscale;
vec3 BloomOverdrive = vec3(global.bloomoverdrive_r, global.bloomoverdrive_g, global.bloomoverdrive_b);
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
const float E = 2.7182817f;
const float Gelfond = 23.140692f; // e^pi (Gelfond constant)
const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant)
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/
float random(vec2 seed)
{
// irrationals for pseudo randomness
vec2 i = vec2(Gelfond, GelfondSchneider);
return fract(cos(dot(seed, i)) * 123456.0f);
}
//-----------------------------------------------------------------------------
// Bloom Vertex Shader
//-----------------------------------------------------------------------------
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
layout(location = 1) out vec2 BloomCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
BloomCoord = vTexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 1) in vec2 BloomCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
#define DiffuseSampler Source
#define BloomSamplerA Source
#define BloomSamplerB Source
#define BloomSamplerC Source
#define BloomSamplerD Source
#define BloomSamplerE Source
#define BloomSamplerF Source
#define BloomSamplerG Source
#define BloomSamplerH Source
// vector screen uses twice -1 as many bloom levels
#define BloomSamplerI Source
#define BloomSamplerJ Source
#define BloomSamplerK Source
#define BloomSamplerL Source
#define BloomSamplerM Source
#define BloomSamplerN Source
#define BloomSamplerO Source
vec3 GetNoiseFactor(vec3 n, float random)
{
// smaller n become more noisy
vec3 NoiseFactor;
NoiseFactor.x = 1.0f + random * max(0.0f, 0.25f * pow(E, -8. * n.x));
NoiseFactor.y = 1.0f + random * max(0.0f, 0.25f * pow(E, -8. * n.y));
NoiseFactor.z = 1.0f + random * max(0.0f, 0.25f * pow(E, -8. * n.z));
return NoiseFactor;
}
void main()
{
if(!BloomToggle)
{
FragColor = texture(Source, vTexCoord);
return;
}
else
{
vec3 texel = textureLod(DiffuseSampler, vTexCoord, 0.0).rgb;
vec3 texelA = textureLod(BloomSamplerA, BloomCoord.xy, 1.0).rgb;
vec3 texelB = textureLod(BloomSamplerB, BloomCoord.xy, 2.0).rgb;
vec3 texelC = textureLod(BloomSamplerC, BloomCoord.xy, 3.0).rgb;
vec3 texelD = textureLod(BloomSamplerD, BloomCoord.xy, 4.0).rgb;
vec3 texelE = textureLod(BloomSamplerE, BloomCoord.xy, 5.0).rgb;
vec3 texelF = textureLod(BloomSamplerF, BloomCoord.xy, 6.0).rgb;
vec3 texelG = textureLod(BloomSamplerG, BloomCoord.xy, 7.0).rgb;
vec3 texelH = textureLod(BloomSamplerH, BloomCoord.xy, 8.0).rgb;
vec3 texelI = vec3(0.0f, 0.0f, 0.0f);
vec3 texelJ = vec3(0.0f, 0.0f, 0.0f);
vec3 texelK = vec3(0.0f, 0.0f, 0.0f);
vec3 texelL = vec3(0.0f, 0.0f, 0.0f);
vec3 texelM = vec3(0.0f, 0.0f, 0.0f);
vec3 texelN = vec3(0.0f, 0.0f, 0.0f);
vec3 texelO = vec3(0.0f, 0.0f, 0.0f);
// vector screen uses twice -1 as many bloom levels
if (VectorScreen)
{
texelI = textureLod(BloomSamplerI, BloomCoord.xy, 1.0).rgb;
texelJ = textureLod(BloomSamplerJ, BloomCoord.xy, 1.0).rgb;
texelK = textureLod(BloomSamplerK, BloomCoord.xy, 1.0).rgb;
texelL = textureLod(BloomSamplerL, BloomCoord.xy, 1.0).rgb;
texelM = textureLod(BloomSamplerM, BloomCoord.xy, 1.0).rgb;
texelN = textureLod(BloomSamplerN, BloomCoord.xy, 1.0).rgb;
texelO = textureLod(BloomSamplerO, BloomCoord.xy, 1.0).rgb;
}
vec3 blend;
// brighten
if (BloomBlendMode < 0.5)
{
vec3 bloom = vec3(0.0f, 0.0f, 0.0f);
texel *= Level0Weight;
if (VectorScreen)
{
bloom += texelA * Level1Weight;
bloom += texelB * Level2Weight;
bloom += texelC * Level3Weight;
bloom += texelD * Level4Weight;
bloom += texelE * Level5Weight;
bloom += texelF * Level6Weight;
bloom += texelG * Level7Weight;
bloom += texelH * Level8Weight;
}
// vector screen uses twice -1 as many bloom levels
else
{
bloom += texelA * (Level1Weight);
bloom += texelB * (Level1Weight + Level2Weight) * 0.5f;
bloom += texelC * (Level2Weight);
bloom += texelD * (Level2Weight + Level3Weight) * 0.5f;
bloom += texelE * (Level3Weight);
bloom += texelF * (Level3Weight + Level4Weight) * 0.5f;
bloom += texelG * (Level4Weight);
bloom += texelH * (Level4Weight + Level5Weight) * 0.5f;
bloom += texelI * (Level5Weight);
bloom += texelJ * (Level5Weight + Level6Weight) * 0.5f;
bloom += texelK * (Level6Weight);
bloom += texelL * (Level6Weight + Level7Weight) * 0.5f;
bloom += texelM * (Level7Weight);
bloom += texelN * (Level7Weight + Level8Weight) * 0.5f;
bloom += texelO * (Level8Weight);
}
bloom *= BloomScale;
vec3 bloomOverdrive;
bloomOverdrive.r = max(0.0f, texel.r + bloom.r - 1.0f) * BloomOverdrive.r;
bloomOverdrive.g = max(0.0f, texel.g + bloom.g - 1.0f) * BloomOverdrive.g;
bloomOverdrive.b = max(0.0f, texel.b + bloom.b - 1.0f) * BloomOverdrive.b;
bloom.r += bloomOverdrive.g * 0.5f;
bloom.r += bloomOverdrive.b * 0.5f;
bloom.g += bloomOverdrive.r * 0.5f;
bloom.g += bloomOverdrive.b * 0.5f;
bloom.b += bloomOverdrive.r * 0.5f;
bloom.b += bloomOverdrive.g * 0.5f;
vec2 NoiseCoord = vTexCoord;
vec3 NoiseFactor = GetNoiseFactor(bloom, random(NoiseCoord));
blend = texel + bloom * NoiseFactor;
}
// darken
else
{
texelA = min(texel, texelA);
texelB = min(texel, texelB);
texelC = min(texel, texelC);
texelD = min(texel, texelD);
texelE = min(texel, texelE);
texelF = min(texel, texelF);
texelG = min(texel, texelG);
texelH = min(texel, texelH);
blend = texel * Level0Weight;
blend = mix(blend, texelA, Level1Weight * BloomScale);
blend = mix(blend, texelB, Level2Weight * BloomScale);
blend = mix(blend, texelC, Level3Weight * BloomScale);
blend = mix(blend, texelD, Level4Weight * BloomScale);
blend = mix(blend, texelE, Level5Weight * BloomScale);
blend = mix(blend, texelF, Level6Weight * BloomScale);
blend = mix(blend, texelG, Level7Weight * BloomScale);
blend = mix(blend, texelH, Level8Weight * BloomScale);
}
FragColor = vec4(blend, 1.0);
}
}