3 // ____________________________________________________________________________________________
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)
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;
26 uniform vec3 samples[256];
27 uniform sampler2D ssaoRotations;
28 uniform float ssaoScale;
29 uniform mat4 projection;
32 const vec2 noiseScale = vec2(1024.0/256.0, 1024.0/256.0);
34 uniform vec4 color_objective;
35 uniform vec4 color_buyzone;
36 uniform vec4 color_cover;
37 uniform vec4 color_cover2;
40 // ____________________________________________________________________________________________
41 // --------------------------------------- Blend modes ----------------------------------------
43 float lerp(float a, float b, float w)
48 vec3 lerp(vec3 a, vec3 b, float w)
53 vec4 blend_normal(vec4 a, vec4 b, float s)
55 return vec4(lerp(a.rgb, b.rgb, b.a * s), a.a + (b.a * s));
58 vec4 blend_add(vec4 a, vec4 b, float s)
60 return vec4(a.rgb + (b.rgb * s), a.a);
63 // ------------------------------------------ maths -------------------------------------------
64 float remap(float value, float low1, float high1, float low2, float high2)
66 return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
70 // ____________________________________________________________________________________________
71 // ( Write all your shader code & functions here )
73 vec4 sample_gradient(float height)
75 return vec4(texture(tex_gradient, vec2(remap(height, bounds_SEL.y, bounds_NWU.y, 0, 1), 0)));
78 float kernel_filter_glow(sampler2D sampler, int channelID, int sample_size, int inverse)
80 vec2 pixel_size = 1.0 / vec2(textureSize(sampler, 0));
83 int sample_double = sample_size * 2;
86 for(int x = 0; x <= sample_double; x++){
87 for(int y = 0; y <= sample_double; y++){
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];
94 sT /= (sample_double * sample_double);
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)
102 vec2 pixel_size = 1.0 / vec2(textureSize(sampler, 0));
105 int sample_double = sample_size * 2;
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];
116 return max(min(sT, 1) - texture(sampler, TexCoords)[channelID], 0);
119 float kernel_filter_glow(usampler2D sampler, int sample_size, int inverse)
121 vec2 pixel_size = 1.0 / vec2(textureSize(sampler, 0));
124 int sample_double = sample_size * 2;
127 for(int x = 0; x <= sample_double; x++){
128 for(int y = 0; y <= sample_double; y++){
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;
134 float r = float(sT) / (sample_double * sample_double);
138 // Given a 0-1 mask, return an outline drawn around that mask
139 float kernel_filter_outline(usampler2D sampler, int sample_size)
141 vec2 pixel_size = 1.0 / vec2(textureSize(sampler, 0));
144 int sample_double = sample_size * 2;
147 for(int x = 0; x <= sample_double; x++){
148 for(int y = 0; y <= sample_double; y++){
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);
155 return float(max(min(sT, 1U) - texture(sampler, TexCoords).r, 0U));
160 //vec4 s_background = texture(tex_background, TexCoords);
161 vec4 final = vec4(0,0,0,0);
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);
169 uint s_um_playspace = texture(umask_playspace, TexCoords).r;
171 float m_playspace_clean = float(((s_um_playspace >> 0) & 0x1U));
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));
178 final = blend_normal(final,
180 lerp(s_position_clean.y, s_position.y, clamp((1 - s_modulate.r) + (float((s_info >> 1) & 0x1U) - m_playspace_clean), 0, 1))
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)));
186 vec4 s_normal = texture(gbuffer_normal, TexCoords);
187 vec3 randVec = texture(ssaoRotations, TexCoords * noiseScale).rgb;
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);
193 float occlusion = 0.0;
194 for(int i = 0; i < 256; i++)
196 vec3 sample = TBN * samples[i];
197 sample = s_position.xyz + sample * ssaoScale;
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;
204 float sDepth = texture(gbuffer_position, offset.xy).y;
206 occlusion += (sDepth >= sample.y + 10.0 ? 1.0 : 0.0);
209 final = blend_normal(final, vec4(0,0,0,1), (occlusion / 200) * m_playspace);
212 final = blend_normal(final, color_objective, // Objectives
214 (kernel_filter_glow(umask_objectives, 13, 1))
216 * ( 1 - float((s_info >> 7) & 0x1U))
220 kernel_filter_outline(umask_objectives, 2) * 0.9
221 * ( 1 - float((s_info >> 7) & 0x1U)) * s_modulate_1_5.r
225 (kernel_filter_glow(umask_objectives, 13, 0))
226 * ( 1 - m_objectives )
227 * ( 1 - float((s_info >> 7) & 0x1U))
231 final = blend_normal(final, color_buyzone, // Objectives
233 (kernel_filter_glow(umask_buyzone, 13, 1))
235 * ( 1 - float((s_info >> 7) & 0x1U))
239 kernel_filter_outline(umask_buyzone, 2) * 0.9
240 * ( 1 - float((s_info >> 7) & 0x1U))
244 (kernel_filter_glow(umask_buyzone, 13, 0))
246 * ( 1 - float((s_info >> 7) & 0x1U))