2.0
[tar-legacy.git] / MCDV / shaders / fullscreenbase.fs
1 #version 330 core
2 // OPENGL
3 // ____________________________________________________________________________________________
4 in vec2 TexCoords;
5 out vec4 FragColor;
6
7 // UNIFORMS
8 // Vector Information _________________________________________________________________________
9 // ( A bunch of vectors that give you the location of different entities )
10 uniform vec3 bounds_NWU; // North-West-Upper coordinate of the playspace (worldspace)
11 uniform vec3 bounds_SEL; // South-East-Lower coordinate of the playspace (worldspace)
12
13 // SAMPLER UNIFORMS
14 // Image Inputs _______________________________________________________________________________
15 uniform sampler2D tex_gradient;
16 uniform sampler2D tex_background;
17 uniform sampler2D tex_modulate;
18 uniform sampler2D gbuffer_position;
19 uniform sampler2D gbuffer_clean_position;
20 uniform sampler2D gbuffer_normal;
21 uniform usampler2D gbuffer_info;
22 uniform usampler2D umask_playspace;
23 uniform usampler2D umask_objectives;
24 uniform usampler2D umask_buyzone;
25
26 uniform vec3 samples[256];
27 uniform sampler2D ssaoRotations;
28 uniform float ssaoScale;
29 uniform mat4 projection;
30 uniform mat4 view;
31
32 const vec2 noiseScale = vec2(1024.0/256.0, 1024.0/256.0);
33
34 uniform vec4 color_objective;
35 uniform vec4 color_buyzone;
36 uniform vec4 color_cover;
37 uniform vec4 color_cover2;
38
39 // SHADER HELPERS
40 // ____________________________________________________________________________________________
41 // --------------------------------------- Blend modes ----------------------------------------
42
43 float lerp(float a, float b, float w)
44 {
45 return a + w*(b-a);
46 }
47
48 vec3 lerp(vec3 a, vec3 b, float w)
49 {
50 return a + w*(b-a);
51 }
52
53 vec4 blend_normal(vec4 a, vec4 b, float s)
54 {
55 return vec4(lerp(a.rgb, b.rgb, b.a * s), a.a + (b.a * s));
56 }
57
58 vec4 blend_add(vec4 a, vec4 b, float s)
59 {
60 return vec4(a.rgb + (b.rgb * s), a.a);
61 }
62
63 // ------------------------------------------ maths -------------------------------------------
64 float remap(float value, float low1, float high1, float low2, float high2)
65 {
66 return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
67 }
68
69 // SHADER PROGRAM
70 // ____________________________________________________________________________________________
71 // ( Write all your shader code & functions here )
72
73 vec4 sample_gradient(float height)
74 {
75 return vec4(texture(tex_gradient, vec2(remap(height, bounds_SEL.y, bounds_NWU.y, 0, 1), 0)));
76 }
77
78 float kernel_filter_glow(sampler2D sampler, int channelID, int sample_size, int inverse)
79 {
80 vec2 pixel_size = 1.0 / vec2(textureSize(sampler, 0));
81
82 float sT = 0;
83 int sample_double = sample_size * 2;
84
85 // Process kernel
86 for(int x = 0; x <= sample_double; x++){
87 for(int y = 0; y <= sample_double; y++){
88 if(inverse == 0)
89 sT += texture(sampler, TexCoords + vec2((-sample_size + x) * pixel_size.x, (-sample_size + y) * pixel_size.y))[channelID];
90 else sT += 1 - texture(sampler, TexCoords + vec2((-sample_size + x) * pixel_size.x, (-sample_size + y) * pixel_size.y))[channelID];
91 }
92 }
93
94 sT /= (sample_double * sample_double);
95
96 return sT;
97 }
98
99 // Given a 0-1 mask, return an outline drawn around that mask
100 float kernel_filter_outline(sampler2D sampler, int channelID, int sample_size)
101 {
102 vec2 pixel_size = 1.0 / vec2(textureSize(sampler, 0));
103
104 float sT = 0;
105 int sample_double = sample_size * 2;
106
107 // Process kernel
108 for(int x = 0; x <= sample_double; x++){
109 for(int y = 0; y <= sample_double; y++){
110 sT += //texture(sampler, TexCoords + vec2((-sample_size + x) * pixel_size.x, (-sample_size + y) * pixel_size.y))[channelID];
111 (sample_size - min(length(vec2(-sample_size + x, -sample_size + y)), sample_size)) *
112 texture(sampler, TexCoords + vec2((-sample_size + x) * pixel_size.x, (-sample_size + y) * pixel_size.y))[channelID];
113 }
114 }
115
116 return max(min(sT, 1) - texture(sampler, TexCoords)[channelID], 0);
117 }
118
119 float kernel_filter_glow(usampler2D sampler, int sample_size, int inverse)
120 {
121 vec2 pixel_size = 1.0 / vec2(textureSize(sampler, 0));
122
123 uint sT = 0U;
124 int sample_double = sample_size * 2;
125
126 // Process kernel
127 for(int x = 0; x <= sample_double; x++){
128 for(int y = 0; y <= sample_double; y++){
129 if(inverse == 0)
130 sT += texture(sampler, TexCoords + vec2((-sample_size + x) * pixel_size.x, (-sample_size + y) * pixel_size.y)).r;
131 else sT += 1U - texture(sampler, TexCoords + vec2((-sample_size + x) * pixel_size.x, (-sample_size + y) * pixel_size.y)).r;
132 }
133 }
134 float r = float(sT) / (sample_double * sample_double);
135 return r * r;
136 }
137
138 // Given a 0-1 mask, return an outline drawn around that mask
139 float kernel_filter_outline(usampler2D sampler, int sample_size)
140 {
141 vec2 pixel_size = 1.0 / vec2(textureSize(sampler, 0));
142
143 float sT = 0;
144 int sample_double = sample_size * 2;
145
146 // Process kernel
147 for(int x = 0; x <= sample_double; x++){
148 for(int y = 0; y <= sample_double; y++){
149 sT +=
150 (sample_size - min(length(vec2(-sample_size + x, -sample_size + y)), sample_size)) *
151 float(texture(sampler, TexCoords + vec2((-sample_size + x) * pixel_size.x, (-sample_size + y) * pixel_size.y)).r);
152 }
153 }
154
155 return float(max(min(sT, 1U) - texture(sampler, TexCoords).r, 0U));
156 }
157
158 void main()
159 {
160 //vec4 s_background = texture(tex_background, TexCoords);
161 vec4 final = vec4(0,0,0,0);
162
163 vec4 s_position = texture(gbuffer_position, TexCoords);
164 vec4 s_modulate_1_5 = texture(tex_modulate, TexCoords * 1.5);
165 vec4 s_modulate = texture(tex_modulate, TexCoords);
166 vec4 s_position_clean = texture(gbuffer_clean_position, TexCoords);
167 float htest = remap(s_position.y, bounds_SEL.y, bounds_NWU.y, 0, 1);
168
169 uint s_um_playspace = texture(umask_playspace, TexCoords).r;
170
171 float m_playspace_clean = float(((s_um_playspace >> 0) & 0x1U));
172
173 float m_objectives = float(texture(umask_objectives, TexCoords).r);
174 float m_buyzones = float(texture(umask_buyzone, TexCoords).r);
175 uint s_info = texture(gbuffer_info, TexCoords).r;
176 float m_playspace = float(((s_um_playspace >> 0) & 0x1U) | ((s_info >> 1) & 0x1U));
177
178 final = blend_normal(final,
179 sample_gradient(
180 lerp(s_position_clean.y, s_position.y, clamp((1 - s_modulate.r) + (float((s_info >> 1) & 0x1U) - m_playspace_clean), 0, 1))
181 ), m_playspace);
182
183 final = blend_normal(final, color_cover, float((s_info >> 7) & 0x1U) * m_playspace);
184 final = blend_normal(final, color_cover * vec4(0.4, 0.4, 0.4, 1.0), float((s_info >> 7) & 0x1U) * m_playspace * (1 - ((s_position.y - s_position_clean.y) / 256)));
185
186 vec4 s_normal = texture(gbuffer_normal, TexCoords);
187 vec3 randVec = texture(ssaoRotations, TexCoords * noiseScale).rgb;
188
189 vec3 tangent = normalize(randVec - s_normal.rgb * dot(randVec, s_normal.rgb));
190 vec3 bitangent = cross(s_normal.rgb, tangent);
191 mat3 TBN = mat3(tangent, bitangent, s_normal.rgb);
192
193 float occlusion = 0.0;
194 for(int i = 0; i < 256; i++)
195 {
196 vec3 sample = TBN * samples[i];
197 sample = s_position.xyz + sample * ssaoScale;
198
199 vec4 offset = vec4(sample, 1.0);
200 offset = projection * view * offset;
201 offset.xyz /= offset.w;
202 offset.xyz = offset.xyz * 0.5 + 0.5;
203
204 float sDepth = texture(gbuffer_position, offset.xy).y;
205
206 occlusion += (sDepth >= sample.y + 10.0 ? 1.0 : 0.0);
207 }
208
209 final = blend_normal(final, vec4(0,0,0,1), (occlusion / 200) * m_playspace);
210
211
212 final = blend_normal(final, color_objective, // Objectives
213 (
214 (kernel_filter_glow(umask_objectives, 13, 1))
215 * m_objectives
216 * ( 1 - float((s_info >> 7) & 0x1U))
217 )
218 +
219 (
220 kernel_filter_outline(umask_objectives, 2) * 0.9
221 * ( 1 - float((s_info >> 7) & 0x1U)) * s_modulate_1_5.r
222 )
223 +
224 (
225 (kernel_filter_glow(umask_objectives, 13, 0))
226 * ( 1 - m_objectives )
227 * ( 1 - float((s_info >> 7) & 0x1U))
228 )
229 );
230
231 final = blend_normal(final, color_buyzone, // Objectives
232 (
233 (kernel_filter_glow(umask_buyzone, 13, 1))
234 * m_buyzones
235 * ( 1 - float((s_info >> 7) & 0x1U))
236 )
237 +
238 (
239 kernel_filter_outline(umask_buyzone, 2) * 0.9
240 * ( 1 - float((s_info >> 7) & 0x1U))
241 )
242 +
243 (
244 (kernel_filter_glow(umask_buyzone, 13, 0))
245 * ( 1 - m_buyzones )
246 * ( 1 - float((s_info >> 7) & 0x1U))
247 )
248 );
249
250 FragColor = final;
251 }