/* quad vertex shader */ @vs vs 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 /* quad fragment shader */ @fs fs 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 /* quad shader program */ @program quad vs fs @vs vs_shadow 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; }; layout(binding=1) uniform Light { vec2 light_pos; }; in vec2 inst_pos; in ivec2 inst_size; out vec2 uv; 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 = indices[gl_VertexIndex]; vec2 pos = positions[idx]; uv = uvs[idx]; if (idx == 2 || idx == 3) { // keep pos for lower vertices (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), }; vec2 inst_pos_abs = anchor_abs + dir + left_right[idx] / 2; 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; out vec4 frag_color; void main() { vec4 tex_color = texture(sampler2D(tex, smp), uv); // if (tex_color.a < 1) // discard; frag_color = vec4(0, 0, 0, 1); } @end @program shadow vs_shadow fs_shadow @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; }; in vec2 light_pos; void main() { int idx = indices[gl_VertexIndex]; vec2 pos = positions[idx]; vec2 light_size = vec2(10, 10); vec2 inst_pos_abs = light_pos + light_size * pos - cam - screen / 2; gl_Position = vec4(inst_pos_abs / screen * 2, 1, 1); } @end @fs fs_light out vec4 frag_color; void main() { frag_color = vec4(1, 0, 0, 1); } @end @program light vs_light fs_light