mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-31 23:45:35 +00:00
071b66999d
Add wareya's linear bloom shader See merge request OpenMW/openmw!2313 (cherry picked from commit537c6e96ab
)534f0377
Add wareya's linear bloom shader84c72b1c
Add dots at the end, and add the .ru translation
231 lines
6.5 KiB
Text
231 lines
6.5 KiB
Text
uniform_float uGamma {
|
|
default = 2.2;
|
|
min = 0.1;
|
|
max = 4.0;
|
|
step = 0.01;
|
|
display_name = "#{BuiltInShaders:GammaLevelName}";
|
|
description = "#{BuiltInShaders:GammaLevelDescription}";
|
|
}
|
|
uniform_float uThreshold {
|
|
default = 0.35;
|
|
min = 0.0;
|
|
max = 1.0;
|
|
step = 0.01;
|
|
description = "#{BuiltInShaders:ThresholdLevelName}";
|
|
display_name = "#{BuiltInShaders:ThresholdLevelDescription}";
|
|
}
|
|
uniform_float uClamp {
|
|
default = 1.0;
|
|
min = 0.0;
|
|
max = 1.0;
|
|
step = 0.01;
|
|
description = "#{BuiltInShaders:BloomClampLevelName}";
|
|
display_name = "#{BuiltInShaders:BloomClampLevelDescription}";
|
|
}
|
|
uniform_float uSkyFactor {
|
|
default = 0.5;
|
|
min = 0.0;
|
|
max = 2.0;
|
|
step = 0.01;
|
|
description = "#{BuiltInShaders:SkyFactorLevelName}";
|
|
display_name = "#{BuiltInShaders:SkyFactorLevelDescription}";
|
|
}
|
|
uniform_float uRadius {
|
|
default = 0.5;
|
|
min = 0.0;
|
|
max = 1.0;
|
|
step = 0.01;
|
|
description = "#{BuiltInShaders:RadiusLevelName}";
|
|
display_name = "#{BuiltInShaders:RadiusLevelDescription}";
|
|
}
|
|
uniform_float uStrength {
|
|
default = 0.25;
|
|
min = 0.0;
|
|
max = 1.0;
|
|
step = 0.01;
|
|
display_name = "#{BuiltInShaders:StrengthLevelName}";
|
|
description = "#{BuiltInShaders:StrengthLevelDescription}";
|
|
}
|
|
|
|
shared {
|
|
float scramblify(float x)
|
|
{
|
|
x = fract(x);
|
|
x = x + 4.0;
|
|
x = x*x;
|
|
x = x*x;
|
|
return fract(x);
|
|
}
|
|
float scramblev2_inner(vec2 v, float z)
|
|
{
|
|
return scramblify(v.x*0.6491 + v.y*0.029 + z);
|
|
}
|
|
|
|
float time = fract(omw.simulationTime);
|
|
vec4 scramblev2(vec2 v)
|
|
{
|
|
v *= 61.12;
|
|
vec2 fwup = vec2(scramblev2_inner(v, fract(time)), scramblev2_inner(v, fract(time*fract(v.x)) + 0.18943));
|
|
return vec4(0.5) - vec4(fwup, fwup);
|
|
}
|
|
|
|
float gauss(float x)
|
|
{
|
|
return exp(-x*x);
|
|
}
|
|
float calculate_radius(vec2 texcoord)
|
|
{
|
|
float radius = uRadius * 0.2;
|
|
radius *= omw.resolution.y;
|
|
radius = max(radius, 0.1);
|
|
// hack: make the radius wider on the screen edges
|
|
// (makes things in the corner of the screen look less "wrong" with not-extremely-low FOVs)
|
|
radius *= pow(texcoord.x*2.0-1.0, 2)+1.0;
|
|
radius *= pow(texcoord.y*2.0-1.0, 2)+1.0;
|
|
return radius;
|
|
}
|
|
vec3 powv(vec3 a, float x)
|
|
{
|
|
return pow(a, vec3(x));
|
|
}
|
|
}
|
|
|
|
render_target RT_NoMipmap {
|
|
width_ratio = 0.25;
|
|
height_ratio = 0.25;
|
|
internal_format = rgb16f;
|
|
source_type = float;
|
|
source_format = rgb;
|
|
mipmaps = false;
|
|
min_filter = nearest;
|
|
mag_filter = nearest;
|
|
}
|
|
|
|
render_target RT_Horizontal {
|
|
width_ratio = 0.25;
|
|
height_ratio = 0.25;
|
|
internal_format = rgb16f;
|
|
source_type = float;
|
|
source_format = rgb;
|
|
mipmaps = false;
|
|
min_filter = nearest;
|
|
mag_filter = nearest;
|
|
}
|
|
|
|
render_target RT_Vertical {
|
|
width_ratio = 0.25;
|
|
height_ratio = 0.25;
|
|
internal_format = rgb16f;
|
|
source_type = float;
|
|
source_format = rgb;
|
|
mipmaps = false;
|
|
min_filter = linear;
|
|
mag_filter = linear;
|
|
}
|
|
|
|
fragment nomipmap(target=RT_NoMipmap) {
|
|
omw_In vec2 omw_TexCoord;
|
|
|
|
void main()
|
|
{
|
|
// downsample into a smaller buffer with mipmapping disabled (no need for it + might interfere with the blurring process)
|
|
// do the gamma compression step while we're at it
|
|
vec3 sample = omw_GetLastShader(omw_TexCoord).rgb;
|
|
bool is_sky = (omw_GetLinearDepth(omw_TexCoord) > omw.far*0.999);
|
|
float factor = is_sky ? uSkyFactor : 1.0;
|
|
vec3 ret_sample = powv(sample, uGamma);
|
|
factor *= (!is_sky && (dot(sample, vec3(1.0/3.0)) < uThreshold)) ? 0.0 : 1.0;
|
|
ret_sample *= factor;
|
|
omw_FragColor = vec4(ret_sample, 1.0);
|
|
}
|
|
}
|
|
|
|
fragment horizontal(target=RT_Horizontal, rt1=RT_NoMipmap) {
|
|
omw_In vec2 omw_TexCoord;
|
|
|
|
void main()
|
|
{
|
|
// gaussian blur, horizontal step
|
|
float radius = calculate_radius(omw_TexCoord);
|
|
int radius_i = int(ceil(radius));
|
|
vec3 sum = vec3(0.0);
|
|
float normalize = 0.0;
|
|
for(int x = -radius_i; x <= radius_i; x += 1)
|
|
{
|
|
float strength = gauss(float(x)/radius*2.0);
|
|
normalize += strength;
|
|
vec2 coord = omw_TexCoord + vec2(float(x), 0.0) / omw.resolution.xy;
|
|
vec3 sample = omw_Texture2D(RT_NoMipmap, coord).rgb;
|
|
sum += strength * sample;
|
|
}
|
|
sum /= normalize;
|
|
|
|
omw_FragColor = vec4(sum, 1.0);
|
|
}
|
|
}
|
|
|
|
fragment vertical(target=RT_Vertical, rt1=RT_Horizontal) {
|
|
omw_In vec2 omw_TexCoord;
|
|
|
|
void main()
|
|
{
|
|
// gaussian blur, vertical step
|
|
float radius = calculate_radius(omw_TexCoord);
|
|
int radius_i = int(ceil(radius));
|
|
vec3 sum = vec3(0.0);
|
|
float normalize = 0.0;
|
|
for(int y = -radius_i; y <= radius_i; y += 1)
|
|
{
|
|
float strength = gauss(float(y)/radius*2.0);
|
|
normalize += strength;
|
|
vec2 coord = omw_TexCoord + vec2(0.0, float(y)) / omw.resolution.xy;
|
|
vec3 sample = omw_Texture2D(RT_Horizontal, coord).rgb;
|
|
sum += strength * sample;
|
|
}
|
|
sum /= normalize;
|
|
|
|
omw_FragColor = vec4(sum, 1.0);
|
|
}
|
|
}
|
|
|
|
fragment final(rt1=RT_Vertical) {
|
|
omw_In vec2 omw_TexCoord;
|
|
|
|
float clampify(float x, float clamp)
|
|
{
|
|
if(x < clamp)
|
|
return x;
|
|
return ((x-clamp)*0.5)+clamp;
|
|
}
|
|
|
|
void main()
|
|
{
|
|
vec3 color = vec3(0.0);
|
|
color = omw_Texture2D(RT_Vertical, omw_TexCoord).rgb;
|
|
// add dithering (in gamma-compressed light, because monitors are sRGB)
|
|
color = powv(color, 1.0/uGamma);
|
|
color += (scramblev2(omw_TexCoord).rgb/255.0 - vec3(0.5/255.0))*2.0;
|
|
color = max(vec3(0.0), color);
|
|
// also do clamping in gamma-compressed light
|
|
float color_luma = dot(color, vec3(1.0/3.0));
|
|
if(uClamp == 0.0)
|
|
color *= 0.0;
|
|
else if(color_luma > uClamp)
|
|
color /= color_luma/uClamp;
|
|
color = powv(color, uGamma);
|
|
|
|
// add bloom to base color in linear light
|
|
vec3 base_color = powv(omw_GetLastShader(omw_TexCoord).rgb, uGamma);
|
|
vec3 add_color = base_color + color * uStrength * 0.5;
|
|
omw_FragColor = vec4(powv(add_color, 1.0/uGamma), 1.0);
|
|
//omw_FragColor = vec4(powv(color, 1.0/uGamma), 1.0);
|
|
}
|
|
}
|
|
|
|
technique {
|
|
passes = nomipmap, horizontal, vertical, final;
|
|
description = "#{BuiltInShaders:BloomDescription}";
|
|
author = "OpenMW";
|
|
version = "1.0";
|
|
}
|
|
|