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