109 lines
3.8 KiB
Text
109 lines
3.8 KiB
Text
include "pipelines/common.glsl"
|
|
|
|
common [[
|
|
layout(std140, binding = 4) uniform Drawcall {
|
|
uniform vec4 u_offset_scale;
|
|
};
|
|
]]
|
|
|
|
vertex_shader [[
|
|
layout (location = 0) out vec2 v_uv;
|
|
void main() {
|
|
vec4 pos = fullscreenQuad(gl_VertexID, v_uv);
|
|
pos.xy = pos.xy * u_offset_scale.zw + u_offset_scale.xy;
|
|
pos.y = -pos.y;
|
|
gl_Position = pos;
|
|
}
|
|
]]
|
|
|
|
|
|
fragment_shader [[
|
|
// arrow from https://www.shadertoy.com/view/4s23DG
|
|
const int ARROW_V_STYLE = 1;
|
|
const int ARROW_LINE_STYLE = 2;
|
|
|
|
// Choose your arrow head style
|
|
const int ARROW_STYLE = ARROW_LINE_STYLE;
|
|
const float ARROW_TILE_SIZE = 32.0;
|
|
|
|
// How sharp should the arrow head be? Used
|
|
const float ARROW_HEAD_ANGLE = 45.0 * M_PI / 180.0;
|
|
|
|
// Used for ARROW_LINE_STYLE
|
|
const float ARROW_HEAD_LENGTH = ARROW_TILE_SIZE / 6.0;
|
|
const float ARROW_SHAFT_THICKNESS = 3.0;
|
|
|
|
// Computes the center pixel of the tile containing pixel pos
|
|
vec2 arrowTileCenterCoord(vec2 pos) {
|
|
return (floor(pos / ARROW_TILE_SIZE) + 0.5) * ARROW_TILE_SIZE;
|
|
}
|
|
|
|
float arrow(vec2 p, vec2 v) {
|
|
// Make everything relative to the center, which may be fractional
|
|
p -= arrowTileCenterCoord(p);
|
|
|
|
float mag_v = length(v), mag_p = length(p);
|
|
|
|
if (mag_v > 0.0) {
|
|
// Non-zero velocity case
|
|
vec2 dir_p = p / mag_p, dir_v = v / mag_v;
|
|
|
|
// We can't draw arrows larger than the tile radius, so clamp magnitude.
|
|
// Enforce a minimum length to help see direction
|
|
mag_v = clamp(mag_v, 5.0, ARROW_TILE_SIZE / 2.0);
|
|
|
|
// Arrow tip location
|
|
v = dir_v * mag_v;
|
|
|
|
// Define a 2D implicit surface so that the arrow is antialiased.
|
|
// In each line, the left expression defines a shape and the right controls
|
|
// how quickly it fades in or out.
|
|
|
|
float dist;
|
|
if (ARROW_STYLE == ARROW_LINE_STYLE) {
|
|
// Signed distance from a line segment based on https://www.shadertoy.com/view/ls2GWG by
|
|
// Matthias Reitinger, @mreitinger
|
|
|
|
// Line arrow style
|
|
dist =
|
|
max(
|
|
// Shaft
|
|
ARROW_SHAFT_THICKNESS / 4.0 -
|
|
max(abs(dot(p, vec2(dir_v.y, -dir_v.x))), // Width
|
|
abs(dot(p, dir_v)) - mag_v + ARROW_HEAD_LENGTH / 2.0), // Length
|
|
|
|
// Arrow head
|
|
min(0.0, dot(v - p, dir_v) - cos(ARROW_HEAD_ANGLE / 2.0) * length(v - p)) * 2.0 + // Front sides
|
|
min(0.0, dot(p, dir_v) + ARROW_HEAD_LENGTH - mag_v)); // Back
|
|
} else {
|
|
// V arrow style
|
|
dist = min(0.0, mag_v - mag_p) * 2.0 + // length
|
|
min(0.0, dot(normalize(v - p), dir_v) - cos(ARROW_HEAD_ANGLE / 2.0)) * 2.0 * length(v - p) + // head sides
|
|
min(0.0, dot(p, dir_v) + 1.0) + // head back
|
|
min(0.0, cos(ARROW_HEAD_ANGLE / 2.0) - dot(normalize(v * 0.33 - p), dir_v)) * mag_v * 0.8; // cutout
|
|
}
|
|
|
|
return clamp(1.0 + dist, 0.0, 1.0);
|
|
} else {
|
|
// Center of the pixel is always on the arrow
|
|
return max(0.0, 1.2 - mag_p);
|
|
}
|
|
}
|
|
|
|
layout (binding=0) uniform sampler2D u_texture;
|
|
layout (location = 0) in vec2 v_uv;
|
|
layout (location = 0) out vec4 o_color;
|
|
|
|
void main() {
|
|
#ifdef ORIGIN_BOTTOM_LEFT
|
|
vec2 uv = v_uv;
|
|
#else
|
|
vec2 uv = vec2(v_uv.x, 1 - v_uv.y);
|
|
#endif
|
|
vec4 t = textureLod(u_texture, uv, 0) * 2 - 1;
|
|
float tt = arrow(gl_FragCoord.xy, (t.xy) * 10000);
|
|
|
|
o_color = vec4(t.rg * 100, 1 - tt, 1);
|
|
}
|
|
]]
|
|
|