]> gitweb.ps.run Git - sporegirl/blobdiff - shd/main.glsl
changezzz
[sporegirl] / shd / main.glsl
diff --git a/shd/main.glsl b/shd/main.glsl
new file mode 100644 (file)
index 0000000..c6ec364
--- /dev/null
@@ -0,0 +1,301 @@
+// === combine ===
+@vs vs_combine
+const vec2 positions[4] = { vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1) };
+const vec2 uvs[4] = { vec2(0, 1), vec2(1, 1), vec2(1, 0), vec2(0, 0) };
+const int indices[6] = { 0, 1, 2, 0, 2, 3 };
+
+layout(binding=0) uniform Game
+{
+    vec2 screen;
+    vec2 cam;
+};
+
+out vec2 uv;
+
+void main() {
+    int idx = indices[gl_VertexIndex];
+    vec2 pos = positions[idx];
+    uv = uvs[idx];
+
+    gl_Position = vec4(pos, 1, 1);
+}
+@end
+
+@fs fs_combine
+layout(binding=0) uniform texture2D tex_tex;
+layout(binding=1) uniform texture2D tex_shadow;
+layout(binding=2) uniform texture2D tex_light;
+layout(binding=0) uniform sampler smp;
+
+in vec2 uv;
+out vec4 frag_color;
+
+
+void main() {
+    vec4 tb = vec4(0.8,0.3,0.3,1);
+    if (mod(floor(uv.x*10), 2) != mod(floor(uv.y*10),2)) {
+        tb = vec4(0.3,0.3,0.8,1);
+    }
+    vec4 tt = texture(sampler2D(tex_tex, smp), uv);
+    vec4 ts = texture(sampler2D(tex_shadow, smp), uv);
+    vec4 tl = texture(sampler2D(tex_light, smp), uv);
+    
+    vec3 l = tt.a * (tt.rgb * tl.rgb) + (1-tt.a) * (tl.rgb * tl.a);
+    l = ts.a * (l * ts.rgb) + (1-ts.a) * (l);
+    frag_color = vec4(l, 1);
+
+    vec3 a = (tb.rgb + tl.rgb) * tt.rgb * ts.rgb; // + tl.rgb * tl.a;
+    frag_color = vec4(a, 1);
+
+
+    vec3 bg = tb.rgb * tl.rgb;
+    vec3 bg_s = bg * (1-ts.a) + bg * ts.rgb * 0.5 * ts.a;
+    vec3 t = tt.rgb * tl.rgb;
+    vec3 t_s = t * (1-ts.a) + t * ts.rgb * 0.5 * ts.a;
+    vec3 bg_s_t_s = bg_s * (1-tt.a) + t_s * tt.a;
+    frag_color = vec4(bg_s_t_s, 1);
+
+    // frag_color = vec4(tl);
+}
+@end
+
+@program combine vs_combine fs_combine
+
+
+// === tex ===
+@vs vs_tex
+const vec2 positions[4] = { vec2(0, 1), vec2(1, 1), vec2(1, 0), vec2(0, 0) };
+const vec2 uvs[4] = { vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1) };
+const int indices[6] = { 0, 1, 2, 0, 2, 3 };
+
+layout(binding=0) uniform Game
+{
+    vec2 screen;
+    vec2 cam;
+};
+
+in vec2 inst_pos;
+in ivec2 inst_size;
+out vec2 uv;
+
+void main() {
+    int idx = indices[gl_VertexIndex];
+    vec2 pos = positions[idx];
+    uv = uvs[idx];
+
+    vec2 inst_pos_abs = inst_pos + inst_size * pos - cam - screen / 2;
+    gl_Position = vec4(inst_pos_abs / screen * 2, 1, 1);
+}
+@end
+
+@fs fs_tex
+layout(binding=0) uniform texture2D tex;
+layout(binding=0) uniform sampler smp;
+
+in vec2 uv;
+out vec4 frag_color;
+
+void main() {
+    vec4 tex_color = texture(sampler2D(tex, smp), uv);
+    if (tex_color.a < 1)
+        discard;
+    frag_color = tex_color;
+}
+@end
+
+@program tex vs_tex fs_tex
+
+
+// === shadows ===
+@vs vs_shadow
+const vec2 positions[3] = { vec2(0, 1), vec2(1, 1), vec2(0.5, 0) };
+const vec2 uvs[3] = { vec2(0, 0), vec2(1, 0), vec2(0.5, 1) };
+
+layout(binding=0) uniform Game
+{
+    vec2 screen;
+    vec2 cam;
+};
+
+layout(binding=1) uniform Light
+{
+    vec3 color;
+    vec2 pos;
+    float reach;
+    float radius_glow;
+    float intensity;
+    float shadow_brightness;
+} light;
+
+in vec2 inst_pos;
+in ivec2 inst_size;
+out vec2 uv;
+out vec3 light_color;
+out float shadow_brightness;
+
+// https://gist.github.com/yiwenl/3f804e80d0930e34a0b33359259b556c
+vec2 rotate(vec2 v, float a) {
+       float s = sin(a);
+       float c = cos(a);
+       mat2 m = mat2(c, s, -s, c);
+       return m * v;
+}
+
+void main() {
+    int idx = gl_VertexIndex;
+    vec2 pos = positions[idx];
+    uv = uvs[idx];
+    light_color = light.color;
+    shadow_brightness = light.shadow_brightness;
+
+    if (idx == 2) { // keep pos for base
+        vec2 inst_pos_abs = inst_pos + inst_size * pos - cam - screen / 2;
+        gl_Position = vec4(inst_pos_abs / screen * 2, 1, 1);
+    }
+    else {
+        vec2 anchor = vec2(0.5, 0);
+        vec2 anchor_abs = inst_pos + inst_size * anchor - cam - screen / 2;
+        vec2 light_pos_abs = light.pos - cam - screen / 2;
+        vec2 dir = anchor_abs - light_pos_abs;
+
+        vec2 left_right[] = {
+            rotate(dir, 1.5708),
+            rotate(dir, -1.5708),
+        };
+
+        float light_radius_factor = 1.5 / log(light.reach);
+
+        vec2 inst_pos_abs = anchor_abs + dir + left_right[idx] * light_radius_factor;
+        gl_Position = vec4(inst_pos_abs / screen * 2, 1, 1);
+    }
+}
+@end
+
+@fs fs_shadow
+layout(binding=0) uniform texture2D tex;
+layout(binding=0) uniform sampler smp;
+
+in vec2 uv;
+in vec3 light_color;
+in float shadow_brightness;
+out vec4 frag_color;
+
+vec3 brighten(vec3 c, float f) {
+    vec3 d = vec3(1) - c;
+    return c + d * f;
+}
+
+vec4 blur(float radius, float resolution) {
+    float blur = radius/resolution; 
+    
+    float hstep = 1;
+    float vstep = 1;
+    
+    vec4 sum = vec4(0.0);
+    
+    sum += texture(sampler2D(tex, smp), vec2(uv.x - 4.0*blur*hstep, uv.y - 4.0*blur*vstep)) * 0.0162162162;
+    sum += texture(sampler2D(tex, smp), vec2(uv.x - 3.0*blur*hstep, uv.y - 3.0*blur*vstep)) * 0.0540540541;
+    sum += texture(sampler2D(tex, smp), vec2(uv.x - 2.0*blur*hstep, uv.y - 2.0*blur*vstep)) * 0.1216216216;
+    sum += texture(sampler2D(tex, smp), vec2(uv.x - 1.0*blur*hstep, uv.y - 1.0*blur*vstep)) * 0.1945945946;
+    
+    sum += texture(sampler2D(tex, smp), vec2(uv.x, uv.y)) * 0.2270270270;
+    
+    sum += texture(sampler2D(tex, smp), vec2(uv.x + 1.0*blur*hstep, uv.y + 1.0*blur*vstep)) * 0.1945945946;
+    sum += texture(sampler2D(tex, smp), vec2(uv.x + 2.0*blur*hstep, uv.y + 2.0*blur*vstep)) * 0.1216216216;
+    sum += texture(sampler2D(tex, smp), vec2(uv.x + 3.0*blur*hstep, uv.y + 3.0*blur*vstep)) * 0.0540540541;
+    sum += texture(sampler2D(tex, smp), vec2(uv.x + 4.0*blur*hstep, uv.y + 4.0*blur*vstep)) * 0.0162162162;
+
+    return sum;
+}
+
+void main() {
+    vec4 tex_color = blur(10, 1);
+    tex_color = texture(sampler2D(tex, smp), uv);
+    
+    vec3 brighter = brighten(light_color, shadow_brightness);
+    frag_color = vec4(brighter * tex_color.a + vec3(1) * (1-tex_color.a), tex_color.a);
+}
+@end
+
+@program shadow vs_shadow fs_shadow
+
+
+// === lights ===
+@vs vs_light
+const vec2 positions[4] = { vec2(-0.5, 0.5), vec2(0.5, 0.5), vec2(0.5, -0.5), vec2(-0.5, -0.5) };
+const int indices[6] = { 0, 1, 2, 0, 2, 3 };
+
+layout(binding=0) uniform Game
+{
+    vec2 screen;
+    vec2 cam;
+};
+
+layout(binding=1) uniform Light
+{
+    vec3 color;
+    vec2 pos;
+    float reach;
+    float radius_glow;
+    float intensity;
+    float shadow_brightness;
+} light;
+
+out vec3 light_col;
+out vec2 light_pos;
+out float light_rea;
+out float light_glo;
+out float light_intensity;
+out vec2 fragpos;
+
+void main() {
+    int idx = indices[gl_VertexIndex];
+    vec2 pos = positions[idx];
+
+    vec2 inst_pos_ap = light.pos + light.reach * 2 * pos;
+    vec2 inst_pos_rp = inst_pos_ap - cam - screen / 2;
+    vec2 inst_pos_rw = inst_pos_rp / screen * 2;
+    gl_Position = vec4(inst_pos_rw, 1, 1);
+
+    light_col = light.color;
+    light_pos = light.pos;
+    light_rea = light.reach;
+    light_glo = light.radius_glow;
+    light_intensity = light.intensity;
+    fragpos = inst_pos_ap;
+}
+@end
+
+@fs fs_light
+layout(binding=0) uniform Game
+{
+    vec2 screen;
+    vec2 cam;
+};
+
+in vec3 light_col;
+in vec2 light_pos;
+in float light_rea;
+in float light_glo;
+in float light_intensity;
+in vec2 fragpos;
+out vec4 frag_color;
+
+float dist(vec2 a, vec2 b) {
+    float d1 = a.x - b.x;
+    float d2 = a.y - b.y;
+    return sqrt(d1*d1 + d2*d2);
+}
+
+void main() {
+    // vec2 frag_coord_abs = gl_FragCoord.xy * v_screen + v_cam + v_screen / 2;
+    // float factor = dist(light_pos, frag_coord_abs) / light_rad;
+    float factor_rea = 1 - (dist(light_pos, fragpos) / light_rea);
+    float factor_glo = 1 - (dist(light_pos, fragpos) / light_glo);
+    if (factor_rea > 1.0) discard;
+    frag_color = vec4(light_col.rgb * factor_rea, factor_glo * light_intensity);
+    // frag_color = vec4(vec3(mod(factor, 1.0)) * light_col, factor);
+}
+@end
+
+@program light vs_light fs_light