summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/render/bgfx/fs_post.sc
blob: bfe8eef42e404ca2ebe90825b4d030572878bac2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
$input v_color0, v_texcoord0, v_texcoord1

// license:BSD-3-Clause
// copyright-holders:Ryan Holtz,ImJezze
//-----------------------------------------------------------------------------
// Defocus Effect
//-----------------------------------------------------------------------------

#include "../../../../../3rdparty/bgfx/examples/common/common.sh"

// Autos
uniform vec4 u_swap_xy;
uniform vec4 u_screen_dims; // size of the output window
uniform vec4 u_source_dims; // size of the guest machine
uniform vec4 u_screen_scale; // TODO: Hook up ScreenScale code-side
uniform vec4 u_screen_offset; // TODO: Hook up ScreenOffset code-side

// User-supplied
uniform vec4 u_prepare_bloom; // disables some effects for rendering bloom textures
uniform vec4 u_prepare_vector;
uniform vec4 u_scanline_alpha;
uniform vec4 u_scanline_scale;
uniform vec4 u_scanline_bright_scale;
uniform vec4 u_scanline_bright_offset;
uniform vec4 u_scanline_jitter;
uniform vec4 u_scanline_height;
uniform vec4 u_back_color; // TODO: Unused in current implementation, mostly
uniform vec4 u_shadow_tile_mode; // 0 based on screen dimension, 1 based on source dimension
uniform vec4 u_shadow_alpha;
uniform vec4 u_shadow_uv;
uniform vec4 u_shadow_uv_offset;
uniform vec4 u_humbar_hertz_rate; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC)
uniform vec4 u_humbar_alpha;
uniform vec4 u_power;
uniform vec4 u_floor;

// Parametric
uniform vec4 u_time;
uniform vec4 u_jitter_amount;

// Samplers
SAMPLER2D(s_tex, 0);
SAMPLER2D(s_shadow, 1);

//-----------------------------------------------------------------------------
// Scanline & Shadowmask Pixel Shader
//-----------------------------------------------------------------------------

vec2 GetAdjustedCoords(vec2 coord, vec2 center_offset)
{
	// center coordinates
	coord -= center_offset;

	// apply screen scale
	//coord /= u_screen_scale.xy;

	// un-center coordinates
	coord += center_offset;

	// apply screen offset
	coord += (center_offset * 2.0) * u_screen_offset.xy;

	return coord;
}

void main()
{
	vec2 ScreenTexelDims = vec2(1.0, 1.0) / u_screen_dims.xy;
	vec2 SourceTexelDims = vec2(1.0, 1.0) / u_source_dims.xy;
	vec2 SourceRes = u_source_dims.xy;

	vec2 HalfSourceRect = vec2(0.5, 0.5);

	vec2 ScreenCoord = v_texcoord0.xy;
	vec2 BaseCoord = GetAdjustedCoords(v_texcoord0, HalfSourceRect);

	// Color
	vec4 BaseColor = texture2D(s_tex, BaseCoord);
	BaseColor.a = 1.0;

	if (BaseCoord.x < 0.0 || BaseCoord.y < 0.0)
	{
		BaseColor.rgb = vec3(0.0, 0.0, 0.0);
	}

	// Mask Simulation (may not affect bloom)
	if (u_prepare_bloom.x == 0.0 && u_shadow_alpha.x > 0.0)
	{
		vec2 screenCoord = ScreenCoord;
		screenCoord = u_swap_xy.x > 0.0 ? screenCoord.yx : screenCoord.xy;

		vec2 shadowTile = (u_shadow_tile_mode.x == 0.0 ? u_screen_dims.xy : u_source_dims.xy);
		shadowTile = u_swap_xy.x > 0.0 ? shadowTile.yx : shadowTile.xy;

		vec2 ShadowFrac = fract(screenCoord * shadowTile);
		vec2 ShadowCoord = (ShadowFrac * u_shadow_uv.xy);

		vec4 ShadowColor = texture2D(s_shadow, ShadowCoord);
		vec3 ShadowMaskColor = mix(vec3(1.0, 1.0, 1.0), ShadowColor.rgb, u_shadow_alpha.xxx);
		float ShadowMaskClear = (1.0 - ShadowColor.a) * u_shadow_alpha.x;

		// apply shadow mask color
		BaseColor.rgb *= ShadowMaskColor;
		// clear shadow mask by background color
		BaseColor.rgb = mix(BaseColor.rgb, u_back_color.rgb, ShadowMaskClear);
	}

	// Color Compression (may not affect bloom)
	if (u_prepare_bloom.x == 0.0)
	{
		// increasing the floor of the signal without affecting the ceiling
		BaseColor.rgb = u_floor.rgb + (vec3(1.0, 1.0, 1.0) - u_floor.rgb) * BaseColor.rgb;
	}

	// Color Power (may affect bloom)
	BaseColor.r = pow(BaseColor.r, u_power.r);
	BaseColor.g = pow(BaseColor.g, u_power.g);
	BaseColor.b = pow(BaseColor.b, u_power.b);

	// Scanline Simulation (may not affect bloom)
	if (u_prepare_bloom.x == 0.0)
	{
		// Scanline Simulation (may not affect vector screen)
		if (u_prepare_vector.x == 0.0 && u_scanline_alpha.x > 0.0f)
		{
			float ScanCoord = v_texcoord0.y * u_source_dims.y * u_scanline_scale.x * 3.1415927;
			float ScanCoordJitter = u_scanline_jitter.x * u_jitter_amount.x * 1.618034;
			float ScanSine = sin(ScanCoord + ScanCoordJitter);
			float ScanSineScaled = pow(ScanSine * ScanSine, 1.0);//u_scanline_height.x);
			float ScanBrightness = (ScanSineScaled * u_scanline_bright_scale.x + 1.0 + u_scanline_bright_offset.x) * 0.5;

			BaseColor.rgb *= mix(vec3(1.0, 1.0, 1.0), vec3(ScanBrightness, ScanBrightness, ScanBrightness), u_scanline_alpha.xxx);
		}

		// Hum Bar Simulation (may not affect vector screen)
		if (u_prepare_vector.x == 0.0 && u_humbar_alpha.x > 0.0f)
		{
			float HumTimeStep = fract(u_time.x * 0.001);
			float HumBrightness = 1.0 - fract(BaseCoord.y + HumTimeStep) * u_humbar_alpha.x;
			BaseColor.rgb *= HumBrightness;
		}
	}

	vec4 Output = u_prepare_vector.x > 0.0 ? BaseColor * (v_color0 + vec4(1.0, 1.0, 1.0, 0.0)) : BaseColor * v_color0;
	Output.a = 1.0;

	gl_FragColor = Output;
}