mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-01 03:21:41 +00:00
223 lines
6.2 KiB
Plaintext
223 lines
6.2 KiB
Plaintext
uniform_float uGamma {
|
|
default = 2.2;
|
|
min = 0.1;
|
|
max = 4.0;
|
|
step = 0.01;
|
|
display_name = "#{OMWShaders:GammaLevelName}";
|
|
description = "#{OMWShaders:GammaLevelDescription}";
|
|
}
|
|
uniform_float uThreshold {
|
|
default = 0.35;
|
|
min = 0.0;
|
|
max = 1.0;
|
|
step = 0.01;
|
|
display_name = "#{OMWShaders:BloomThresholdLevelName}";
|
|
description = "#{OMWShaders:BloomThresholdLevelDescription}";
|
|
}
|
|
uniform_float uClamp {
|
|
default = 1.0;
|
|
min = 0.0;
|
|
max = 1.0;
|
|
step = 0.01;
|
|
display_name = "#{OMWShaders:BloomClampLevelName}";
|
|
description = "#{OMWShaders:BloomClampLevelDescription}";
|
|
}
|
|
uniform_float uSkyFactor {
|
|
default = 0.5;
|
|
min = 0.0;
|
|
max = 2.0;
|
|
step = 0.01;
|
|
display_name = "#{OMWShaders:SkyFactorLevelName}";
|
|
description = "#{OMWShaders:SkyFactorLevelDescription}";
|
|
}
|
|
uniform_float uRadius {
|
|
default = 0.5;
|
|
min = 0.0;
|
|
max = 1.0;
|
|
step = 0.01;
|
|
display_name = "#{OMWShaders:RadiusLevelName}";
|
|
description = "#{OMWShaders:RadiusLevelDescription}";
|
|
}
|
|
uniform_float uStrength {
|
|
default = 0.25;
|
|
min = 0.0;
|
|
max = 1.0;
|
|
step = 0.01;
|
|
display_name = "#{OMWShaders:StrengthLevelName}";
|
|
description = "#{OMWShaders: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;
|
|
|
|
void main()
|
|
{
|
|
vec3 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);
|
|
}
|
|
}
|
|
|
|
technique {
|
|
passes = nomipmap, horizontal, vertical, final;
|
|
description = "#{OMWShaders:BloomDescription}";
|
|
author = "OpenMW";
|
|
version = "1.0";
|
|
}
|
|
|