Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:58:55 +01:00
parent 4af19165ec
commit 68073add76
12458 changed files with 12350765 additions and 2 deletions

2
libs/shaders/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
gl_shaders.cpp
gl_shaders.hpp

159
libs/shaders/CMakeLists.txt Normal file
View file

@ -0,0 +1,159 @@
project(shaders)
add_library(${PROJECT_NAME})
set(shader_files
GL/area.vsh.glsl
GL/area3d.vsh.glsl
GL/area3d_outline.vsh.glsl
GL/arrow3d.fsh.glsl
GL/arrow3d.vsh.glsl
GL/arrow3d_outline.fsh.glsl
GL/arrow3d_shadow.fsh.glsl
GL/arrow3d_shadow.vsh.glsl
GL/arrow3d_textured.fsh.glsl
GL/arrow3d_textured.vsh.glsl
GL/circle.fsh.glsl
GL/circle.vsh.glsl
GL/circle_point.fsh.glsl
GL/circle_point.vsh.glsl
GL/colored_symbol.fsh.glsl
GL/colored_symbol.vsh.glsl
GL/colored_symbol_billboard.vsh.glsl
GL/dashed_line.fsh.glsl
GL/dashed_line.vsh.glsl
GL/debug_rect.fsh.glsl
GL/debug_rect.vsh.glsl
GL/hatching_area.fsh.glsl
GL/hatching_area.vsh.glsl
GL/imgui.fsh.glsl
GL/imgui.vsh.glsl
GL/line.fsh.glsl
GL/line.vsh.glsl
GL/masked_texturing.fsh.glsl
GL/masked_texturing.vsh.glsl
GL/masked_texturing_billboard.vsh.glsl
GL/my_position.vsh.glsl
GL/path_symbol.vsh.glsl
GL/position_accuracy3d.vsh.glsl
GL/route.fsh.glsl
GL/route.vsh.glsl
GL/route_arrow.fsh.glsl
GL/route_arrow.vsh.glsl
GL/route_dash.fsh.glsl
GL/route_marker.fsh.glsl
GL/route_marker.vsh.glsl
GL/ruler.fsh.glsl
GL/ruler.vsh.glsl
GL/screen_quad.fsh.glsl
GL/screen_quad.vsh.glsl
GL/selection_line.fsh.glsl
GL/selection_line.vsh.glsl
GL/shaders_lib.glsl
GL/smaa_blending_weight.fsh.glsl
GL/smaa_blending_weight.vsh.glsl
GL/smaa_edges.fsh.glsl
GL/smaa_edges.vsh.glsl
GL/smaa_final.fsh.glsl
GL/smaa_final.vsh.glsl
GL/solid_color.fsh.glsl
GL/text.fsh.glsl
GL/text.vsh.glsl
GL/text_billboard.vsh.glsl
GL/text_outlined.vsh.glsl
GL/text_outlined_billboard.vsh.glsl
GL/text_outlined_gui.fsh.glsl
GL/text_outlined_gui.vsh.glsl
GL/texturing.fsh.glsl
GL/texturing.vsh.glsl
GL/texturing3d.fsh.glsl
GL/texturing_billboard.vsh.glsl
GL/texturing_gui.fsh.glsl
GL/texturing_gui.vsh.glsl
GL/texturing_position.fsh.glsl
GL/traffic.fsh.glsl
GL/traffic.vsh.glsl
GL/traffic_circle.fsh.glsl
GL/traffic_circle.vsh.glsl
GL/traffic_line.fsh.glsl
GL/traffic_line.vsh.glsl
GL/transit.fsh.glsl
GL/transit.vsh.glsl
GL/transit_circle.fsh.glsl
GL/transit_circle.vsh.glsl
GL/transit_marker.fsh.glsl
GL/transit_marker.vsh.glsl
GL/user_mark.fsh.glsl
GL/user_mark.vsh.glsl
GL/user_mark_billboard.vsh.glsl
)
add_custom_command(
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS
gl_shaders_preprocessor.py
${shader_files}
GL/shader_index.txt
programs.hpp
COMMAND
${Python3_EXECUTABLE}
ARGS
gl_shaders_preprocessor.py
GL/
shader_index.txt
programs.hpp
shaders_lib.glsl
./
gl_shaders
OUTPUT
${CMAKE_CURRENT_SOURCE_DIR}/gl_shaders.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_shaders.hpp
)
source_group("Shader Index" FILES GL/shader_index.txt)
target_sources(${PROJECT_NAME}
PRIVATE
${shader_files}
gl_program_info.hpp
gl_program_params.cpp
gl_program_params.hpp
gl_program_pool.cpp
gl_program_pool.hpp
gl_shaders.cpp
gl_shaders.hpp
program_manager.cpp
program_manager.hpp
program_params.cpp
program_params.hpp
program_pool.hpp
programs.hpp
GL/shader_index.txt
vulkan_program_params.cpp
vulkan_program_params.hpp
vulkan_program_pool.cpp
vulkan_program_pool.hpp
)
if (PLATFORM_IPHONE OR PLATFORM_MAC)
target_sources(${PROJECT_NAME}
PRIVATE
metal_program_params.hpp
metal_program_params.mm
metal_program_pool.hpp
metal_program_pool.mm
program_manager_metal.mm
)
endif()
# Do not include glm's CMakeLists.txt, because it's outdated and not necessary.
target_include_directories(${PROJECT_NAME} PUBLIC "${OMIM_ROOT}/3party/glm")
target_link_libraries(${PROJECT_NAME} drape)
if (PLATFORM_MAC)
set_target_properties(${PROJECT_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
endif()
omim_add_test_subdirectory(shaders_tests)

View file

@ -0,0 +1,35 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_colorTexCoords;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoords;
#endif
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
{
vec4 pos = vec4(a_position, 1) * u_modelView * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, a_colorTexCoords);
#else
v_colorTexCoords = a_colorTexCoords;
#endif
}

View file

@ -0,0 +1,40 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (location = 1) out float v_intensity;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
const vec4 kNormalizedLightDir = vec4(0.3162, 0.0, 0.9486, 0.0);
void main()
{
vec4 pos = vec4(a_position, 1.0) * u_modelView;
vec4 normal = vec4(a_position + a_normal, 1.0) * u_modelView;
normal.xyw = (normal * u_projection).xyw;
normal.z = normal.z * u_zScale;
pos.xyw = (pos * u_projection).xyw;
pos.z = a_position.z * u_zScale;
vec4 normDir = normal - pos;
if (dot(normDir, normDir) != 0.0)
v_intensity = max(0.0, -dot(kNormalizedLightDir, normalize(normDir)));
else
v_intensity = 0.0;
gl_Position = u_pivotTransform * pos;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
v_colorTexCoords = a_colorTexCoords;
}

View file

@ -0,0 +1,41 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_colorTexCoords;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoords;
#endif
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
{
vec4 pos = vec4(a_position, 1.0) * u_modelView;
pos.xyw = (pos * u_projection).xyw;
pos.z = a_position.z * u_zScale;
gl_Position = u_pivotTransform * pos;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, a_colorTexCoords);
#else
v_colorTexCoords = a_colorTexCoords;
#endif
}

View file

@ -0,0 +1,19 @@
layout (location = 0) in vec3 v_normal;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
const vec3 lightDir = vec3(0.316, 0.0, 0.948);
void main()
{
float phongDiffuse = max(0.0, -dot(lightDir, v_normal));
v_FragColor = vec4((phongDiffuse * 0.5 + 0.5) * u_color.rgb, u_color.a);
}

View file

@ -0,0 +1,23 @@
layout (location = 0) in vec3 a_pos;
layout (location = 1) in vec3 a_normal;
layout (location = 0) out vec3 v_normal;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
void main()
{
vec4 position = u_transform * vec4(a_pos, 1.0);
v_normal = normalize((u_normalTransform * vec4(a_normal, 0.0)).xyz);
gl_Position = position;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
}

View file

@ -0,0 +1,16 @@
layout (location = 0) in float v_intensity;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
void main()
{
v_FragColor = vec4(u_color.rgb, u_color.a * smoothstep(0.7, 1.0, v_intensity));
}

View file

@ -0,0 +1,16 @@
layout (location = 0) in float v_intensity;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
void main()
{
v_FragColor = vec4(u_color.rgb, u_color.a * v_intensity);
}

View file

@ -0,0 +1,23 @@
layout (location = 0) in vec3 a_pos;
layout (location = 1) in vec2 a_texCoords;
layout (location = 0) out float v_intensity;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
void main()
{
vec4 position = u_transform * vec4(a_pos, 1.0);
v_intensity = a_texCoords.x;
gl_Position = position;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
}

View file

@ -0,0 +1,23 @@
layout (location = 0) in vec3 v_normal;
layout (location = 1) in vec2 v_texCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
layout (binding = 1) uniform sampler2D u_colorTex;
const vec3 lightDir = vec3(0.316, 0.0, 0.948);
void main()
{
float phongDiffuse = max(0.0, -dot(lightDir, v_normal));
vec4 color = texture(u_colorTex, v_texCoords) * u_color;
v_FragColor = vec4((phongDiffuse * 0.5 + 0.5) * color.rgb, color.a);
}

View file

@ -0,0 +1,26 @@
layout (location = 0) in vec3 a_pos;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec2 a_texCoords;
layout (location = 0) out vec3 v_normal;
layout (location = 1) out vec2 v_texCoords;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
void main()
{
vec4 position = u_transform * vec4(a_pos, 1.0);
v_normal = normalize((u_normalTransform * vec4(a_normal, 0.0)).xyz);
v_texCoords = mix(a_texCoords, 1.0 - a_texCoords, u_texCoordFlipping);
gl_Position = position;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
}

View file

@ -0,0 +1,37 @@
#ifdef ENABLE_VTF
layout (location = 0) in LOW_P vec4 v_color;
#else
layout (location = 1) in vec2 v_colorTexCoords;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
layout (location = 2) in vec3 v_radius;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
const float aaPixelsCount = 2.5;
void main()
{
#ifdef ENABLE_VTF
LOW_P vec4 finalColor = v_color;
#else
LOW_P vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
#endif
float smallRadius = v_radius.z - aaPixelsCount;
float stepValue = smoothstep(smallRadius * smallRadius, v_radius.z * v_radius.z,
v_radius.x * v_radius.x + v_radius.y * v_radius.y);
finalColor.a = finalColor.a * u_opacity * (1.0 - stepValue);
v_FragColor = finalColor;
}

View file

@ -0,0 +1,39 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoords;
#endif
layout (location = 2) out vec3 v_radius;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
{
vec4 p = vec4(a_position, 1) * u_modelView;
vec4 pos = vec4(a_normal.xy, 0, 0) + p;
gl_Position = applyPivotTransform(pos * u_projection, u_pivotTransform, 0.0);
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, a_colorTexCoords);
#else
v_colorTexCoords = a_colorTexCoords;
#endif
v_radius = a_normal;
}

View file

@ -0,0 +1,28 @@
layout (location = 0) in vec3 v_radius;
layout (location = 1) in vec4 v_color;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
const float kAntialiasingScalar = 0.9;
void main()
{
float d = dot(v_radius.xy, v_radius.xy);
vec4 finalColor = v_color;
float aaRadius = v_radius.z * kAntialiasingScalar;
float stepValue = smoothstep(aaRadius * aaRadius, v_radius.z * v_radius.z, d);
finalColor.a = finalColor.a * u_opacity * (1.0 - stepValue);
v_FragColor = finalColor;
}

View file

@ -0,0 +1,28 @@
layout (location = 0) in vec3 a_normal;
layout (location = 1) in vec3 a_position;
layout (location = 2) in vec4 a_color;
layout (location = 0) out vec3 v_radius;
layout (location = 1) out vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
vec3 radius = a_normal * a_position.z;
vec4 pos = vec4(a_position.xy, 0, 1) * u_modelView;
vec4 shiftedPos = vec4(radius.xy, 0, 0) + pos;
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
v_radius = radius;
v_color = a_color;
}

View file

@ -0,0 +1,41 @@
layout (location = 0) in vec4 v_normal;
#ifdef ENABLE_VTF
layout (location = 1) in LOW_P vec4 v_color;
#else
layout (location = 2) in vec2 v_colorTexCoords;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
const float aaPixelsCount = 2.5;
void main()
{
#ifdef ENABLE_VTF
LOW_P vec4 color = v_color;
#else
LOW_P vec4 color = texture(u_colorTex, v_colorTexCoords);
#endif
float r1 = (v_normal.z - aaPixelsCount) * (v_normal.z - aaPixelsCount);
float r2 = v_normal.x * v_normal.x + v_normal.y * v_normal.y;
float r3 = v_normal.z * v_normal.z;
float alpha = mix(step(r3, r2), smoothstep(r1, r3, r2), v_normal.w);
LOW_P vec4 finalColor = color;
finalColor.a = finalColor.a * u_opacity * (1.0 - alpha);
if (finalColor.a == 0.0)
discard;
v_FragColor = finalColor;
}

View file

@ -0,0 +1,39 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec4 a_normal;
layout (location = 2) in vec4 a_colorTexCoords;
layout (location = 0) out vec4 v_normal;
#ifdef ENABLE_VTF
layout (location = 1) out LOW_P vec4 v_color;
#else
layout (location = 2) out vec2 v_colorTexCoords;
#endif
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
{
vec4 p = vec4(a_position, 1) * u_modelView;
vec4 pos = vec4(a_normal.xy + a_colorTexCoords.zw, 0, 0) + p;
gl_Position = applyPivotTransform(pos * u_projection, u_pivotTransform, 0.0);
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, a_colorTexCoords.xy);
#else
v_colorTexCoords = a_colorTexCoords.xy;
#endif
v_normal = a_normal;
}

View file

@ -0,0 +1,39 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec4 a_normal;
layout (location = 2) in vec4 a_colorTexCoords;
layout (location = 0) out vec4 v_normal;
#ifdef ENABLE_VTF
layout (location = 1) out LOW_P vec4 v_color;
#else
layout (location = 2) out vec2 v_colorTexCoords;
#endif
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
{
vec4 pivot = vec4(a_position.xyz, 1.0) * u_modelView;
vec4 offset = vec4(a_normal.xy + a_colorTexCoords.zw, 0.0, 0.0) * u_projection;
gl_Position = applyBillboardPivotTransform(pivot * u_projection, u_pivotTransform, 0.0, offset.xy);
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, a_colorTexCoords.xy);
#else
v_colorTexCoords = a_colorTexCoords.xy;
#endif
v_normal = a_normal;
}

View file

@ -0,0 +1,35 @@
layout (location = 0) in vec2 v_colorTexCoord;
layout (location = 1) in vec2 v_maskTexCoord;
//layout (location = 2) in vec2 v_halfLength;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 1) uniform sampler2D u_colorTex;
layout (binding = 2) uniform sampler2D u_maskTex;
//const float aaPixelsCount = 2.5;
void main()
{
vec4 color = texture(u_colorTex, v_colorTexCoord);
float mask = texture(u_maskTex, v_maskTexCoord).r;
color.a = color.a * mask * u_opacity;
// Disabled too agressive AA-like blurring of edges,
// see https://github.com/organicmaps/organicmaps/issues/6583.
//float currentW = abs(v_halfLength.x);
//float diff = v_halfLength.y - currentW;
//color.a *= mix(0.3, 1.0, clamp(diff / aaPixelsCount, 0.0, 1.0));
v_FragColor = color;
}

View file

@ -0,0 +1,38 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec2 a_colorTexCoord;
layout (location = 3) in vec4 a_maskTexCoord;
layout (location = 0) out vec2 v_colorTexCoord;
layout (location = 1) out vec2 v_maskTexCoord;
//layout (location = 2) out vec2 v_halfLength;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
vec2 normal = a_normal.xy;
float halfWidth = length(normal);
vec2 transformedAxisPos = (vec4(a_position.xy, 0.0, 1.0) * u_modelView).xy;
if (halfWidth != 0.0)
{
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + normal,
u_modelView, halfWidth);
}
float uOffset = min(length(vec4(kShapeCoordScalar, 0, 0, 0) * u_modelView) * a_maskTexCoord.x, 1.0);
v_colorTexCoord = a_colorTexCoord;
v_maskTexCoord = vec2(a_maskTexCoord.y + uOffset * a_maskTexCoord.z, a_maskTexCoord.w);
//v_halfLength = vec2(sign(a_normal.z) * halfWidth, abs(a_normal.z));
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

View file

@ -0,0 +1,11 @@
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
vec4 u_color;
};
void main()
{
v_FragColor = u_color;
}

View file

@ -0,0 +1,10 @@
layout (location = 0) in vec2 a_position;
void main()
{
gl_Position = vec4(a_position, 0, 1);
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
}

View file

@ -0,0 +1,35 @@
#ifdef ENABLE_VTF
layout (location = 0) in LOW_P vec4 v_color;
#else
layout (location = 1) in vec2 v_colorTexCoords;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
layout (location = 2) in vec2 v_maskTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 2) uniform sampler2D u_maskTex;
void main()
{
#ifdef ENABLE_VTF
LOW_P vec4 color = v_color;
#else
LOW_P vec4 color = texture(u_colorTex, v_colorTexCoords);
#endif
color *= texture(u_maskTex, v_maskTexCoords);
color.a *= u_opacity;
v_FragColor = color;
}

View file

@ -0,0 +1,38 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_colorTexCoords;
layout (location = 2) in vec2 a_maskTexCoords;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoords;
#endif
layout (location = 2) out vec2 v_maskTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
{
vec4 pos = vec4(a_position, 1) * u_modelView * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, a_colorTexCoords);
#else
v_colorTexCoords = a_colorTexCoords;
#endif
v_maskTexCoords = a_maskTexCoords;
}

View file

@ -0,0 +1,12 @@
layout (location = 0) in vec2 v_texCoords;
layout (location = 1) in vec4 v_color;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
LOW_P vec4 color = texture(u_colorTex, v_texCoords);
v_FragColor = color * v_color;
}

View file

@ -0,0 +1,22 @@
layout (location = 0) in vec2 a_position;
layout (location = 1) in vec2 a_texCoords;
layout (location = 2) in vec4 a_color;
layout (location = 0) out vec2 v_texCoords;
layout (location = 1) out vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_projection;
};
void main()
{
v_texCoords = a_texCoords;
v_color = a_color;
gl_Position = vec4(a_position, 0, 1) * u_projection;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
}

View file

@ -0,0 +1,39 @@
#ifdef ENABLE_VTF
layout (location = 0) in LOW_P vec4 v_color;
#else
layout (location = 1) in vec2 v_colorTexCoord;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
//layout (location = 2) in vec2 v_halfLength;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
//const float aaPixelsCount = 2.5;
void main()
{
#ifdef ENABLE_VTF
LOW_P vec4 color = v_color;
#else
LOW_P vec4 color = texture(u_colorTex, v_colorTexCoord);
#endif
color.a *= u_opacity;
// Disabled too agressive AA-like blurring of edges,
// see https://github.com/organicmaps/organicmaps/issues/6583.
//float currentW = abs(v_halfLength.x);
//float diff = v_halfLength.y - currentW;
//color.a *= mix(0.3, 1.0, clamp(diff / aaPixelsCount, 0.0, 1.0));
v_FragColor = color;
}

View file

@ -0,0 +1,47 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec2 a_colorTexCoord;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoord;
#endif
//layout (location = 2) out vec2 v_halfLength;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
{
vec2 normal = a_normal.xy;
float halfWidth = length(normal);
vec2 transformedAxisPos = (vec4(a_position.xy, 0.0, 1.0) * u_modelView).xy;
if (halfWidth != 0.0)
{
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + normal,
u_modelView, halfWidth);
}
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, a_colorTexCoord);
#else
v_colorTexCoord = a_colorTexCoord;
#endif
//v_halfLength = vec2(sign(a_normal.z) * halfWidth, abs(a_normal.z));
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

View file

@ -0,0 +1,26 @@
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 1) in vec2 v_maskTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 1) uniform sampler2D u_colorTex;
layout (binding = 2) uniform sampler2D u_maskTex;
void main()
{
vec4 finalColor = texture(u_colorTex, v_colorTexCoords) * texture(u_maskTex, v_maskTexCoords);
finalColor.a *= u_opacity;
v_FragColor = finalColor;
}

View file

@ -0,0 +1,28 @@
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 3) in vec2 a_maskTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (location = 1) out vec2 v_maskTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
vec4 pos = vec4(a_position.xyz, 1) * u_modelView;
vec4 shiftedPos = vec4(a_normal, 0, 0) + pos;
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
v_colorTexCoords = a_colorTexCoords;
v_maskTexCoords = a_maskTexCoords;
}

View file

@ -0,0 +1,29 @@
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 3) in vec2 a_maskTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (location = 1) out vec2 v_maskTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
vec4 pivot = vec4(a_position.xyz, 1.0) * u_modelView;
vec4 offset = vec4(a_normal, 0.0, 0.0) * u_projection;
gl_Position = applyBillboardPivotTransform(pivot * u_projection, u_pivotTransform,
a_position.w * u_zScale, offset.xy);
v_colorTexCoords = a_colorTexCoords;
v_maskTexCoords = a_maskTexCoords;
}

View file

@ -0,0 +1,33 @@
layout (location = 0) in vec2 a_normal;
layout (location = 1) in vec2 a_colorTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_position;
vec2 u_lineParams;
float u_accuracy;
float u_zScale;
float u_opacity;
float u_azimut;
};
void main()
{
float sinV = sin(u_azimut);
float cosV = cos(u_azimut);
mat4 rotation;
rotation[0] = vec4(cosV, sinV, 0.0, 0.0);
rotation[1] = vec4(-sinV, cosV, 0.0, 0.0);
rotation[2] = vec4(0.0, 0.0, 1.0, 0.0);
rotation[3] = vec4(0.0, 0.0, 0.0, 1.0);
vec4 pos = vec4(u_position.xyz, 1.0) * u_modelView;
vec4 normal = vec4(a_normal, 0, 0);
vec4 shiftedPos = normal * rotation + pos;
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
v_colorTexCoords = a_colorTexCoords;
}

View file

@ -0,0 +1,30 @@
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
vec4 pos = vec4(a_position.xyz, 1) * u_modelView;
float normalLen = length(a_normal);
vec4 n = vec4(a_position.xy + a_normal * kShapeCoordScalar, 0.0, 0.0) * u_modelView;
vec4 norm = vec4(0.0, 0.0, 0.0, 0.0);
if (dot(n, n) != 0.0)
norm = normalize(n) * normalLen;
vec4 shiftedPos = norm + pos;
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
v_colorTexCoords = a_colorTexCoords;
}

View file

@ -0,0 +1,26 @@
layout (location = 0) in vec2 a_normal;
layout (location = 1) in vec2 a_colorTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_position;
vec2 u_lineParams;
float u_accuracy;
float u_zScale;
float u_opacity;
float u_azimut;
};
void main()
{
vec4 position = vec4(u_position.xy, 0.0, 1.0) * u_modelView;
vec4 normal = vec4(a_normal * u_accuracy, 0.0, 0.0);
position = (position + normal) * u_projection;
gl_Position = applyPivotTransform(position, u_pivotTransform, u_position.z * u_zScale);
v_colorTexCoords = a_colorTexCoords;
}

View file

@ -0,0 +1,47 @@
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
layout (location = 0) in vec3 v_length;
layout (location = 1) in vec4 v_color;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
const float kAntialiasingThreshold = 0.92;
const float kOutlineThreshold1 = 0.81;
const float kOutlineThreshold2 = 0.71;
void main()
{
if (v_length.x < v_length.z)
discard;
vec2 coefs = step(v_length.xx, u_fakeBorders);
coefs.y = 1.0 - coefs.y;
vec4 mainColor = mix(u_color, u_fakeColor, coefs.x);
mainColor = mix(mainColor, u_fakeColor, coefs.y);
vec4 mainOutlineColor = mix(u_outlineColor, u_fakeOutlineColor, coefs.x);
mainOutlineColor = mix(mainOutlineColor, u_fakeOutlineColor, coefs.y);
vec4 color = mix(mix(mainColor, vec4(v_color.rgb, 1.0), v_color.a), mainColor, step(u_routeParams.w, 0.0));
color = mix(color, mainOutlineColor, step(kOutlineThreshold1, abs(v_length.y)));
color = mix(color, mainOutlineColor, smoothstep(kOutlineThreshold2, kOutlineThreshold1, abs(v_length.y)));
color.a *= (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(v_length.y)));
color = vec4(mix(color.rgb, u_maskColor.rgb, u_maskColor.a), color.a);
v_FragColor = color;
}

View file

@ -0,0 +1,43 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec3 a_length;
layout (location = 3) in vec4 a_color;
layout (location = 0) out vec3 v_length;
layout (location = 1) out vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
void main()
{
vec2 transformedAxisPos = (vec4(a_position.xy, 0.0, 1.0) * u_modelView).xy;
vec2 len = vec2(a_length.x, a_length.z);
if (dot(a_normal, a_normal) != 0.0)
{
vec2 norm = a_normal * u_routeParams.x;
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + norm,
u_modelView, length(norm));
if (u_routeParams.y != 0.0)
len = vec2(a_length.x + a_length.y * u_routeParams.y, a_length.z);
}
v_length = vec3(len, u_routeParams.z);
v_color = a_color;
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

View file

@ -0,0 +1,36 @@
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
finalColor.a *= u_opacity;
if (finalColor.a < 0.01)
discard;
finalColor = vec4(mix(finalColor.rgb, u_maskColor.rgb, u_maskColor.a), finalColor.a);
v_FragColor = finalColor;
}

View file

@ -0,0 +1,37 @@
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
void main()
{
vec2 transformedAxisPos = (vec4(a_position.xy, 0.0, 1.0) * u_modelView).xy;
if (dot(a_normal, a_normal) != 0.0)
{
vec2 norm = a_normal * u_arrowHalfWidth;
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + norm,
u_modelView, length(norm));
}
v_colorTexCoords = a_colorTexCoords;
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

View file

@ -0,0 +1,49 @@
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
layout (location = 0) in vec3 v_length;
layout (location = 1) in vec4 v_color;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
const float kAntialiasingThreshold = 0.92;
float alphaFromPattern(float curLen, float dashLen, float gapLen)
{
float len = dashLen + gapLen;
float offset = fract(curLen / len) * len;
return step(offset, dashLen);
}
void main()
{
if (v_length.x < v_length.z)
discard;
vec2 coefs = step(v_length.xx, u_fakeBorders);
coefs.y = 1.0 - coefs.y;
vec4 mainColor = mix(u_color, u_fakeColor, coefs.x);
mainColor = mix(mainColor, u_fakeColor, coefs.y);
vec4 color = mainColor + v_color;
color.a *= (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(v_length.y))) *
alphaFromPattern(v_length.x, u_pattern.x, u_pattern.y);
color = vec4(mix(color.rgb, u_maskColor.rgb, u_maskColor.a), color.a);
v_FragColor = color;
}

View file

@ -0,0 +1,40 @@
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
layout (location = 0) in vec4 v_radius;
layout (location = 1) in vec4 v_color;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
const float kAntialiasingPixelsCount = 2.5;
void main()
{
vec4 finalColor = v_color;
float aaRadius = max(v_radius.z - kAntialiasingPixelsCount, 0.0);
float stepValue = smoothstep(aaRadius * aaRadius, v_radius.z * v_radius.z,
dot(v_radius.xy, v_radius.xy));
finalColor.a = finalColor.a * u_opacity * (1.0 - stepValue);
if (finalColor.a < 0.01 || u_routeParams.y > v_radius.w)
discard;
finalColor = vec4(mix(finalColor.rgb, u_maskColor.rgb, u_maskColor.a), finalColor.a);
v_FragColor = finalColor;
}

View file

@ -0,0 +1,38 @@
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec4 a_color;
layout (location = 0) out vec4 v_radius;
layout (location = 1) out vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
void main()
{
float r = u_routeParams.x * a_normal.z;
vec2 normal = vec2(a_normal.x * u_angleCosSin.x - a_normal.y * u_angleCosSin.y,
a_normal.x * u_angleCosSin.y + a_normal.y * u_angleCosSin.x);
vec4 radius = vec4(normal.xy * r, r, a_position.w);
vec4 pos = vec4(a_position.xy, 0, 1) * u_modelView;
vec2 shiftedPos = radius.xy + pos.xy;
pos = vec4(shiftedPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
v_radius = radius;
v_color = a_color;
}

View file

@ -0,0 +1,23 @@
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
vec2 u_contrastGamma;
vec2 u_position;
float u_isOutlinePass;
float u_opacity;
float u_length;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
finalColor.a *= u_opacity;
v_FragColor = finalColor;
}

View file

@ -0,0 +1,26 @@
layout (location = 0) in vec2 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
vec2 u_contrastGamma;
vec2 u_position;
float u_isOutlinePass;
float u_opacity;
float u_length;
};
void main()
{
gl_Position = vec4(u_position + a_position + u_length * a_normal, 0, 1) * u_projection;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
v_colorTexCoords = a_colorTexCoords;
}

View file

@ -0,0 +1,17 @@
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
float u_opacity;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
finalColor.a *= u_opacity;
v_FragColor = finalColor;
}

View file

@ -0,0 +1,10 @@
layout (location = 0) in vec2 a_pos;
layout (location = 1) in vec2 a_tcoord;
layout (location = 0) out vec2 v_colorTexCoords;
void main()
{
v_colorTexCoords = a_tcoord;
gl_Position = vec4(a_pos, 0.0, 1.0);
}

View file

@ -0,0 +1,36 @@
#ifdef ENABLE_VTF
layout (location = 0) in LOW_P vec4 v_color;
#else
layout (location = 1) in vec2 v_colorTexCoord;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
layout (location = 2) in float v_lengthY;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_position;
vec2 u_lineParams;
float u_accuracy;
float u_zScale;
float u_opacity;
float u_azimut;
};
const float kAntialiasingThreshold = 0.92;
void main()
{
#ifdef ENABLE_VTF
LOW_P vec4 color = v_color;
#else
LOW_P vec4 color = texture(u_colorTex, v_colorTexCoord);
#endif
color.a *= u_opacity;
color.a *= (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(v_lengthY)));
v_FragColor = color;
}

View file

@ -0,0 +1,52 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 3) in vec3 a_length;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoord;
#endif
layout (location = 2) out float v_lengthY;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_position;
vec2 u_lineParams;
float u_accuracy;
float u_zScale;
float u_opacity;
float u_azimut;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
const float kAntialiasingThreshold = 0.92;
void main()
{
vec2 transformedAxisPos = (vec4(a_position.xy, 0.0, 1.0) * u_modelView).xy;
vec2 len = vec2(a_length.x, a_length.z);
if (dot(a_normal, a_normal) != 0.0)
{
vec2 norm = a_normal * u_lineParams.x;
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + norm,
u_modelView, length(norm));
if (u_lineParams.y != 0.0)
len = vec2(a_length.x + a_length.y * u_lineParams.y, a_length.z);
}
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, a_colorTexCoords);
#else
v_colorTexCoord = a_colorTexCoords;
#endif
v_lengthY = len.y;
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

View file

@ -0,0 +1,56 @@
ColoredSymbol colored_symbol.vsh.glsl colored_symbol.fsh.glsl
Texturing texturing.vsh.glsl texturing.fsh.glsl
MaskedTexturing masked_texturing.vsh.glsl masked_texturing.fsh.glsl
Bookmark user_mark.vsh.glsl user_mark.fsh.glsl
BookmarkAnim user_mark.vsh.glsl user_mark.fsh.glsl
TextOutlined text_outlined.vsh.glsl text.fsh.glsl
Text text.vsh.glsl text.fsh.glsl
TextStaticOutlinedGui text_outlined_gui.vsh.glsl text_outlined_gui.fsh.glsl
TextOutlinedGui text_outlined_gui.vsh.glsl text_outlined_gui.fsh.glsl
Area area.vsh.glsl solid_color.fsh.glsl
AreaOutline area.vsh.glsl solid_color.fsh.glsl
Area3d area3d.vsh.glsl texturing3d.fsh.glsl
Area3dOutline area3d_outline.vsh.glsl solid_color.fsh.glsl
Line line.vsh.glsl line.fsh.glsl
TransitCircle transit_circle.vsh.glsl transit_circle.fsh.glsl
DashedLine dashed_line.vsh.glsl dashed_line.fsh.glsl
PathSymbol path_symbol.vsh.glsl texturing.fsh.glsl
TransparentArea area.vsh.glsl solid_color.fsh.glsl
CapJoin circle.vsh.glsl circle.fsh.glsl
HatchingArea hatching_area.vsh.glsl hatching_area.fsh.glsl
TexturingGui texturing_gui.vsh.glsl texturing_gui.fsh.glsl
Ruler ruler.vsh.glsl ruler.fsh.glsl
Accuracy position_accuracy3d.vsh.glsl texturing_position.fsh.glsl
MyPosition my_position.vsh.glsl texturing_position.fsh.glsl
SelectionLine selection_line.vsh.glsl selection_line.fsh.glsl
Transit transit.vsh.glsl transit.fsh.glsl
TransitMarker transit_marker.vsh.glsl transit_marker.fsh.glsl
Route route.vsh.glsl route.fsh.glsl
RouteDash route.vsh.glsl route_dash.fsh.glsl
RouteArrow route_arrow.vsh.glsl route_arrow.fsh.glsl
RouteMarker route_marker.vsh.glsl route_marker.fsh.glsl
CirclePoint circle_point.vsh.glsl circle_point.fsh.glsl
BookmarkAboveText user_mark.vsh.glsl user_mark.fsh.glsl
BookmarkAnimAboveText user_mark.vsh.glsl user_mark.fsh.glsl
DebugRect debug_rect.vsh.glsl debug_rect.fsh.glsl
ScreenQuad screen_quad.vsh.glsl screen_quad.fsh.glsl
Arrow3d arrow3d.vsh.glsl arrow3d.fsh.glsl
Arrow3dTextured arrow3d_textured.vsh.glsl arrow3d_textured.fsh.glsl
Arrow3dShadow arrow3d_shadow.vsh.glsl arrow3d_shadow.fsh.glsl
Arrow3dOutline arrow3d_shadow.vsh.glsl arrow3d_outline.fsh.glsl
ColoredSymbolBillboard colored_symbol_billboard.vsh.glsl colored_symbol.fsh.glsl
TexturingBillboard texturing_billboard.vsh.glsl texturing.fsh.glsl
MaskedTexturingBillboard masked_texturing_billboard.vsh.glsl masked_texturing.fsh.glsl
BookmarkBillboard user_mark_billboard.vsh.glsl user_mark.fsh.glsl
BookmarkAnimBillboard user_mark_billboard.vsh.glsl user_mark.fsh.glsl
BookmarkAboveTextBillboard user_mark_billboard.vsh.glsl user_mark.fsh.glsl
BookmarkAnimAboveTextBillboard user_mark_billboard.vsh.glsl user_mark.fsh.glsl
TextOutlinedBillboard text_outlined_billboard.vsh.glsl text.fsh.glsl
TextBillboard text_billboard.vsh.glsl text.fsh.glsl
Traffic traffic.vsh.glsl traffic.fsh.glsl
TrafficLine traffic_line.vsh.glsl traffic_line.fsh.glsl
TrafficCircle traffic_circle.vsh.glsl traffic_circle.fsh.glsl
SmaaEdges smaa_edges.vsh.glsl smaa_edges.fsh.glsl
SmaaBlendingWeight smaa_blending_weight.vsh.glsl smaa_blending_weight.fsh.glsl
SmaaFinal smaa_final.vsh.glsl smaa_final.fsh.glsl
ImGui imgui.vsh.glsl imgui.fsh.glsl

View file

@ -0,0 +1,49 @@
// This is a library of functions which we are use in our shaders.
// Common (DO NOT modify this comment, it marks up block of common functions).
// Scale factor in shape's coordinates transformation from tile's coordinate
// system.
const float kShapeCoordScalar = 1000.0;
// VS (DO NOT modify this comment, it marks up block of vertex shader functions).
// This function applies a 2D->3D transformation matrix |pivotTransform| to |pivot|.
vec4 applyPivotTransform(vec4 pivot, mat4 pivotTransform, float pivotRealZ)
{
vec4 transformedPivot = pivot;
float w = transformedPivot.w;
transformedPivot.xyw = (pivotTransform * vec4(transformedPivot.xy, pivotRealZ, w)).xyw;
transformedPivot.z *= transformedPivot.w / w;
#ifdef VULKAN
transformedPivot.y = -transformedPivot.y;
transformedPivot.z = (transformedPivot.z + transformedPivot.w) / 2.0;
#endif
return transformedPivot;
}
// This function applies a 2D->3D transformation matrix to billboards.
vec4 applyBillboardPivotTransform(vec4 pivot, mat4 pivotTransform, float pivotRealZ, vec2 offset)
{
float logicZ = pivot.z / pivot.w;
vec4 transformedPivot = pivotTransform * vec4(pivot.xy, pivotRealZ, pivot.w);
vec4 scale = pivotTransform * vec4(1.0, -1.0, 0.0, 1.0);
vec4 position = vec4(transformedPivot.xy / transformedPivot.w, logicZ, 1.0) + vec4(offset / scale.w * scale.x, 0.0, 0.0);
#ifdef VULKAN
position.y = -position.y;
position.z = (position.z + position.w) / 2.0;
#endif
return position;
}
// This function calculates transformed position on an axis for line shaders family.
vec2 calcLineTransformedAxisPos(vec2 originalAxisPos, vec2 shiftedPos, mat4 modelView, float halfWidth)
{
vec2 p = (vec4(shiftedPos, 0.0, 1.0) * modelView).xy;
vec2 d = p - originalAxisPos;
if (dot(d, d) != 0.0)
return originalAxisPos + normalize(d) * halfWidth;
else
return originalAxisPos;
}
// FS (DO NOT modify this comment, it marks up block of fragment shader functions).

View file

@ -0,0 +1,160 @@
// Implementation of Subpixel Morphological Antialiasing (SMAA) is based on https://github.com/iryoku/smaa
layout (location = 0) in vec4 v_coords;
layout (location = 1) in vec4 v_offset0;
layout (location = 2) in vec4 v_offset1;
layout (location = 3) in vec4 v_offset2;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
vec4 u_framebufferMetrics;
};
layout (binding = 1) uniform sampler2D u_colorTex;
layout (binding = 2) uniform sampler2D u_smaaArea;
layout (binding = 3) uniform sampler2D u_smaaSearch;
#define SMAA_SEARCHTEX_SIZE vec2(66.0, 33.0)
#define SMAA_SEARCHTEX_PACKED_SIZE vec2(64.0, 16.0)
#define SMAA_AREATEX_MAX_DISTANCE 16.0
#define SMAA_AREATEX_PIXEL_SIZE (vec2(1.0 / 256.0, 1.0 / 1024.0))
#define SMAALoopBegin(condition) while (condition) {
#define SMAALoopEnd }
#define SMAASampleLevelZero(tex, coord) textureLod(tex, coord, 0.0)
#define SMAASampleLevelZeroOffset(tex, coord, offset) textureLodOffset(tex, coord, 0.0, offset)
#define SMAARound(v) round((v))
#define SMAAOffset(x,y) ivec2(x,y)
const vec2 kAreaTexMaxDistance = vec2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE);
const float kActivationThreshold = 0.8281;
float SMAASearchLength(vec2 e, float offset)
{
// The texture is flipped vertically, with left and right cases taking half
// of the space horizontally.
vec2 scale = SMAA_SEARCHTEX_SIZE * vec2(0.5, -1.0);
vec2 bias = SMAA_SEARCHTEX_SIZE * vec2(offset, 1.0);
// Scale and bias to access texel centers.
scale += vec2(-1.0, 1.0);
bias += vec2( 0.5, -0.5);
// Convert from pixel coordinates to texcoords.
// (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped).
scale *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE;
bias *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE;
// Lookup the search texture.
return SMAASampleLevelZero(u_smaaSearch, scale * e + bias).r;
}
float SMAASearchXLeft(vec2 texcoord, float end)
{
vec2 e = vec2(0.0, 1.0);
SMAALoopBegin(texcoord.x > end && e.g > kActivationThreshold && e.r == 0.0)
e = SMAASampleLevelZero(u_colorTex, texcoord).rg;
texcoord = vec2(-2.0, 0.0) * u_framebufferMetrics.xy + texcoord;
SMAALoopEnd
float offset = 3.25 - (255.0 / 127.0) * SMAASearchLength(e, 0.0);
return u_framebufferMetrics.x * offset + texcoord.x;
}
float SMAASearchXRight(vec2 texcoord, float end)
{
vec2 e = vec2(0.0, 1.0);
SMAALoopBegin(texcoord.x < end && e.g > kActivationThreshold && e.r == 0.0)
e = SMAASampleLevelZero(u_colorTex, texcoord).rg;
texcoord = vec2(2.0, 0.0) * u_framebufferMetrics.xy + texcoord;
SMAALoopEnd
float offset = 3.25 - (255.0 / 127.0) * SMAASearchLength(e, 0.5);
return -u_framebufferMetrics.x * offset + texcoord.x;
}
float SMAASearchYUp(vec2 texcoord, float end)
{
vec2 e = vec2(1.0, 0.0);
SMAALoopBegin(texcoord.y > end && e.r > kActivationThreshold && e.g == 0.0)
e = SMAASampleLevelZero(u_colorTex, texcoord).rg;
texcoord = vec2(0.0, -2.0) * u_framebufferMetrics.xy + texcoord;
SMAALoopEnd
float offset = 3.25 - (255.0 / 127.0) * SMAASearchLength(e.gr, 0.0);
return u_framebufferMetrics.y * offset + texcoord.y;
}
float SMAASearchYDown(vec2 texcoord, float end)
{
vec2 e = vec2(1.0, 0.0);
SMAALoopBegin(texcoord.y < end && e.r > kActivationThreshold && e.g == 0.0)
e = SMAASampleLevelZero(u_colorTex, texcoord).rg;
texcoord = vec2(0.0, 2.0) * u_framebufferMetrics.xy + texcoord;
SMAALoopEnd
float offset = 3.25 - (255.0 / 127.0) * SMAASearchLength(e.gr, 0.5);
return -u_framebufferMetrics.y * offset + texcoord.y;
}
// Here, we have the distance and both crossing edges. So, what are the areas
// at each side of current edge?
vec2 SMAAArea(vec2 dist, float e1, float e2)
{
// Rounding prevents precision errors of bilinear filtering.
vec2 texcoord = kAreaTexMaxDistance * SMAARound(4.0 * vec2(e1, e2)) + dist;
// We do a scale and bias for mapping to texel space.
texcoord = SMAA_AREATEX_PIXEL_SIZE * (texcoord + 0.5);
return SMAASampleLevelZero(u_smaaArea, texcoord).rg;
}
void main()
{
vec4 weights = vec4(0.0, 0.0, 0.0, 0.0);
vec2 e = texture(u_colorTex, v_coords.xy).rg;
if (e.g > 0.0) // Edge at north
{
vec2 d;
// Find the distance to the left.
vec3 coords;
coords.x = SMAASearchXLeft(v_offset0.xy, v_offset2.x);
coords.y = v_offset1.y;
d.x = coords.x;
// Now fetch the left crossing edges, two at a time using bilinear
// filtering. Sampling at -0.25 enables to discern what value each edge has.
float e1 = SMAASampleLevelZero(u_colorTex, coords.xy).r;
// Find the distance to the right.
coords.z = SMAASearchXRight(v_offset0.zw, v_offset2.y);
d.y = coords.z;
// We want the distances to be in pixel units (doing this here allow to
// better interleave arithmetic and memory accesses).
vec2 zz = u_framebufferMetrics.zz;
d = abs(SMAARound(zz * d - v_coords.zz));
// SMAAArea below needs a sqrt, as the areas texture is compressed
// quadratically.
vec2 sqrt_d = sqrt(d);
// Fetch the right crossing edges.
float e2 = SMAASampleLevelZeroOffset(u_colorTex, coords.zy, SMAAOffset(1, 0)).r;
// Here we know how this pattern looks like, now it is time for getting
// the actual area.
weights.rg = SMAAArea(sqrt_d, e1, e2);
}
if (e.r > 0.0) // Edge at west
{
vec2 d;
// Find the distance to the top.
vec3 coords;
coords.y = SMAASearchYUp(v_offset1.xy, v_offset2.z);
coords.x = v_offset0.x;
d.x = coords.y;
// Fetch the top crossing edges.
float e1 = SMAASampleLevelZero(u_colorTex, coords.xy).g;
// Find the distance to the bottom.
coords.z = SMAASearchYDown(v_offset1.zw, v_offset2.w);
d.y = coords.z;
// We want the distances to be in pixel units.
vec2 ww = u_framebufferMetrics.ww;
d = abs(SMAARound(ww * d - v_coords.ww));
// SMAAArea below needs a sqrt, as the areas texture is compressed
// quadratically.
vec2 sqrt_d = sqrt(d);
// Fetch the bottom crossing edges.
float e2 = SMAASampleLevelZeroOffset(u_colorTex, coords.xz, SMAAOffset(0, 1)).g;
// Get the area for this direction.
weights.ba = SMAAArea(sqrt_d, e1, e2);
}
v_FragColor = weights;
}

View file

@ -0,0 +1,30 @@
// Implementation of Subpixel Morphological Antialiasing (SMAA) is based on https://github.com/iryoku/smaa
layout (location = 0) in vec2 a_pos;
layout (location = 1) in vec2 a_tcoord;
layout (location = 0) out vec4 v_coords;
layout (location = 1) out vec4 v_offset0;
layout (location = 2) out vec4 v_offset1;
layout (location = 3) out vec4 v_offset2;
layout (binding = 0) uniform UBO
{
vec4 u_framebufferMetrics;
};
// SMAA_MAX_SEARCH_STEPS specifies the maximum steps performed in the
// horizontal/vertical pattern searches, at each side of the pixel.
#define SMAA_MAX_SEARCH_STEPS 8.0
const vec4 kMaxSearchSteps = vec4(-2.0 * SMAA_MAX_SEARCH_STEPS, 2.0 * SMAA_MAX_SEARCH_STEPS,
-2.0 * SMAA_MAX_SEARCH_STEPS, 2.0 * SMAA_MAX_SEARCH_STEPS);
void main()
{
v_coords = vec4(a_tcoord, a_tcoord * u_framebufferMetrics.zw);
// We will use these offsets for the searches.
v_offset0 = u_framebufferMetrics.xyxy * vec4(-0.25, -0.125, 1.25, -0.125) + a_tcoord.xyxy;
v_offset1 = u_framebufferMetrics.xyxy * vec4(-0.125, -0.25, -0.125, 1.25) + a_tcoord.xyxy;
// And these for the searches, they indicate the ends of the loops.
v_offset2 = u_framebufferMetrics.xxyy * kMaxSearchSteps + vec4(v_offset0.xz, v_offset1.yw);
gl_Position = vec4(a_pos, 0.0, 1.0);
}

View file

@ -0,0 +1,58 @@
// Implementation of Subpixel Morphological Antialiasing (SMAA) is based on https://github.com/iryoku/smaa
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 1) in vec4 v_offset0;
layout (location = 2) in vec4 v_offset1;
layout (location = 3) in vec4 v_offset2;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 1) uniform sampler2D u_colorTex;
// SMAA_THRESHOLD specifies the threshold or sensitivity to edges.
// Lowering this value you will be able to detect more edges at the expense of
// performance.
// Range: [0, 0.5]
// 0.1 is a reasonable value, and allows to catch most visible edges.
// 0.05 is a rather overkill value, that allows to catch 'em all.
#define SMAA_THRESHOLD 0.05
const vec2 kThreshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD);
// If there is an neighbor edge that has SMAA_LOCAL_CONTRAST_FACTOR times
// bigger contrast than current edge, current edge will be discarded.
// This allows to eliminate spurious crossing edges, and is based on the fact
// that, if there is too much contrast in a direction, that will hide
// perceptually contrast in the other neighbors.
#define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0
// Standard relative luminance weights.
// https://en.wikipedia.org/wiki/Relative_luminance
const vec3 kWeights = vec3(0.2126, 0.7152, 0.0722);
void main()
{
// Calculate lumas.
float L = dot(texture(u_colorTex, v_colorTexCoords).rgb, kWeights);
float Lleft = dot(texture(u_colorTex, v_offset0.xy).rgb, kWeights);
float Ltop = dot(texture(u_colorTex, v_offset0.zw).rgb, kWeights);
// We do the usual threshold.
vec4 delta;
delta.xy = abs(L - vec2(Lleft, Ltop));
vec2 edges = step(kThreshold, delta.xy);
if (dot(edges, vec2(1.0, 1.0)) == 0.0)
discard;
// Calculate right and bottom deltas.
float Lright = dot(texture(u_colorTex, v_offset1.xy).rgb, kWeights);
float Lbottom = dot(texture(u_colorTex, v_offset1.zw).rgb, kWeights);
delta.zw = abs(L - vec2(Lright, Lbottom));
// Calculate the maximum delta in the direct neighborhood.
vec2 maxDelta = max(delta.xy, delta.zw);
// Calculate left-left and top-top deltas.
float Lleftleft = dot(texture(u_colorTex, v_offset2.xy).rgb, kWeights);
float Ltoptop = dot(texture(u_colorTex, v_offset2.zw).rgb, kWeights);
delta.zw = abs(vec2(Lleft, Ltop) - vec2(Lleftleft, Ltoptop));
// Calculate the final maximum delta.
maxDelta = max(maxDelta.xy, delta.zw);
float finalDelta = max(maxDelta.x, maxDelta.y);
// Local contrast adaptation
edges *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
v_FragColor = vec4(edges, 0.0, 1.0);
}

View file

@ -0,0 +1,22 @@
// Implementation of Subpixel Morphological Antialiasing (SMAA) is based on https://github.com/iryoku/smaa
layout (location = 0) in vec2 a_pos;
layout (location = 1) in vec2 a_tcoord;
layout (location = 0) out vec2 v_colorTexCoords;
layout (location = 1) out vec4 v_offset0;
layout (location = 2) out vec4 v_offset1;
layout (location = 3) out vec4 v_offset2;
layout (binding = 0) uniform UBO
{
vec4 u_framebufferMetrics;
};
void main()
{
v_colorTexCoords = a_tcoord;
v_offset0 = u_framebufferMetrics.xyxy * vec4(-1.0, 0.0, 0.0, -1.0) + a_tcoord.xyxy;
v_offset1 = u_framebufferMetrics.xyxy * vec4( 1.0, 0.0, 0.0, 1.0) + a_tcoord.xyxy;
v_offset2 = u_framebufferMetrics.xyxy * vec4(-2.0, 0.0, 0.0, -2.0) + a_tcoord.xyxy;
gl_Position = vec4(a_pos, 0.0, 1.0);
}

View file

@ -0,0 +1,49 @@
// Implementation of Subpixel Morphological Antialiasing (SMAA) is based on https://github.com/iryoku/smaa
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 1) in vec4 v_offset;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
vec4 u_framebufferMetrics;
};
layout (binding = 1) uniform sampler2D u_colorTex;
layout (binding = 2) uniform sampler2D u_blendingWeightTex;
#define SMAASampleLevelZero(tex, coord) textureLod(tex, coord, 0.0)
void main()
{
// Fetch the blending weights for current pixel.
vec4 a;
a.x = texture(u_blendingWeightTex, v_offset.xy).a; // Right
a.y = texture(u_blendingWeightTex, v_offset.zw).g; // Top
a.wz = texture(u_blendingWeightTex, v_colorTexCoords).xz; // Bottom / Left
// Is there any blending weight with a value greater than 0.0?
if (dot(a, vec4(1.0, 1.0, 1.0, 1.0)) < 1e-5)
{
v_FragColor = texture(u_colorTex, v_colorTexCoords);
}
else
{
// Calculate the blending offsets.
vec4 blendingOffset = vec4(0.0, a.y, 0.0, a.w);
vec2 blendingWeight = a.yw;
if (max(a.x, a.z) > max(a.y, a.w))
{
blendingOffset = vec4(a.x, 0.0, a.z, 0.0);
blendingWeight = a.xz;
}
blendingWeight /= dot(blendingWeight, vec2(1.0, 1.0));
// Calculate the texture coordinates.
vec4 bc = blendingOffset * vec4(u_framebufferMetrics.xy, -u_framebufferMetrics.xy);
bc += v_colorTexCoords.xyxy;
// We exploit bilinear filtering to mix current pixel with the chosen neighbor.
vec4 color = blendingWeight.x * SMAASampleLevelZero(u_colorTex, bc.xy);
color += blendingWeight.y * SMAASampleLevelZero(u_colorTex, bc.zw);
v_FragColor = color;
}
}

View file

@ -0,0 +1,18 @@
// Implementation of Subpixel Morphological Antialiasing (SMAA) is based on https://github.com/iryoku/smaa
layout (location = 0) in vec2 a_pos;
layout (location = 1) in vec2 a_tcoord;
layout (location = 0) out vec2 v_colorTexCoords;
layout (location = 1) out vec4 v_offset;
layout (binding = 0) uniform UBO
{
vec4 u_framebufferMetrics;
};
void main()
{
v_colorTexCoords = a_tcoord;
v_offset = u_framebufferMetrics.xyxy * vec4(1.0, 0.0, 0.0, 1.0) + a_tcoord.xyxy;
gl_Position = vec4(a_pos, 0.0, 1.0);
}

View file

@ -0,0 +1,31 @@
#ifdef ENABLE_VTF
layout (location = 0) in LOW_P vec4 v_color;
#else
layout (location = 1) in vec2 v_colorTexCoords;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
#ifdef ENABLE_VTF
LOW_P vec4 finalColor = v_color;
#else
LOW_P vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
#endif
finalColor.a *= u_opacity;
v_FragColor = finalColor;
}

View file

@ -0,0 +1,36 @@
#ifdef ENABLE_VTF
layout (location = 0) in LOW_P vec4 v_color;
#else
layout (location = 1) in vec2 v_colorTexCoord;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
layout (location = 2) in vec2 v_maskTexCoord;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 2) uniform sampler2D u_maskTex;
void main()
{
#ifdef ENABLE_VTF
LOW_P vec4 glyphColor = v_color;
#else
LOW_P vec4 glyphColor = texture(u_colorTex, v_colorTexCoord);
#endif
float dist = texture(u_maskTex, v_maskTexCoord).r;
float alpha = smoothstep(u_contrastGamma.x - u_contrastGamma.y, u_contrastGamma.x + u_contrastGamma.y, dist) * u_opacity;
glyphColor.a *= alpha;
v_FragColor = glyphColor;
}

View file

@ -0,0 +1,40 @@
layout (location = 0) in vec2 a_colorTexCoord;
layout (location = 1) in vec2 a_maskTexCoord;
layout (location = 2) in vec4 a_position;
layout (location = 3) in vec2 a_normal;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoord;
#endif
layout (location = 2) out vec2 v_maskTexCoord;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
{
vec4 pos = vec4(a_position.xyz, 1) * u_modelView;
vec4 shiftedPos = vec4(a_normal, 0.0, 0.0) + pos;
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, a_colorTexCoord);
#else
v_colorTexCoord = a_colorTexCoord;
#endif
v_maskTexCoord = a_maskTexCoord;
}

View file

@ -0,0 +1,39 @@
layout (location = 0) in vec2 a_colorTexCoord;
layout (location = 1) in vec2 a_maskTexCoord;
layout (location = 2) in vec4 a_position;
layout (location = 3) in vec2 a_normal;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoord;
#endif
layout (location = 2) out vec2 v_maskTexCoord;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 pivot = vec4(a_position.xyz, 1.0) * u_modelView;
vec4 offset = vec4(a_normal, 0.0, 0.0) * u_projection;
gl_Position = applyBillboardPivotTransform(pivot * u_projection, u_pivotTransform,
a_position.w * u_zScale, offset.xy);
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, a_colorTexCoord);
#else
v_colorTexCoord = a_colorTexCoord;
#endif
v_maskTexCoord = a_maskTexCoord;
}

View file

@ -0,0 +1,47 @@
layout (location = 0) in vec2 a_colorTexCoord;
layout (location = 1) in vec2 a_outlineColorTexCoord;
layout (location = 2) in vec2 a_maskTexCoord;
layout (location = 3) in vec4 a_position;
layout (location = 4) in vec2 a_normal;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoord;
#endif
layout (location = 2) out vec2 v_maskTexCoord;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
const float BaseDepthShift = -10.0;
void main()
{
float isOutline = step(0.5, u_isOutlinePass);
float notOutline = 1.0 - isOutline;
float depthShift = BaseDepthShift * isOutline;
vec4 pos = (vec4(a_position.xyz, 1) + vec4(0.0, 0.0, depthShift, 0.0)) * u_modelView;
vec4 shiftedPos = vec4(a_normal, 0.0, 0.0) + pos;
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
vec2 colorTexCoord = a_colorTexCoord * notOutline + a_outlineColorTexCoord * isOutline;
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, colorTexCoord);
#else
v_colorTexCoord = colorTexCoord;
#endif
v_maskTexCoord = a_maskTexCoord;
}

View file

@ -0,0 +1,45 @@
layout (location = 0) in vec2 a_colorTexCoord;
layout (location = 1) in vec2 a_outlineColorTexCoord;
layout (location = 2) in vec2 a_maskTexCoord;
layout (location = 3) in vec4 a_position;
layout (location = 4) in vec2 a_normal;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoord;
#endif
layout (location = 2) out vec2 v_maskTexCoord;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 1) uniform sampler2D u_colorTex;
const float kBaseDepthShift = -10.0;
void main()
{
float isOutline = step(0.5, u_isOutlinePass);
float depthShift = kBaseDepthShift * isOutline;
vec4 pivot = (vec4(a_position.xyz, 1.0) + vec4(0.0, 0.0, depthShift, 0.0)) * u_modelView;
vec4 offset = vec4(a_normal, 0.0, 0.0) * u_projection;
gl_Position = applyBillboardPivotTransform(pivot * u_projection, u_pivotTransform,
a_position.w * u_zScale, offset.xy);
vec2 colorTexCoord = mix(a_colorTexCoord, a_outlineColorTexCoord, isOutline);
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, colorTexCoord);
#else
v_colorTexCoord = colorTexCoord;
#endif
v_maskTexCoord = a_maskTexCoord;
}

View file

@ -0,0 +1,35 @@
#ifdef ENABLE_VTF
layout (location = 0) in LOW_P vec4 v_color;
#else
layout (location = 1) in vec2 v_colorTexCoord;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
layout (location = 2) in vec2 v_maskTexCoord;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
vec2 u_contrastGamma;
vec2 u_position;
float u_isOutlinePass;
float u_opacity;
float u_length;
};
layout (binding = 2) uniform sampler2D u_maskTex;
void main()
{
#ifdef ENABLE_VTF
LOW_P vec4 glyphColor = v_color;
#else
LOW_P vec4 glyphColor = texture(u_colorTex, v_colorTexCoord);
#endif
float dist = texture(u_maskTex, v_maskTexCoord).r;
float alpha = smoothstep(u_contrastGamma.x - u_contrastGamma.y, u_contrastGamma.x + u_contrastGamma.y, dist) * u_opacity;
glyphColor.a *= alpha;
v_FragColor = glyphColor;
}

View file

@ -0,0 +1,49 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_colorTexCoord;
layout (location = 2) in vec2 a_outlineColorTexCoord;
layout (location = 3) in vec2 a_normal;
layout (location = 4) in vec2 a_maskTexCoord;
#ifdef ENABLE_VTF
layout (location = 0) out LOW_P vec4 v_color;
#else
layout (location = 1) out vec2 v_colorTexCoord;
#endif
layout (location = 2) out vec2 v_maskTexCoord;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
vec2 u_contrastGamma;
vec2 u_position;
float u_isOutlinePass;
float u_opacity;
float u_length;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
const float kBaseDepthShift = -10.0;
void main()
{
float isOutline = step(0.5, u_isOutlinePass);
float depthShift = kBaseDepthShift * isOutline;
vec4 pos = (vec4(a_position, 1.0) + vec4(0.0, 0.0, depthShift, 0.0)) * u_modelView;
vec4 shiftedPos = vec4(a_normal, 0.0, 0.0) + pos;
gl_Position = shiftedPos * u_projection;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
vec2 colorTexCoord = mix(a_colorTexCoord, a_outlineColorTexCoord, isOutline);
#ifdef ENABLE_VTF
v_color = texture(u_colorTex, colorTexCoord);
#else
v_colorTexCoord = colorTexCoord;
#endif
v_maskTexCoord = a_maskTexCoord;
}

View file

@ -0,0 +1,24 @@
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
finalColor.a *= u_opacity;
v_FragColor = finalColor;
}

View file

@ -0,0 +1,25 @@
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
vec4 pos = vec4(a_position.xyz, 1) * u_modelView;
vec4 shiftedPos = vec4(a_normal, 0, 0) + pos;
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
v_colorTexCoords = a_colorTexCoords;
}

View file

@ -0,0 +1,24 @@
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 1) in float v_intensity;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 finalColor = vec4(texture(u_colorTex, v_colorTexCoords).rgb, u_opacity);
v_FragColor = vec4((v_intensity * 0.2 + 0.8) * finalColor.rgb, finalColor.a);
}

View file

@ -0,0 +1,26 @@
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
vec4 pivot = vec4(a_position.xyz, 1.0) * u_modelView;
vec4 offset = vec4(a_normal, 0.0, 0.0) * u_projection;
gl_Position = applyBillboardPivotTransform(pivot * u_projection, u_pivotTransform,
a_position.w * u_zScale, offset.xy);
v_colorTexCoords = a_colorTexCoords;
}

View file

@ -0,0 +1,23 @@
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
vec2 u_contrastGamma;
vec2 u_position;
float u_isOutlinePass;
float u_opacity;
float u_length;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
finalColor.a *= u_opacity;
v_FragColor = finalColor;
}

View file

@ -0,0 +1,25 @@
layout (location = 0) in vec2 a_position;
layout (location = 1) in vec2 a_colorTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
vec2 u_contrastGamma;
vec2 u_position;
float u_isOutlinePass;
float u_opacity;
float u_length;
};
void main()
{
gl_Position = vec4(a_position, 0, 1) * u_modelView * u_projection;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
v_colorTexCoords = a_colorTexCoords;
}

View file

@ -0,0 +1,25 @@
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_position;
vec2 u_lineParams;
float u_accuracy;
float u_zScale;
float u_opacity;
float u_azimut;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
finalColor.a *= u_opacity;
v_FragColor = finalColor;
}

View file

@ -0,0 +1,41 @@
layout (location = 0) in vec2 v_colorTexCoord;
layout (location = 1) in vec2 v_maskTexCoord;
layout (location = 2) in float v_halfLength;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_trafficParams;
vec4 u_outlineColor;
vec4 u_lightArrowColor;
vec4 u_darkArrowColor;
float u_outline;
float u_opacity;
};
layout (binding = 1) uniform sampler2D u_colorTex;
layout (binding = 2) uniform sampler2D u_maskTex;
const float kAntialiasingThreshold = 0.92;
const float kOutlineThreshold1 = 0.8;
const float kOutlineThreshold2 = 0.5;
const float kMaskOpacity = 0.7;
void main()
{
vec4 color = texture(u_colorTex, v_colorTexCoord);
float alphaCode = color.a;
vec4 mask = texture(u_maskTex, v_maskTexCoord);
color.a = u_opacity * (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(v_halfLength)));
color.rgb = mix(color.rgb, mask.rgb * mix(u_lightArrowColor.rgb, u_darkArrowColor.rgb, step(alphaCode, 0.6)), mask.a * kMaskOpacity);
if (u_outline > 0.0)
{
color.rgb = mix(color.rgb, u_outlineColor.rgb, step(kOutlineThreshold1, abs(v_halfLength)));
color.rgb = mix(color.rgb, u_outlineColor.rgb, smoothstep(kOutlineThreshold2, kOutlineThreshold1, abs(v_halfLength)));
}
v_FragColor = color;
}

View file

@ -0,0 +1,44 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec4 a_normal;
layout (location = 2) in vec4 a_colorTexCoord;
layout (location = 0) out vec2 v_colorTexCoord;
layout (location = 1) out vec2 v_maskTexCoord;
layout (location = 2) out float v_halfLength;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_trafficParams;
vec4 u_outlineColor;
vec4 u_lightArrowColor;
vec4 u_darkArrowColor;
float u_outline;
float u_opacity;
};
const float kArrowVSize = 0.25;
void main()
{
vec2 normal = a_normal.xy;
vec2 transformedAxisPos = (vec4(a_position.xy, 0.0, 1.0) * u_modelView).xy;
if (dot(normal, normal) != 0.0)
{
vec2 norm = normal * u_trafficParams.x;
if (a_normal.z < 0.0)
norm = normal * u_trafficParams.y;
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + norm,
u_modelView, length(norm));
}
float uOffset = length(vec4(kShapeCoordScalar, 0, 0, 0) * u_modelView) * a_normal.w;
v_colorTexCoord = a_colorTexCoord.xy;
float v = mix(a_colorTexCoord.z, a_colorTexCoord.z + kArrowVSize, 0.5 * a_normal.z + 0.5);
v_maskTexCoord = vec2(uOffset * u_trafficParams.z, v) * u_trafficParams.w;
v_maskTexCoord.x *= step(a_colorTexCoord.w, v_maskTexCoord.x);
v_halfLength = a_normal.z;
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

View file

@ -0,0 +1,36 @@
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
layout (location = 0) in vec2 v_colorTexCoord;
layout (location = 1) in vec3 v_radius;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_trafficParams;
vec4 u_outlineColor;
vec4 u_lightArrowColor;
vec4 u_darkArrowColor;
float u_outline;
float u_opacity;
};
layout (binding = 1) uniform sampler2D u_colorTex;
const float kAntialiasingThreshold = 0.92;
void main()
{
vec4 color = texture(u_colorTex, v_colorTexCoord);
float smallRadius = v_radius.z * kAntialiasingThreshold;
float stepValue = smoothstep(smallRadius * smallRadius, v_radius.z * v_radius.z,
v_radius.x * v_radius.x + v_radius.y * v_radius.y);
color.a = u_opacity * (1.0 - stepValue);
if (color.a < 0.01)
discard;
v_FragColor = color;
}

View file

@ -0,0 +1,41 @@
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec4 a_normal;
layout (location = 2) in vec2 a_colorTexCoord;
layout (location = 0) out vec2 v_colorTexCoord;
layout (location = 1) out vec3 v_radius;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_trafficParams;
vec4 u_outlineColor;
vec4 u_lightArrowColor;
vec4 u_darkArrowColor;
float u_outline;
float u_opacity;
};
void main()
{
vec2 normal = a_normal.xy;
vec2 transformedAxisPos = (vec4(a_position.xy, 0.0, 1.0) * u_modelView).xy;
int index = int(a_position.w);
float leftSize = u_lightArrowColor[index];
float rightSize = u_darkArrowColor[index];
if (dot(normal, normal) != 0.0)
{
// offset by normal = rightVec * (rightSize - leftSize) / 2
vec2 norm = normal * 0.5 * (rightSize - leftSize);
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + norm,
u_modelView, length(norm));
}
// radius = (leftSize + rightSize) / 2
v_radius = vec3(a_normal.zw, 1.0) * 0.5 * (leftSize + rightSize);
vec2 finalPos = transformedAxisPos + v_radius.xy;
v_colorTexCoord = a_colorTexCoord;
vec4 pos = vec4(finalPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

View file

@ -0,0 +1,24 @@
layout (location = 0) in vec2 v_colorTexCoord;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_trafficParams;
vec4 u_outlineColor;
vec4 u_lightArrowColor;
vec4 u_darkArrowColor;
float u_outline;
float u_opacity;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 color = texture(u_colorTex, v_colorTexCoord);
v_FragColor = vec4(color.rgb, u_opacity);
}

View file

@ -0,0 +1,25 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_colorTexCoord;
layout (location = 0) out vec2 v_colorTexCoord;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_trafficParams;
vec4 u_outlineColor;
vec4 u_lightArrowColor;
vec4 u_darkArrowColor;
float u_outline;
float u_opacity;
};
void main()
{
vec2 transformedAxisPos = (vec4(a_position.xy, 0.0, 1.0) * u_modelView).xy;
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
v_colorTexCoord = a_colorTexCoord;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

View file

@ -0,0 +1,8 @@
layout (location = 0) in vec4 v_color;
layout (location = 0) out vec4 v_FragColor;
void main()
{
v_FragColor = v_color;
}

View file

@ -0,0 +1,30 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec4 a_normal;
layout (location = 2) in vec4 a_color;
layout (location = 0) out vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_params;
float u_lineHalfWidth;
float u_maxRadius;
};
void main()
{
vec2 normal = a_normal.xy;
vec2 transformedAxisPos = (vec4(a_position.xy, 0.0, 1.0) * u_modelView).xy;
if (dot(normal, normal) != 0.0)
{
vec2 norm = normal * u_lineHalfWidth;
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + norm,
u_modelView, length(norm));
}
v_color = a_color;
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

View file

@ -0,0 +1,21 @@
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
layout (location = 0) in vec3 v_radius;
layout (location = 1) in vec4 v_color;
layout (location = 0) out vec4 v_FragColor;
const float aaPixelsCount = 2.5;
void main()
{
vec4 finalColor = v_color;
float smallRadius = v_radius.z - aaPixelsCount;
float stepValue = smoothstep(smallRadius * smallRadius, v_radius.z * v_radius.z,
dot(v_radius.xy, v_radius.xy));
finalColor.a = finalColor.a * (1.0 - stepValue);
if (finalColor.a < 0.01)
discard;
v_FragColor = finalColor;
}

View file

@ -0,0 +1,33 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec4 a_normal;
layout (location = 2) in vec4 a_color;
layout (location = 0) out vec3 v_radius;
layout (location = 1) out vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_params;
float u_lineHalfWidth;
float u_maxRadius;
};
void main()
{
vec2 normal = a_normal.xy;
vec2 transformedAxisPos = (vec4(a_position.xy, 0.0, 1.0) * u_modelView).xy;
if (dot(normal, normal) != 0.0)
{
vec2 norm = normal * u_lineHalfWidth;
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + norm,
u_modelView, length(norm));
}
transformedAxisPos += a_normal.zw * u_lineHalfWidth;
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
v_color = a_color;
v_radius = vec3(a_normal.zw, u_maxRadius) * u_lineHalfWidth;
}

View file

@ -0,0 +1,17 @@
layout (location = 0) in vec4 v_offsets;
layout (location = 1) in vec4 v_color;
layout (location = 0) out vec4 v_FragColor;
void main()
{
vec4 finalColor = v_color;
vec2 radius;
radius.x = max(0.0, abs(v_offsets.x) - v_offsets.z);
radius.y = max(0.0, abs(v_offsets.y) - v_offsets.w);
float maxRadius = 1.0;
float aaRadius = 0.9;
float stepValue = smoothstep(aaRadius * aaRadius, maxRadius * maxRadius, dot(radius.xy, radius.xy));
finalColor.a = finalColor.a * (1.0 - stepValue);
v_FragColor = finalColor;
}

View file

@ -0,0 +1,29 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec4 a_normal;
layout (location = 2) in vec4 a_color;
layout (location = 0) out vec4 v_offsets;
layout (location = 1) out vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_params;
float u_lineHalfWidth;
float u_maxRadius;
};
void main()
{
vec4 pos = vec4(a_position.xy, 0, 1) * u_modelView;
vec2 normal = vec2(a_normal.x * u_params.x - a_normal.y * u_params.y,
a_normal.x * u_params.y + a_normal.y * u_params.x);
vec2 shiftedPos = normal * u_params.z + pos.xy;
pos = vec4(shiftedPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
vec2 offsets = abs(a_normal.zw);
v_offsets = vec4(a_normal.zw, offsets - 1.0);
v_color = a_color;
}

View file

@ -0,0 +1,32 @@
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
layout (location = 0) in vec4 v_texCoords;
layout (location = 1) in vec4 v_maskColor;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 color = texture(u_colorTex, v_texCoords.xy);
vec4 bgColor = texture(u_colorTex, v_texCoords.zw) * vec4(v_maskColor.xyz, 1.0);
vec4 finalColor = mix(color, mix(bgColor, color, color.a), bgColor.a);
finalColor.a = clamp(color.a + bgColor.a, 0.0, 1.0) * u_opacity * v_maskColor.w;
if (finalColor.a < 0.01)
discard;
v_FragColor = finalColor;
}

View file

@ -0,0 +1,34 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec3 a_normalAndAnimateOrZ;
layout (location = 2) in vec4 a_texCoords;
layout (location = 3) in vec4 a_color;
layout (location = 0) out vec4 v_texCoords;
layout (location = 1) out vec4 v_maskColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
vec2 normal = a_normalAndAnimateOrZ.xy;
if (a_normalAndAnimateOrZ.z > 0.0)
normal = u_interpolation * normal;
vec4 p = vec4(a_position, 1.0) * u_modelView;
vec4 pos = vec4(normal, 0.0, 0.0) + p;
vec4 projectedPivot = p * u_projection;
gl_Position = applyPivotTransform(pos * u_projection, u_pivotTransform, 0.0);
float newZ = projectedPivot.y / projectedPivot.w * 0.5 + 0.5;
gl_Position.z = abs(a_normalAndAnimateOrZ.z) * newZ + (1.0 - abs(a_normalAndAnimateOrZ.z)) * gl_Position.z;
v_texCoords = a_texCoords;
v_maskColor = a_color;
}

View file

@ -0,0 +1,34 @@
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec3 a_normalAndAnimateOrZ;
layout (location = 2) in vec4 a_texCoords;
layout (location = 3) in vec4 a_color;
layout (location = 0) out vec4 v_texCoords;
layout (location = 1) out vec4 v_maskColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
vec2 normal = a_normalAndAnimateOrZ.xy;
if (a_normalAndAnimateOrZ.z > 0.0)
normal = u_interpolation * normal;
vec4 pivot = vec4(a_position, 1.0) * u_modelView;
vec4 offset = vec4(normal, 0.0, 0.0) * u_projection;
vec4 projectedPivot = pivot * u_projection;
gl_Position = applyBillboardPivotTransform(projectedPivot, u_pivotTransform, 0.0, offset.xy);
float newZ = projectedPivot.y / projectedPivot.w * 0.5 + 0.5;
gl_Position.z = abs(a_normalAndAnimateOrZ.z) * newZ + (1.0 - abs(a_normalAndAnimateOrZ.z)) * gl_Position.z;
v_texCoords = a_texCoords;
v_maskColor = a_color;
}

View file

@ -0,0 +1,109 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
typedef struct
{
float4x4 u_transform;
float4x4 u_normalTransform;
float4 u_color;
float2 u_texCoordFlipping;
} Uniforms_T;
typedef struct
{
float3 a_position [[attribute(0)]];
float3 a_normal [[attribute(1)]];
} Vertex_T;
typedef struct
{
float4 position [[position]];
float3 normal;
} Fragment_T;
typedef struct
{
float3 a_position [[attribute(0)]];
float2 a_texCoords [[attribute(1)]];
} VertexShadow_T;
typedef struct
{
float4 position [[position]];
float intensity;
} FragmentShadow_T;
typedef struct
{
float3 a_position [[attribute(0)]];
float3 a_normal [[attribute(1)]];
float2 a_texCoords [[attribute(2)]];
} VertexTextured_T;
typedef struct
{
float4 position [[position]];
float3 normal;
float2 texCoords;
} FragmentTextured_T;
vertex Fragment_T vsArrow3d(const Vertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(2)]])
{
Fragment_T out;
out.position = uniforms.u_transform * float4(in.a_position, 1.0);
out.normal = normalize((uniforms.u_normalTransform * float4(in.a_normal, 0.0)).xyz);
return out;
}
fragment float4 fsArrow3d(const Fragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]])
{
constexpr float3 kLightDir = float3(0.316, 0.0, 0.948);
float phongDiffuse = max(0.0, -dot(kLightDir, in.normal));
return float4((phongDiffuse * 0.5 + 0.5) * uniforms.u_color.rgb, uniforms.u_color.a);
}
vertex FragmentShadow_T vsArrow3dShadow(const VertexShadow_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(2)]])
{
FragmentShadow_T out;
out.position = uniforms.u_transform * float4(in.a_position, 1.0);
out.intensity = in.a_texCoords.x;
return out;
}
fragment float4 fsArrow3dShadow(const FragmentShadow_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]])
{
return float4(uniforms.u_color.rgb, uniforms.u_color.a * in.intensity);
}
fragment float4 fsArrow3dOutline(const FragmentShadow_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]])
{
float alpha = smoothstep(0.7, 1.0, in.intensity);
return float4(uniforms.u_color.rgb, uniforms.u_color.a * alpha);
}
vertex FragmentTextured_T vsArrow3dTextured(const VertexTextured_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(3)]])
{
FragmentTextured_T out;
out.position = uniforms.u_transform * float4(in.a_position, 1.0);
out.normal = normalize((uniforms.u_normalTransform * float4(in.a_normal, 0.0)).xyz);
out.texCoords = mix(in.a_texCoords, 1.0 - in.a_texCoords, uniforms.u_texCoordFlipping);
return out;
}
fragment float4 fsArrow3dTextured(const FragmentTextured_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
constexpr float3 kLightDir = float3(0.316, 0.0, 0.948);
float phongDiffuse = max(0.0, -dot(kLightDir, in.normal));
float4 color = u_colorTex.sample(u_colorTexSampler, in.texCoords) * uniforms.u_color;
return float4((phongDiffuse * 0.5 + 0.5) * color.rgb, color.a);
}

View file

@ -0,0 +1,31 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
typedef struct
{
float2 a_position [[attribute(0)]];
} Vertex_T;
typedef struct
{
float4 position [[position]];
} Fragment_T;
typedef struct
{
float4 u_color;
} Uniforms_T;
vertex Fragment_T vsDebugRect(const Vertex_T in [[stage_in]])
{
Fragment_T out;
out.position = float4(in.a_position, 0.0, 1.0);
return out;
}
fragment float4 fsDebugRect(const Fragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]])
{
return uniforms.u_color;
}

View file

@ -0,0 +1,162 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
typedef struct
{
float4x4 u_modelView;
float4x4 u_projection;
packed_float2 u_contrastGamma;
packed_float2 u_position;
float u_isOutlinePass;
float u_opacity;
float u_length;
} Uniforms_T;
// Ruler
typedef struct
{
float2 a_position [[attribute(0)]];
float2 a_normal [[attribute(1)]];
float2 a_texCoords [[attribute(2)]];
} RulerVertex_T;
typedef struct
{
float4 position [[position]];
half4 color;
} RulerFragment_T;
vertex RulerFragment_T vsRuler(const RulerVertex_T in [[stage_in]],
texture2d<half> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
RulerFragment_T out;
float2 p = uniforms.u_position + in.a_position + uniforms.u_length * in.a_normal;
out.position = float4(p, 0.0, 1.0) * uniforms.u_projection;
half4 color = u_colorTex.sample(u_colorTexSampler, in.a_texCoords);
color.a *= uniforms.u_opacity;
out.color = color;
return out;
}
fragment half4 fsRuler(const RulerFragment_T in [[stage_in]])
{
return in.color;
}
// TextStaticOutlinedGui / TextOutlinedGui
typedef struct
{
float3 a_position [[attribute(0)]];
float2 a_colorTexCoord [[attribute(1)]];
float2 a_outlineColorTexCoord [[attribute(2)]];
float2 a_normal [[attribute(3)]];
float2 a_maskTexCoord [[attribute(4)]];
} TextStaticOutlinedGuiVertex_T;
typedef struct
{
float3 a_position [[attribute(0)]];
float2 a_colorTexCoord [[attribute(1)]];
float2 a_outlineColorTexCoord [[attribute(2)]];
float2 a_normal [[attribute(3)]];
float2 a_maskTexCoord [[attribute(4)]];
} TextOutlinedGuiVertex_T;
typedef struct
{
float4 position [[position]];
half4 glyphColor;
float2 maskTexCoord;
} TextOutlinedGuiFragment_T;
TextOutlinedGuiFragment_T ComputeTextOutlinedGuiVertex(constant Uniforms_T & uniforms, float3 a_position, float2 a_normal,
float2 a_colorTexCoord, float2 a_outlineColorTexCoord,
float2 a_maskTexCoord, texture2d<half> u_colorTex,
sampler u_colorTexSampler)
{
constexpr float kBaseDepthShift = -10.0;
TextOutlinedGuiFragment_T out;
float isOutline = step(0.5, uniforms.u_isOutlinePass);
float depthShift = kBaseDepthShift * isOutline;
float4 pos = (float4(a_position, 1.0) + float4(0.0, 0.0, depthShift, 0.0)) * uniforms.u_modelView;
float4 shiftedPos = float4(a_normal, 0.0, 0.0) + pos;
out.position = shiftedPos * uniforms.u_projection;
out.glyphColor = u_colorTex.sample(u_colorTexSampler,
mix(a_colorTexCoord, a_outlineColorTexCoord, isOutline));
out.maskTexCoord = a_maskTexCoord;
return out;
}
vertex TextOutlinedGuiFragment_T vsTextStaticOutlinedGui(const TextStaticOutlinedGuiVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<half> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
return ComputeTextOutlinedGuiVertex(uniforms, in.a_position, in.a_normal, in.a_colorTexCoord,
in.a_outlineColorTexCoord, in.a_maskTexCoord,
u_colorTex, u_colorTexSampler);
}
vertex TextOutlinedGuiFragment_T vsTextOutlinedGui(const TextOutlinedGuiVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(2)]],
texture2d<half> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
return ComputeTextOutlinedGuiVertex(uniforms, in.a_position, in.a_normal, in.a_colorTexCoord,
in.a_outlineColorTexCoord, in.a_maskTexCoord,
u_colorTex, u_colorTexSampler);
}
fragment half4 fsTextOutlinedGui(const TextOutlinedGuiFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_maskTex [[texture(0)]],
sampler u_maskTexSampler [[sampler(0)]])
{
half4 glyphColor = in.glyphColor;
float dist = u_maskTex.sample(u_maskTexSampler, in.maskTexCoord).a;
float2 contrastGamma = uniforms.u_contrastGamma;
float alpha = smoothstep(contrastGamma.x - contrastGamma.y, contrastGamma.x + contrastGamma.y, dist);
glyphColor.a *= (alpha * uniforms.u_opacity);
return glyphColor;
}
// TexturingGui
typedef struct
{
float2 a_position [[attribute(0)]];
float2 a_texCoords [[attribute(1)]];
} TexturingGuiVertex_T;
typedef struct
{
float4 position [[position]];
float2 texCoords;
} TexturingGuiFragment_T;
vertex TexturingGuiFragment_T vsTexturingGui(const TexturingGuiVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
TexturingGuiFragment_T out;
out.position = float4(in.a_position, 0.0, 1.0) * uniforms.u_modelView * uniforms.u_projection;
out.texCoords = in.a_texCoords;
return out;
}
fragment float4 fsTexturingGui(const TexturingGuiFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
float4 color = u_colorTex.sample(u_colorTexSampler, in.texCoords);
color.a *= uniforms.u_opacity;
return color;
}

View file

@ -0,0 +1,39 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
typedef struct
{
float2 a_position [[attribute(0)]];
float2 a_texCoords [[attribute(1)]];
float4 a_color [[attribute(2)]];
} Vertex_T;
typedef struct
{
float4 position [[position]];
float2 texCoords;
float4 color;
} Fragment_T;
typedef struct
{
float4x4 u_projection;
} Uniforms_T;
vertex Fragment_T vsImGui(const Vertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
Fragment_T out;
out.position = float4(in.a_position, 0.0, 1.0) * uniforms.u_projection;
out.texCoords = in.a_texCoords;
out.color = in.a_color;
return out;
}
fragment float4 fsImGui(const Fragment_T in [[stage_in]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
return in.color * u_colorTex.sample(u_colorTexSampler, in.texCoords);
}

View file

@ -0,0 +1,841 @@
#include <metal_stdlib>
#include <simd/simd.h>
#include "shaders_lib.h"
using namespace metal;
typedef struct
{
float4x4 u_modelView;
float4x4 u_projection;
float4x4 u_pivotTransform;
packed_float2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
} Uniforms_T;
// Area/AreaOutline
typedef struct
{
float3 a_position [[attribute(0)]];
float2 a_texCoords [[attribute(1)]];
} AreaVertex_T;
typedef struct
{
float4 position [[position]];
half4 color;
} AreaFragment_T;
vertex AreaFragment_T vsArea(const AreaVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<half> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
AreaFragment_T out;
float4 pos = float4(in.a_position, 1.0) * uniforms.u_modelView * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
half4 color = u_colorTex.sample(u_colorTexSampler, in.a_texCoords);
color.a *= uniforms.u_opacity;
out.color = color;
return out;
}
fragment half4 fsArea(const AreaFragment_T in [[stage_in]])
{
return in.color;
}
// Area3d
typedef struct
{
float3 a_position [[attribute(0)]];
float3 a_normal [[attribute(1)]];
float2 a_texCoords [[attribute(2)]];
} Area3dVertex_T;
typedef struct
{
float4 position [[position]];
half4 color;
float intensity;
} Area3dFragment_T;
vertex Area3dFragment_T vsArea3d(const Area3dVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<half> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
constexpr float4 kNormalizedLightDir = float4(0.3162, 0.0, 0.9486, 0.0);
Area3dFragment_T out;
float4 pos = float4(in.a_position, 1.0) * uniforms.u_modelView;
float4 normal = float4(in.a_position + in.a_normal, 1.0) * uniforms.u_modelView;
normal.xyw = (normal * uniforms.u_projection).xyw;
normal.z = normal.z * uniforms.u_zScale;
pos.xyw = (pos * uniforms.u_projection).xyw;
pos.z = in.a_position.z * uniforms.u_zScale;
float4 normDir = normal - pos;
if (dot(normDir, normDir) != 0.0)
out.intensity = max(0.0, -dot(kNormalizedLightDir, normalize(normDir)));
else
out.intensity = 0.0;
out.position = uniforms.u_pivotTransform * pos;
half4 color = u_colorTex.sample(u_colorTexSampler, in.a_texCoords);
color.a = (half)uniforms.u_opacity;
out.color = color;
return out;
}
fragment half4 fsArea3d(const Area3dFragment_T in [[stage_in]])
{
return half4(in.color.rgb * (in.intensity * 0.2 + 0.8), in.color.a);
}
// Area3dOutline
typedef struct
{
float3 a_position [[attribute(0)]];
float2 a_texCoords [[attribute(1)]];
} Area3dOutlineVertex_T;
vertex AreaFragment_T vsArea3dOutline(const Area3dOutlineVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<half> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
AreaFragment_T out;
float4 pos = float4(in.a_position, 1.0) * uniforms.u_modelView;
pos.xyw = (pos * uniforms.u_projection).xyw;
pos.z = in.a_position.z * uniforms.u_zScale;
out.position = uniforms.u_pivotTransform * pos;
half4 color = u_colorTex.sample(u_colorTexSampler, in.a_texCoords);
color.a *= uniforms.u_opacity;
out.color = color;
return out;
}
// HatchingArea
typedef struct
{
float3 a_position [[attribute(0)]];
float2 a_colorTexCoords [[attribute(1)]];
float2 a_maskTexCoords [[attribute(2)]];
} HatchingAreaVertex_T;
typedef struct
{
float4 position [[position]];
half4 color;
float2 maskTexCoords;
} HatchingAreaFragment_T;
vertex HatchingAreaFragment_T vsHatchingArea(const HatchingAreaVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<half> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
HatchingAreaFragment_T out;
float4 pos = float4(in.a_position, 1.0) * uniforms.u_modelView * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
out.maskTexCoords = in.a_maskTexCoords;
half4 color = u_colorTex.sample(u_colorTexSampler, in.a_colorTexCoords);
color.a *= uniforms.u_opacity;
out.color = color;
return out;
}
fragment half4 fsHatchingArea(const HatchingAreaFragment_T in [[stage_in]],
texture2d<half> u_maskTex [[texture(0)]],
sampler u_maskTexSampler [[sampler(0)]])
{
return in.color * u_maskTex.sample(u_maskTexSampler, in.maskTexCoords);
}
// CirclePoint
typedef struct
{
float3 a_normal [[attribute(0)]];
float3 a_position [[attribute(1)]];
float4 a_color [[attribute(2)]];
} CirclePointVertex_T;
typedef struct
{
float4 position [[position]];
float3 radius;
float4 color;
} CirclePointFragment_T;
vertex CirclePointFragment_T vsCirclePoint(const CirclePointVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(2)]])
{
CirclePointFragment_T out;
float3 radius = in.a_normal * in.a_position.z;
float4 pos = float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView;
float4 shiftedPos = float4(radius.xy, 0.0, 0.0) + pos;
out.position = ApplyPivotTransform(shiftedPos * uniforms.u_projection, uniforms.u_pivotTransform, 0.0);
out.radius = radius;
out.color = in.a_color;
return out;
}
fragment float4 fsCirclePoint(const CirclePointFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]])
{
constexpr float kAntialiasingScalar = 0.9;
float d = dot(in.radius.xy, in.radius.xy);
float4 color = in.color;
float aaRadius = in.radius.z * kAntialiasingScalar;
float stepValue = 1.0 - smoothstep(aaRadius * aaRadius, in.radius.z * in.radius.z, d);
color.a *= (uniforms.u_opacity * stepValue);
return color;
}
// Line
typedef struct
{
float3 a_position [[attribute(0)]];
float3 a_normal [[attribute(1)]];
float2 a_texCoords [[attribute(2)]];
} LineVertex_T;
typedef struct
{
float4 position [[position]];
float4 color;
//float2 halfLength;
} LineFragment_T;
vertex LineFragment_T vsLine(const LineVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
LineFragment_T out;
float2 normal = in.a_normal.xy;
float halfWidth = length(normal);
float2 transformedAxisPos = (float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView).xy;
if (halfWidth != 0.0)
{
transformedAxisPos = CalcLineTransformedAxisPos(transformedAxisPos, in.a_position.xy + normal,
uniforms.u_modelView, halfWidth);
}
//out.halfLength = float2(sign(in.a_normal.z) * halfWidth, abs(in.a_normal.z));
float4 pos = float4(transformedAxisPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
float4 color = u_colorTex.sample(u_colorTexSampler, in.a_texCoords);
color.a *= uniforms.u_opacity;
out.color = color;
return out;
}
fragment float4 fsLine(const LineFragment_T in [[stage_in]])
{
// Disabled too agressive AA-like blurring of edges,
// see https://github.com/organicmaps/organicmaps/issues/6583.
//constexpr float kAntialiasingPixelsCount = 2.5;
//float currentW = abs(in.halfLength.x);
//float diff = in.halfLength.y - currentW;
float4 color = in.color;
//color.a *= mix(0.3, 1.0, saturate(diff / kAntialiasingPixelsCount));
return color;
}
// DashedLine
typedef struct
{
float3 a_position [[attribute(0)]];
float3 a_normal [[attribute(1)]];
float2 a_colorTexCoord [[attribute(2)]];
float4 a_maskTexCoord [[attribute(3)]];
} DashedLineVertex_T;
typedef struct
{
float4 position [[position]];
float4 color;
float2 maskTexCoord;
//float2 halfLength;
} DashedLineFragment_T;
vertex DashedLineFragment_T vsDashedLine(const DashedLineVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
DashedLineFragment_T out;
float2 normal = in.a_normal.xy;
float halfWidth = length(normal);
float2 transformedAxisPos = (float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView).xy;
if (halfWidth != 0.0)
{
transformedAxisPos = CalcLineTransformedAxisPos(transformedAxisPos, in.a_position.xy + normal,
uniforms.u_modelView, halfWidth);
}
float uOffset = min(length(float4(kShapeCoordScalar, 0.0, 0.0, 0.0) * uniforms.u_modelView) * in.a_maskTexCoord.x, 1.0);
out.maskTexCoord = float2(in.a_maskTexCoord.y + uOffset * in.a_maskTexCoord.z, in.a_maskTexCoord.w);
//out.halfLength = float2(sign(in.a_normal.z) * halfWidth, abs(in.a_normal.z));
float4 pos = float4(transformedAxisPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
float4 color = u_colorTex.sample(u_colorTexSampler, in.a_colorTexCoord);
color.a *= uniforms.u_opacity;
out.color = color;
return out;
}
fragment float4 fsDashedLine(const DashedLineFragment_T in [[stage_in]],
texture2d<float> u_maskTex [[texture(0)]],
sampler u_maskTexSampler [[sampler(0)]])
{
// Disabled too agressive AA-like blurring of edges,
// see https://github.com/organicmaps/organicmaps/issues/6583.
//constexpr float kAntialiasingPixelsCount = 2.5;
float4 color = in.color;
color.a *= u_maskTex.sample(u_maskTexSampler, in.maskTexCoord).a;
//float currentW = abs(in.halfLength.x);
//float diff = in.halfLength.y - currentW;
//color.a *= mix(0.3, 1.0, saturate(diff / kAntialiasingPixelsCount));
return color;
}
// CapJoin
typedef struct
{
float3 a_position [[attribute(0)]];
float3 a_normal [[attribute(1)]];
float2 a_texCoords [[attribute(2)]];
} CapJoinVertex_T;
typedef struct
{
float4 position [[position]];
float4 color;
float3 radius;
} CapJoinFragment_T;
typedef struct
{
float4 color [[color(0)]];
float depth [[depth(any)]];
} CapJoinFragment_Output;
vertex CapJoinFragment_T vsCapJoin(const CapJoinVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
CapJoinFragment_T out;
float4 p = float4(in.a_position, 1.0) * uniforms.u_modelView;
float4 pos = float4(in.a_normal.xy, 0.0, 0.0) + p;
out.position = ApplyPivotTransform(pos * uniforms.u_projection, uniforms.u_pivotTransform, 0.0);
out.radius = in.a_normal;
float4 color = u_colorTex.sample(u_colorTexSampler, in.a_texCoords);
color.a *= uniforms.u_opacity;
out.color = color;
return out;
}
fragment CapJoinFragment_Output fsCapJoin(const CapJoinFragment_T in [[stage_in]])
{
constexpr float kAntialiasingPixelsCount = 2.5;
CapJoinFragment_Output out;
float smallRadius = in.radius.z - kAntialiasingPixelsCount;
float stepValue = 1.0 - smoothstep(smallRadius * smallRadius, in.radius.z * in.radius.z,
in.radius.x * in.radius.x + in.radius.y * in.radius.y);
out.color = in.color;
out.color.a *= stepValue;
if (out.color.a < 0.001)
out.depth = 1.0;
else
out.depth = in.position.z;
return out;
}
// PathSymbol
typedef struct
{
float4 a_position [[attribute(0)]];
float2 a_normal [[attribute(1)]];
float2 a_texCoords [[attribute(2)]];
} PathSymbolVertex_T;
typedef struct
{
float4 position [[position]];
float2 texCoords;
} PathSymbolFragment_T;
vertex PathSymbolFragment_T vsPathSymbol(const PathSymbolVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
PathSymbolFragment_T out;
float4 pos = float4(in.a_position.xyz, 1.0) * uniforms.u_modelView;
float normalLen = length(in.a_normal);
float4 n = float4(in.a_position.xy + in.a_normal * kShapeCoordScalar, 0.0, 0.0) * uniforms.u_modelView;
float4 norm;
if (dot(n, n) != 0.0)
norm = normalize(n) * normalLen;
else
norm = float4(0.0, 0.0, 0.0, 0.0);
float4 shiftedPos = norm + pos;
out.position = ApplyPivotTransform(shiftedPos * uniforms.u_projection, uniforms.u_pivotTransform, 0.0);
out.texCoords = in.a_texCoords;
return out;
}
fragment float4 fsPathSymbol(const PathSymbolFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
float4 color = u_colorTex.sample(u_colorTexSampler, in.texCoords);
color.a *= uniforms.u_opacity;
return color;
}
// Text
typedef struct
{
float2 a_colorTexCoord [[attribute(0)]];
float2 a_maskTexCoord [[attribute(1)]];
float4 a_position [[attribute(2)]];
float2 a_normal [[attribute(3)]];
} TextVertex_T;
typedef struct
{
float4 position [[position]];
float4 color;
float2 maskTexCoord;
} TextFragment_T;
vertex TextFragment_T vsText(const TextVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(2)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
TextFragment_T out;
float4 pos = float4(in.a_position.xyz, 1.0) * uniforms.u_modelView;
float4 shiftedPos = float4(in.a_normal, 0.0, 0.0) + pos;
out.position = ApplyPivotTransform(shiftedPos * uniforms.u_projection, uniforms.u_pivotTransform, 0.0);
out.maskTexCoord = in.a_maskTexCoord;
out.color = u_colorTex.sample(u_colorTexSampler, in.a_colorTexCoord);
return out;
}
fragment float4 fsText(const TextFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_maskTex [[texture(0)]],
sampler u_maskTexSampler [[sampler(0)]])
{
float4 glyphColor = in.color;
float dist = u_maskTex.sample(u_maskTexSampler, in.maskTexCoord).a;
float2 contrastGamma = uniforms.u_contrastGamma;
float alpha = smoothstep(contrastGamma.x - contrastGamma.y, contrastGamma.x + contrastGamma.y, dist);
glyphColor.a *= alpha * uniforms.u_opacity;
return glyphColor;
}
// TextBillboard
vertex TextFragment_T vsTextBillboard(const TextVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(2)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
TextFragment_T out;
float4 pivot = float4(in.a_position.xyz, 1.0) * uniforms.u_modelView;
float4 offset = float4(in.a_normal, 0.0, 0.0) * uniforms.u_projection;
out.position = ApplyBillboardPivotTransform(pivot * uniforms.u_projection, uniforms.u_pivotTransform,
in.a_position.w * uniforms.u_zScale, offset.xy);
out.maskTexCoord = in.a_maskTexCoord;
out.color = u_colorTex.sample(u_colorTexSampler, in.a_colorTexCoord);
return out;
}
// TextOutlined
typedef struct
{
float2 a_colorTexCoord [[attribute(0)]];
float2 a_outlineColorTexCoord [[attribute(1)]];
float2 a_maskTexCoord [[attribute(2)]];
float4 a_position [[attribute(3)]];
float2 a_normal [[attribute(4)]];
} TextOutlinedVertex_T;
vertex TextFragment_T vsTextOutlined(const TextOutlinedVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(2)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
constexpr float kBaseDepthShift = -10.0;
TextFragment_T out;
float isOutline = step(0.5, uniforms.u_isOutlinePass);
float notOutline = 1.0 - isOutline;
float depthShift = kBaseDepthShift * isOutline;
float4 pos = (float4(in.a_position.xyz, 1.0) + float4(0.0, 0.0, depthShift, 0.0)) * uniforms.u_modelView;
float4 shiftedPos = float4(in.a_normal, 0.0, 0.0) + pos;
out.position = ApplyPivotTransform(shiftedPos * uniforms.u_projection, uniforms.u_pivotTransform, 0.0);
out.maskTexCoord = in.a_maskTexCoord;
float2 colorTexCoord = in.a_colorTexCoord * notOutline + in.a_outlineColorTexCoord * isOutline;
out.color = u_colorTex.sample(u_colorTexSampler, colorTexCoord);
return out;
}
// TextOutlinedBillboard
vertex TextFragment_T vsTextOutlinedBillboard(const TextOutlinedVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(2)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
constexpr float kBaseDepthShift = -10.0;
TextFragment_T out;
float isOutline = step(0.5, uniforms.u_isOutlinePass);
float depthShift = kBaseDepthShift * isOutline;
float4 pivot = (float4(in.a_position.xyz, 1.0) + float4(0.0, 0.0, depthShift, 0.0)) * uniforms.u_modelView;
float4 offset = float4(in.a_normal, 0.0, 0.0) * uniforms.u_projection;
out.position = ApplyBillboardPivotTransform(pivot * uniforms.u_projection, uniforms.u_pivotTransform,
in.a_position.w * uniforms.u_zScale, offset.xy);
out.maskTexCoord = in.a_maskTexCoord;
float2 colorTexCoord = mix(in.a_colorTexCoord, in.a_outlineColorTexCoord, isOutline);
out.color = u_colorTex.sample(u_colorTexSampler, colorTexCoord);
return out;
}
// TextFixed
/*
fragment float4 fsTextFixed(const TextFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_maskTex [[texture(0)]],
sampler u_maskTexSampler [[sampler(0)]])
{
float4 glyphColor = in.color;
float alpha = u_maskTex.sample(u_maskTexSampler, in.maskTexCoord).a;
glyphColor.a *= alpha * uniforms.u_opacity;
return glyphColor;
}
*/
// ColoredSymbol
typedef struct
{
float3 a_position [[attribute(0)]];
float4 a_normal [[attribute(1)]];
float4 a_colorTexCoords [[attribute(2)]];
} ColoredSymbolVertex_T;
typedef struct
{
float4 position [[position]];
float4 normal;
float4 color;
} ColoredSymbolFragment_T;
typedef struct
{
float4 color [[color(0)]];
float depth [[depth(any)]];
} ColoredSymbolOut_T;
vertex ColoredSymbolFragment_T vsColoredSymbol(const ColoredSymbolVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
ColoredSymbolFragment_T out;
float4 p = float4(in.a_position, 1.0) * uniforms.u_modelView;
float4 pos = float4(in.a_normal.xy + in.a_colorTexCoords.zw, 0.0, 0.0) + p;
out.position = ApplyPivotTransform(pos * uniforms.u_projection, uniforms.u_pivotTransform, 0.0);
out.color = u_colorTex.sample(u_colorTexSampler, in.a_colorTexCoords.xy);
out.normal = in.a_normal;
return out;
}
vertex ColoredSymbolFragment_T vsColoredSymbolBillboard(const ColoredSymbolVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
ColoredSymbolFragment_T out;
float4 pivot = float4(in.a_position.xyz, 1.0) * uniforms.u_modelView;
float4 offset = float4(in.a_normal.xy + in.a_colorTexCoords.zw, 0.0, 0.0) * uniforms.u_projection;
out.position = ApplyBillboardPivotTransform(pivot * uniforms.u_projection, uniforms.u_pivotTransform, 0.0, offset.xy);
out.color = u_colorTex.sample(u_colorTexSampler, in.a_colorTexCoords.xy);
out.normal = in.a_normal;
return out;
}
fragment ColoredSymbolOut_T fsColoredSymbol(const ColoredSymbolFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]])
{
constexpr float kAntialiasingPixelsCount = 2.5;
ColoredSymbolOut_T out;
float r1 = (in.normal.z - kAntialiasingPixelsCount) * (in.normal.z - kAntialiasingPixelsCount);
float r2 = in.normal.x * in.normal.x + in.normal.y * in.normal.y;
float r3 = in.normal.z * in.normal.z;
float alpha = mix(step(r3, r2), smoothstep(r1, r3, r2), in.normal.w);
float4 finalColor = in.color;
finalColor.a = finalColor.a * uniforms.u_opacity * (1.0 - alpha);
if (finalColor.a == 0.0)
out.depth = 1.0;
else
out.depth = in.position.z;
out.color = finalColor;
return out;
}
// Texturing
typedef struct
{
float4 a_position [[attribute(0)]];
float2 a_normal [[attribute(1)]];
float2 a_colorTexCoords [[attribute(2)]];
} TexturingVertex_T;
typedef struct
{
float4 position [[position]];
float2 colorTexCoords;
} TexturingFragment_T;
vertex TexturingFragment_T vsTexturing(const TexturingVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
TexturingFragment_T out;
float4 pos = float4(in.a_position.xyz, 1.0) * uniforms.u_modelView;
float4 shiftedPos = float4(in.a_normal, 0.0, 0.0) + pos;
out.position = ApplyPivotTransform(shiftedPos * uniforms.u_projection, uniforms.u_pivotTransform, 0.0);
out.colorTexCoords = in.a_colorTexCoords;
return out;
}
vertex TexturingFragment_T vsTexturingBillboard(const TexturingVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
TexturingFragment_T out;
float4 pivot = float4(in.a_position.xyz, 1.0) * uniforms.u_modelView;
float4 offset = float4(in.a_normal, 0.0, 0.0) * uniforms.u_projection;
out.position = ApplyBillboardPivotTransform(pivot * uniforms.u_projection, uniforms.u_pivotTransform,
in.a_position.w * uniforms.u_zScale, offset.xy);
out.colorTexCoords = in.a_colorTexCoords;
return out;
}
fragment float4 fsTexturing(const TexturingFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
float4 finalColor = u_colorTex.sample(u_colorTexSampler, in.colorTexCoords.xy);
finalColor.a *= uniforms.u_opacity;
return finalColor;
}
// MaskedTexturing
typedef struct
{
float4 a_position [[attribute(0)]];
float2 a_normal [[attribute(1)]];
float2 a_colorTexCoords [[attribute(2)]];
float2 a_maskTexCoords [[attribute(3)]];
} MaskedTexturingVertex_T;
typedef struct
{
float4 position [[position]];
float2 colorTexCoords;
float2 maskTexCoords;
} MaskedTexturingFragment_T;
vertex MaskedTexturingFragment_T vsMaskedTexturing(const MaskedTexturingVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
MaskedTexturingFragment_T out;
float4 pos = float4(in.a_position.xyz, 1.0) * uniforms.u_modelView;
float4 shiftedPos = float4(in.a_normal, 0.0, 0.0) + pos;
out.position = ApplyPivotTransform(shiftedPos * uniforms.u_projection, uniforms.u_pivotTransform, 0.0);
out.colorTexCoords = in.a_colorTexCoords;
out.maskTexCoords = in.a_maskTexCoords;
return out;
}
vertex MaskedTexturingFragment_T vsMaskedTexturingBillboard(const MaskedTexturingVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
MaskedTexturingFragment_T out;
float4 pivot = float4(in.a_position.xyz, 1.0) * uniforms.u_modelView;
float4 offset = float4(in.a_normal, 0.0, 0.0) * uniforms.u_projection;
out.position = ApplyBillboardPivotTransform(pivot * uniforms.u_projection, uniforms.u_pivotTransform,
in.a_position.w * uniforms.u_zScale, offset.xy);
out.colorTexCoords = in.a_colorTexCoords;
out.maskTexCoords = in.a_maskTexCoords;
return out;
}
fragment float4 fsMaskedTexturing(const MaskedTexturingFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]],
texture2d<float> u_maskTex [[texture(1)]],
sampler u_maskTexSampler [[sampler(1)]])
{
float4 finalColor = u_colorTex.sample(u_colorTexSampler, in.colorTexCoords.xy) *
u_maskTex.sample(u_maskTexSampler, in.maskTexCoords.xy);
finalColor.a *= uniforms.u_opacity;
return finalColor;
}
// UserMark
typedef struct
{
float3 a_position [[attribute(0)]];
float3 a_normalAndAnimateOrZ [[attribute(1)]];
float4 a_texCoords [[attribute(2)]];
float4 a_color [[attribute(3)]];
} UserMarkVertex_T;
typedef struct
{
float4 position [[position]];
float4 texCoords;
float4 maskColor;
} UserMarkFragment_T;
typedef struct
{
float4 color [[color(0)]];
float depth [[depth(any)]];
} UserMarkOut_T;
vertex UserMarkFragment_T vsUserMark(const UserMarkVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
UserMarkFragment_T out;
float2 normal = in.a_normalAndAnimateOrZ.xy;
if (in.a_normalAndAnimateOrZ.z > 0.0)
normal = uniforms.u_interpolation * normal;
float4 p = float4(in.a_position, 1.0) * uniforms.u_modelView;
float4 pos = float4(normal, 0.0, 0.0) + p;
float4 projectedPivot = p * uniforms.u_projection;
out.position = ApplyPivotTransform(pos * uniforms.u_projection, uniforms.u_pivotTransform, 0.0);
float newZ = projectedPivot.y / projectedPivot.w * 0.5 + 0.5;
out.position.z = abs(in.a_normalAndAnimateOrZ.z) * newZ + (1.0 - abs(in.a_normalAndAnimateOrZ.z)) * out.position.z;
out.texCoords = in.a_texCoords;
out.maskColor = in.a_color;
return out;
}
vertex UserMarkFragment_T vsUserMarkBillboard(const UserMarkVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
UserMarkFragment_T out;
float2 normal = in.a_normalAndAnimateOrZ.xy;
if (in.a_normalAndAnimateOrZ.z > 0.0)
normal = uniforms.u_interpolation * normal;
float4 pivot = float4(in.a_position.xyz, 1.0) * uniforms.u_modelView;
float4 offset = float4(normal, 0.0, 0.0) * uniforms.u_projection;
float4 projectedPivot = pivot * uniforms.u_projection;
out.position = ApplyBillboardPivotTransform(projectedPivot, uniforms.u_pivotTransform, 0.0, offset.xy);
float newZ = projectedPivot.y / projectedPivot.w * 0.5 + 0.5;
out.position.z = abs(in.a_normalAndAnimateOrZ.z) * newZ + (1.0 - abs(in.a_normalAndAnimateOrZ.z)) * out.position.z;
out.texCoords = in.a_texCoords;
out.maskColor = in.a_color;
return out;
}
fragment UserMarkOut_T fsUserMark(const UserMarkFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
UserMarkOut_T out;
float4 color = u_colorTex.sample(u_colorTexSampler, in.texCoords.xy);
float4 bgColor = u_colorTex.sample(u_colorTexSampler, in.texCoords.zw) * float4(in.maskColor.xyz, 1.0);
float4 finalColor = mix(color, mix(bgColor, color, color.a), bgColor.a);
finalColor.a = clamp(color.a + bgColor.a, 0.0, 1.0) * uniforms.u_opacity * in.maskColor.w;
if (finalColor.a < 0.001)
out.depth = 1.0;
else
out.depth = in.position.z;
out.color = finalColor;
return out;
}

View file

@ -0,0 +1,241 @@
#include <metal_stdlib>
#include <simd/simd.h>
#include "shaders_lib.h"
using namespace metal;
typedef struct
{
float4x4 u_modelView;
float4x4 u_projection;
float4x4 u_pivotTransform;
float4 u_routeParams;
float4 u_color;
float4 u_maskColor;
float4 u_outlineColor;
float4 u_fakeColor;
float4 u_fakeOutlineColor;
packed_float2 u_fakeBorders;
packed_float2 u_pattern;
packed_float2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
} Uniforms_T;
// Route/RouteDash
typedef struct
{
float3 a_position [[attribute(0)]];
float2 a_normal [[attribute(1)]];
float3 a_length [[attribute(2)]];
float4 a_color [[attribute(3)]];
} RouteVertex_T;
typedef struct
{
float4 position [[position]];
float3 lengthParams;
float4 color;
} RouteFragment_T;
vertex RouteFragment_T vsRoute(const RouteVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
RouteFragment_T out;
float2 transformedAxisPos = (float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView).xy;
float2 len = float2(in.a_length.x, in.a_length.z);
if (dot(in.a_normal, in.a_normal) != 0.0)
{
float2 norm = in.a_normal * uniforms.u_routeParams.x;
transformedAxisPos = CalcLineTransformedAxisPos(transformedAxisPos, in.a_position.xy + norm,
uniforms.u_modelView, length(norm));
if (uniforms.u_routeParams.y != 0.0)
len = float2(in.a_length.x + in.a_length.y * uniforms.u_routeParams.y, in.a_length.z);
}
out.lengthParams = float3(len, uniforms.u_routeParams.z);
out.color = in.a_color;
float4 pos = float4(transformedAxisPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
return out;
}
fragment float4 fsRoute(const RouteFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
if (in.lengthParams.x < in.lengthParams.z)
discard_fragment();
constexpr float kAntialiasingThreshold = 0.92;
constexpr float kOutlineThreshold1 = 0.81;
constexpr float kOutlineThreshold2 = 0.71;
float2 fb = uniforms.u_fakeBorders;
float2 coefs = step(in.lengthParams.xx, fb);
coefs.y = 1.0 - coefs.y;
float4 mainColor = mix(uniforms.u_color, uniforms.u_fakeColor, coefs.x);
mainColor = mix(mainColor, uniforms.u_fakeColor, coefs.y);
float4 mainOutlineColor = mix(uniforms.u_outlineColor, uniforms.u_fakeOutlineColor, coefs.x);
mainOutlineColor = mix(mainOutlineColor, uniforms.u_fakeOutlineColor, coefs.y);
float4 color = mix(mix(mainColor, float4(in.color.rgb, 1.0), in.color.a), mainColor,
step(uniforms.u_routeParams.w, 0.0));
color = mix(color, mainOutlineColor, step(kOutlineThreshold1, abs(in.lengthParams.y)));
color = mix(color, mainOutlineColor,
smoothstep(kOutlineThreshold2, kOutlineThreshold1, abs(in.lengthParams.y)));
color.a *= (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(in.lengthParams.y)));
color = float4(mix(color.rgb, uniforms.u_maskColor.rgb, uniforms.u_maskColor.a), color.a);
return color;
}
float AlphaFromPattern(float curLen, float2 dashGapLen)
{
float len = dashGapLen.x + dashGapLen.y;
float offset = fract(curLen / len) * len;
return step(offset, dashGapLen.x);
}
fragment float4 fsRouteDash(const RouteFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
if (in.lengthParams.x < in.lengthParams.z)
discard_fragment();
constexpr float kAntialiasingThreshold = 0.92;
float2 fb = uniforms.u_fakeBorders;
float2 coefs = step(in.lengthParams.xx, fb);
coefs.y = 1.0 - coefs.y;
float4 mainColor = mix(uniforms.u_color, uniforms.u_fakeColor, coefs.x);
mainColor = mix(mainColor, uniforms.u_fakeColor, coefs.y);
float4 color = mainColor + in.color;
float a = 1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(in.lengthParams.y));
color.a *= (a * AlphaFromPattern(in.lengthParams.x, uniforms.u_pattern));
color = float4(mix(color.rgb, uniforms.u_maskColor.rgb, uniforms.u_maskColor.a), color.a);
return color;
}
// RouteArrow
typedef struct
{
float4 a_position [[attribute(0)]];
float2 a_normal [[attribute(1)]];
float2 a_texCoords [[attribute(2)]];
} RouteArrowVertex_T;
typedef struct
{
float4 position [[position]];
float2 texCoords;
} RouteArrowFragment_T;
typedef struct
{
float4 color [[color(0)]];
float depth [[depth(any)]];
} RouteArrowFragment_Output;
vertex RouteArrowFragment_T vsRouteArrow(const RouteArrowVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
RouteArrowFragment_T out;
float2 transformedAxisPos = (float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView).xy;
if (dot(in.a_normal, in.a_normal) != 0.0)
{
float2 norm = in.a_normal * uniforms.u_arrowHalfWidth;
transformedAxisPos = CalcLineTransformedAxisPos(transformedAxisPos, in.a_position.xy + norm,
uniforms.u_modelView, length(norm));
}
out.texCoords = in.a_texCoords;
float4 pos = float4(transformedAxisPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
return out;
}
fragment RouteArrowFragment_Output fsRouteArrow(const RouteArrowFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
RouteArrowFragment_Output output;
float4 color = u_colorTex.sample(u_colorTexSampler, in.texCoords);
color.a *= uniforms.u_opacity;
output.depth = in.position.z;
if (color.a < 0.001)
output.depth = 1.0;
output.color = float4(mix(color.rgb, uniforms.u_maskColor.rgb, uniforms.u_maskColor.a), color.a);
return output;
}
// RouteMarker
typedef struct
{
float4 a_position [[attribute(0)]];
float3 a_normal [[attribute(1)]];
float4 a_color [[attribute(2)]];
} RouteMarkerVertex_T;
typedef struct
{
float4 position [[position]];
float4 radius;
float4 color;
} RouteMarkerFragment_T;
typedef struct
{
float4 color [[color(0)]];
float depth [[depth(any)]];
} RouteMarkerFragment_Output;
vertex RouteMarkerFragment_T vsRouteMarker(const RouteMarkerVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
RouteMarkerFragment_T out;
float r = uniforms.u_routeParams.x * in.a_normal.z;
float2 cs = uniforms.u_angleCosSin;
float2 normal = float2(in.a_normal.x * cs.x - in.a_normal.y * cs.y,
in.a_normal.x * cs.y + in.a_normal.y * cs.x);
float4 radius = float4(normal * r, r, in.a_position.w);
float4 pos = float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView;
float2 shiftedPos = radius.xy + pos.xy;
pos = float4(shiftedPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.radius = radius;
out.color = in.a_color;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
return out;
}
fragment RouteMarkerFragment_Output fsRouteMarker(const RouteMarkerFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
if (uniforms.u_routeParams.y > in.radius.w)
discard_fragment();
RouteMarkerFragment_Output output;
constexpr float kAntialiasingPixelsCount = 2.5;
float4 color = in.color;
float aaRadius = max(in.radius.z - kAntialiasingPixelsCount, 0.0);
float stepValue = smoothstep(aaRadius * aaRadius, in.radius.z * in.radius.z,
dot(in.radius.xy, in.radius.xy));
color.a = color.a * uniforms.u_opacity * (1.0 - stepValue);
output.depth = in.position.z;
if (color.a < 0.001)
output.depth = 1.0;
output.color = float4(mix(color.rgb, uniforms.u_maskColor.rgb, uniforms.u_maskColor.a), color.a);
return output;
}

View file

@ -0,0 +1,40 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
typedef struct
{
float2 a_position [[attribute(0)]];
float2 a_texCoords [[attribute(1)]];
} Vertex_T;
typedef struct
{
float4 position [[position]];
float2 texCoords;
} Fragment_T;
typedef struct
{
float u_opacity;
float u_invertV;
} Uniforms_T;
vertex Fragment_T vsScreenQuad(const Vertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
Fragment_T out;
out.position = float4(in.a_position, 0.0, 1.0);
out.texCoords = mix(in.a_texCoords, float2(in.a_texCoords.x, 1.0 - in.a_texCoords.y), uniforms.u_invertV);
return out;
}
fragment float4 fsScreenQuad(const Fragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
float4 color = u_colorTex.sample(u_colorTexSampler, in.texCoords);
color.a *= uniforms.u_opacity;
return color;
}

View file

@ -0,0 +1,17 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
// Scale factor in shape's coordinates transformation from tile's coordinate
// system.
constant float kShapeCoordScalar = 1000.0;
// This function applies a 2D->3D transformation matrix.
float4 ApplyPivotTransform(float4 pivot, float4x4 pivotTransform, float pivotRealZ);
// This function applies a 2D->3D transformation matrix to billboards.
float4 ApplyBillboardPivotTransform(float4 pivot, float4x4 pivotTransform, float pivotRealZ, float2 offset);
// This function calculates transformed position on an axis for line shaders family.
float2 CalcLineTransformedAxisPos(float2 originalAxisPos, float2 shiftedPos, float4x4 modelView, float halfWidth);

View file

@ -0,0 +1,31 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
float4 ApplyPivotTransform(float4 pivot, float4x4 pivotTransform, float pivotRealZ)
{
float4 transformedPivot = pivot;
float w = transformedPivot.w;
transformedPivot.xyw = (pivotTransform * float4(transformedPivot.xy, pivotRealZ, w)).xyw;
transformedPivot.z *= transformedPivot.w / w;
return transformedPivot;
}
float2 CalcLineTransformedAxisPos(float2 originalAxisPos, float2 shiftedPos, float4x4 modelView, float halfWidth)
{
float2 p = (float4(shiftedPos, 0.0, 1.0) * modelView).xy;
float2 d = p - originalAxisPos;
if (dot(d, d) != 0.0)
return originalAxisPos + normalize(d) * halfWidth;
else
return originalAxisPos;
}
float4 ApplyBillboardPivotTransform(float4 pivot, float4x4 pivotTransform, float pivotRealZ, float2 offset)
{
float logicZ = pivot.z / pivot.w;
float4 transformedPivot = pivotTransform * float4(pivot.xy, pivotRealZ, pivot.w);
float4 scale = pivotTransform * float4(1.0, -1.0, 0.0, 1.0);
return float4(transformedPivot.xy / transformedPivot.w, logicZ, 1.0) + float4(offset / scale.w * scale.x, 0.0, 0.0);
}

View file

@ -0,0 +1,154 @@
#include <metal_stdlib>
#include <simd/simd.h>
#include "shaders_lib.h"
using namespace metal;
typedef struct
{
float4x4 u_modelView;
float4x4 u_projection;
float4x4 u_pivotTransform;
packed_float3 u_position;
float u_dummy1;
packed_float2 u_lineParams;
float u_accuracy;
float u_zScale;
float u_opacity;
float u_azimut;
} Uniforms_T;
typedef struct
{
float2 a_normal [[attribute(0)]];
float2 a_colorTexCoords [[attribute(1)]];
} Vertex_T;
// Accuracy
typedef struct
{
float4 position [[position]];
float2 colorTexCoords;
} FragmentAccuracy_T;
vertex FragmentAccuracy_T vsAccuracy(const Vertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
float3 uPosition = uniforms.u_position;
float4 position = float4(uPosition.xy, 0.0, 1.0) * uniforms.u_modelView;
float4 normal = float4(in.a_normal * uniforms.u_accuracy, 0.0, 0.0);
position = (position + normal) * uniforms.u_projection;
FragmentAccuracy_T out;
out.position = ApplyPivotTransform(position, uniforms.u_pivotTransform, uPosition.z * uniforms.u_zScale);
out.colorTexCoords = in.a_colorTexCoords;
return out;
}
fragment float4 fsAccuracy(const FragmentAccuracy_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
float4 color = u_colorTex.sample(u_colorTexSampler, in.colorTexCoords);
color.a *= uniforms.u_opacity;
return color;
}
// MyPosition
typedef struct
{
float4 position [[position]];
float2 colorTexCoords;
} FragmentMyPosition_T;
vertex FragmentMyPosition_T vsMyPosition(const Vertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
float cosV;
float sinV = sincos(uniforms.u_azimut, cosV);
float4x4 rotation;
rotation[0] = float4(cosV, sinV, 0.0, 0.0);
rotation[1] = float4(-sinV, cosV, 0.0, 0.0);
rotation[2] = float4(0.0, 0.0, 1.0, 0.0);
rotation[3] = float4(0.0, 0.0, 0.0, 1.0);
float4 pos = float4(uniforms.u_position, 1.0) * uniforms.u_modelView;
float4 normal = float4(in.a_normal, 0.0, 0.0);
float4 shiftedPos = normal * rotation + pos;
FragmentMyPosition_T out;
out.position = ApplyPivotTransform(shiftedPos * uniforms.u_projection, uniforms.u_pivotTransform, 0.0);
out.colorTexCoords = in.a_colorTexCoords;
return out;
}
fragment float4 fsMyPosition(const FragmentMyPosition_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
float4 color = u_colorTex.sample(u_colorTexSampler, in.colorTexCoords);
color.a *= uniforms.u_opacity;
return color;
}
// SelectionLine
typedef struct
{
float3 a_position [[attribute(0)]];
float2 a_normal [[attribute(1)]];
float2 a_colorTexCoords [[attribute(2)]];
float3 a_length [[attribute(3)]];
} SelectionLineVertex_T;
typedef struct
{
float4 position [[position]];
float4 color;
float lengthY;
} SelectionLineFragment_T;
vertex SelectionLineFragment_T vsSelectionLine(const SelectionLineVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
SelectionLineFragment_T out;
float2 transformedAxisPos = (float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView).xy;
float2 len = float2(in.a_length.x, in.a_length.z);
float2 lineParams = uniforms.u_lineParams;
if (dot(in.a_normal, in.a_normal) != 0.0)
{
float2 norm = in.a_normal * lineParams.x;
transformedAxisPos = CalcLineTransformedAxisPos(transformedAxisPos, in.a_position.xy + norm,
uniforms.u_modelView, length(norm));
if (lineParams.y != 0.0)
len = float2(in.a_length.x + in.a_length.y * lineParams.y, in.a_length.z);
}
out.lengthY = len.y;
float4 color = u_colorTex.sample(u_colorTexSampler, in.a_colorTexCoords);
color.a *= uniforms.u_opacity;
out.color = color;
float4 pos = float4(transformedAxisPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
return out;
}
fragment float4 fsSelectionLine(const SelectionLineFragment_T in [[stage_in]])
{
constexpr float kAntialiasingThreshold = 0.92;
float4 color = in.color;
color.a *= (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(in.lengthY)));
return color;
}

View file

@ -0,0 +1,377 @@
// Implementation of Subpixel Morphological Antialiasing (SMAA) is based on https://github.com/iryoku/smaa
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
typedef struct
{
float4 u_framebufferMetrics;
} Uniforms_T;
typedef struct
{
float2 a_pos [[attribute(0)]];
float2 a_tcoord [[attribute(1)]];
} SmaaVertex_T;
// SmaaEdges
typedef struct
{
float4 position [[position]];
float4 offset0;
float4 offset1;
float4 offset2;
float2 coords;
} SmaaEdgesFragment_T;
vertex SmaaEdgesFragment_T vsSmaaEdges(const SmaaVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
SmaaEdgesFragment_T out;
out.position = float4(in.a_pos, 0.0, 1.0);
float2 tcoord = float2(in.a_tcoord.x, 1.0 - in.a_tcoord.y);
out.coords = tcoord;
float4 coords1 = uniforms.u_framebufferMetrics.xyxy;
float4 coords2 = tcoord.xyxy;
out.offset0 = coords1 * float4(-1.0, 0.0, 0.0, -1.0) + coords2;
out.offset1 = coords1 * float4( 1.0, 0.0, 0.0, 1.0) + coords2;
out.offset2 = coords1 * float4(-2.0, 0.0, 0.0, -2.0) + coords2;
return out;
}
// SMAA_THRESHOLD specifies the threshold or sensitivity to edges.
// Lowering this value you will be able to detect more edges at the expense of
// performance.
// Range: [0, 0.5]
// 0.1 is a reasonable value, and allows to catch most visible edges.
// 0.05 is a rather overkill value, that allows to catch 'em all.
#define SMAA_THRESHOLD 0.05
constant float2 kThreshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD);
// If there is an neighbor edge that has SMAA_LOCAL_CONTRAST_FACTOR times
// bigger contrast than current edge, current edge will be discarded.
// This allows to eliminate spurious crossing edges, and is based on the fact
// that, if there is too much contrast in a direction, that will hide
// perceptually contrast in the other neighbors.
#define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0
// Standard relative luminance weights.
// https://en.wikipedia.org/wiki/Relative_luminance
constant float3 kWeights = float3(0.2126, 0.7152, 0.0722);
fragment float4 fsSmaaEdges(const SmaaEdgesFragment_T in [[stage_in]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
// Calculate lumas.
float L = dot(u_colorTex.sample(u_colorTexSampler, in.coords).rgb, kWeights);
float Lleft = dot(u_colorTex.sample(u_colorTexSampler, in.offset0.xy).rgb, kWeights);
float Ltop = dot(u_colorTex.sample(u_colorTexSampler, in.offset0.zw).rgb, kWeights);
// We do the usual threshold.
float4 delta;
delta.xy = abs(L - float2(Lleft, Ltop));
float2 edges = step(kThreshold, delta.xy);
if (dot(edges, float2(1.0, 1.0)) == 0.0)
discard_fragment();
// Calculate right and bottom deltas.
float Lright = dot(u_colorTex.sample(u_colorTexSampler, in.offset1.xy).rgb, kWeights);
float Lbottom = dot(u_colorTex.sample(u_colorTexSampler, in.offset1.zw).rgb, kWeights);
delta.zw = abs(L - float2(Lright, Lbottom));
// Calculate the maximum delta in the direct neighborhood.
float2 maxDelta = max(delta.xy, delta.zw);
// Calculate left-left and top-top deltas.
float Lleftleft = dot(u_colorTex.sample(u_colorTexSampler, in.offset2.xy).rgb, kWeights);
float Ltoptop = dot(u_colorTex.sample(u_colorTexSampler, in.offset2.zw).rgb, kWeights);
delta.zw = abs(float2(Lleft, Ltop) - float2(Lleftleft, Ltoptop));
// Calculate the final maximum delta.
maxDelta = max(maxDelta.xy, delta.zw);
float finalDelta = max(maxDelta.x, maxDelta.y);
// Local contrast adaptation.
edges *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
return float4(edges, 0.0, 1.0);
}
// SmaaBlendingWeight
typedef struct
{
float4 position [[position]];
float4 offset0;
float4 offset1;
float4 offset2;
float4 coords;
} SmaaBlendingWeightFragment_T;
// SMAA_MAX_SEARCH_STEPS specifies the maximum steps performed in the
// horizontal/vertical pattern searches, at each side of the pixel.
#define SMAA_MAX_SEARCH_STEPS 8.0
constant float4 kMaxSearchSteps = float4(-2.0 * SMAA_MAX_SEARCH_STEPS, 2.0 * SMAA_MAX_SEARCH_STEPS,
-2.0 * SMAA_MAX_SEARCH_STEPS, 2.0 * SMAA_MAX_SEARCH_STEPS);
vertex SmaaBlendingWeightFragment_T vsSmaaBlendingWeight(const SmaaVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
SmaaBlendingWeightFragment_T out;
out.position = float4(in.a_pos, 0.0, 1.0);
float2 tcoord = float2(in.a_tcoord.x, 1.0 - in.a_tcoord.y);
out.coords = float4(tcoord, tcoord * uniforms.u_framebufferMetrics.zw);
// We will use these offsets for the searches.
float4 coords1 = uniforms.u_framebufferMetrics.xyxy;
float4 coords2 = tcoord.xyxy;
out.offset0 = coords1 * float4(-0.25, -0.125, 1.25, -0.125) + coords2;
out.offset1 = coords1 * float4(-0.125, -0.25, -0.125, 1.25) + coords2;
// And these for the searches, they indicate the ends of the loops.
out.offset2 = uniforms.u_framebufferMetrics.xxyy * kMaxSearchSteps + float4(out.offset0.xz, out.offset1.yw);
return out;
}
#define SMAA_SEARCHTEX_SIZE float2(66.0, 33.0)
#define SMAA_SEARCHTEX_PACKED_SIZE float2(64.0, 16.0)
#define SMAA_AREATEX_MAX_DISTANCE 16.0
#define SMAA_AREATEX_PIXEL_SIZE (float2(1.0 / 256.0, 1.0 / 1024.0))
constant float2 kAreaTexMaxDistance = float2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE);
constant float kActivationThreshold = 0.8281;
float SMAASearchLength(texture2d<float> u_smaaSearch, sampler u_smaaSearchSampler,
float2 e, float offset)
{
// The texture is flipped vertically, with left and right cases taking half
// of the space horizontally.
float2 scale = SMAA_SEARCHTEX_SIZE * float2(0.5, -1.0);
float2 bias = SMAA_SEARCHTEX_SIZE * float2(offset, 1.0);
// Scale and bias to access texel centers.
scale += float2(-1.0, 1.0);
bias += float2( 0.5, -0.5);
// Convert from pixel coordinates to texcoords.
// (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped).
scale *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE;
bias *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE;
// Lookup the search texture.
return u_smaaSearch.sample(u_smaaSearchSampler, scale * e + bias, level(0)).a;
}
float SMAASearchXLeft(texture2d<float> u_colorTex, sampler u_colorTexSampler,
texture2d<float> u_smaaSearch, sampler u_smaaSearchSampler,
float2 texcoord, float end, float4 framebufferMetrics)
{
float2 e = float2(0.0, 1.0);
while (texcoord.x > end && e.g > kActivationThreshold && e.r == 0.0)
{
e = u_colorTex.sample(u_colorTexSampler, texcoord, level(0)).rg;
texcoord = float2(-2.0, 0.0) * framebufferMetrics.xy + texcoord;
}
float offset = 3.25 - (255.0 / 127.0) * SMAASearchLength(u_smaaSearch, u_smaaSearchSampler, e, 0.0);
return framebufferMetrics.x * offset + texcoord.x;
}
float SMAASearchXRight(texture2d<float> u_colorTex, sampler u_colorTexSampler,
texture2d<float> u_smaaSearch, sampler u_smaaSearchSampler,
float2 texcoord, float end, float4 framebufferMetrics)
{
float2 e = float2(0.0, 1.0);
while (texcoord.x < end && e.g > kActivationThreshold && e.r == 0.0)
{
e = u_colorTex.sample(u_colorTexSampler, texcoord, level(0)).rg;
texcoord = float2(2.0, 0.0) * framebufferMetrics.xy + texcoord;
}
float offset = 3.25 - (255.0 / 127.0) * SMAASearchLength(u_smaaSearch, u_smaaSearchSampler, e, 0.5);
return -framebufferMetrics.x * offset + texcoord.x;
}
float SMAASearchYUp(texture2d<float> u_colorTex, sampler u_colorTexSampler,
texture2d<float> u_smaaSearch, sampler u_smaaSearchSampler,
float2 texcoord, float end, float4 framebufferMetrics)
{
float2 e = float2(1.0, 0.0);
while (texcoord.y > end && e.r > kActivationThreshold && e.g == 0.0)
{
e = u_colorTex.sample(u_colorTexSampler, texcoord, level(0)).rg;
texcoord = float2(0.0, -2.0) * framebufferMetrics.xy + texcoord;
}
float offset = 3.25 - (255.0 / 127.0) * SMAASearchLength(u_smaaSearch, u_smaaSearchSampler, e.gr, 0.0);
return framebufferMetrics.y * offset + texcoord.y;
}
float SMAASearchYDown(texture2d<float> u_colorTex, sampler u_colorTexSampler,
texture2d<float> u_smaaSearch, sampler u_smaaSearchSampler,
float2 texcoord, float end, float4 framebufferMetrics)
{
float2 e = float2(1.0, 0.0);
while (texcoord.y < end && e.r > kActivationThreshold && e.g == 0.0)
{
e = u_colorTex.sample(u_colorTexSampler, texcoord, level(0)).rg;
texcoord = float2(0.0, 2.0) * framebufferMetrics.xy + texcoord;
}
float offset = 3.25 - (255.0 / 127.0) * SMAASearchLength(u_smaaSearch, u_smaaSearchSampler, e.gr, 0.5);
return -framebufferMetrics.y * offset + texcoord.y;
}
// Here, we have the distance and both crossing edges. So, what are the areas
// at each side of current edge?
float2 SMAAArea(texture2d<float> u_smaaArea, sampler u_smaaAreaSampler, float2 dist, float e1, float e2)
{
// Rounding prevents precision errors of bilinear filtering.
float2 texcoord = kAreaTexMaxDistance * round(4.0 * float2(e1, e2)) + dist;
// We do a scale and bias for mapping to texel space.
texcoord = SMAA_AREATEX_PIXEL_SIZE * (texcoord + 0.5);
return u_smaaArea.sample(u_smaaAreaSampler, texcoord, level(0)).rg;
}
fragment float4 fsSmaaBlendingWeight(const SmaaBlendingWeightFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]],
texture2d<float> u_smaaArea [[texture(1)]],
sampler u_smaaAreaSampler [[sampler(1)]],
texture2d<float> u_smaaSearch [[texture(2)]],
sampler u_smaaSearchSampler [[sampler(2)]])
{
float4 weights = float4(0.0, 0.0, 0.0, 0.0);
float2 e = u_colorTex.sample(u_colorTexSampler, in.coords.xy).rg;
if (e.g > 0.0) // Edge at north
{
float2 d;
// Find the distance to the left.
float3 coords;
coords.x = SMAASearchXLeft(u_colorTex, u_colorTexSampler, u_smaaSearch, u_smaaSearchSampler,
in.offset0.xy, in.offset2.x, uniforms.u_framebufferMetrics);
coords.y = in.offset1.y;
d.x = coords.x;
// Now fetch the left crossing edges, two at a time using bilinear
// filtering. Sampling at -0.25 enables to discern what value each edge has.
float e1 = u_colorTex.sample(u_colorTexSampler, coords.xy, level(0)).r;
// Find the distance to the right.
coords.z = SMAASearchXRight(u_colorTex, u_colorTexSampler, u_smaaSearch, u_smaaSearchSampler,
in.offset0.zw, in.offset2.y, uniforms.u_framebufferMetrics);
d.y = coords.z;
// We want the distances to be in pixel units (doing this here allow to
// better interleave arithmetic and memory accesses).
d = abs(round(uniforms.u_framebufferMetrics.zz * d - in.coords.zz));
// SMAAArea below needs a sqrt, as the areas texture is compressed
// quadratically.
float2 sqrtD = sqrt(d);
// Fetch the right crossing edges.
float e2 = u_colorTex.sample(u_colorTexSampler, coords.zy, level(0), int2(1, 0)).r;
// Here we know how this pattern looks like, now it is time for getting
// the actual area.
weights.rg = SMAAArea(u_smaaArea, u_smaaAreaSampler, sqrtD, e1, e2);
}
if (e.r > 0.0) // Edge at west
{
float2 d;
// Find the distance to the top.
float3 coords;
coords.y = SMAASearchYUp(u_colorTex, u_colorTexSampler, u_smaaSearch, u_smaaSearchSampler,
in.offset1.xy, in.offset2.z, uniforms.u_framebufferMetrics);
coords.x = in.offset0.x;
d.x = coords.y;
// Fetch the top crossing edges.
float e1 = u_colorTex.sample(u_colorTexSampler, coords.xy, level(0)).g;
// Find the distance to the bottom.
coords.z = SMAASearchYDown(u_colorTex, u_colorTexSampler, u_smaaSearch, u_smaaSearchSampler,
in.offset1.zw, in.offset2.w, uniforms.u_framebufferMetrics);
d.y = coords.z;
// We want the distances to be in pixel units.
d = abs(round(uniforms.u_framebufferMetrics.ww * d - in.coords.ww));
// SMAAArea below needs a sqrt, as the areas texture is compressed
// quadratically.
float2 sqrtD = sqrt(d);
// Fetch the bottom crossing edges.
float e2 = u_colorTex.sample(u_colorTexSampler, coords.xz, level(0), int2(0, 1)).g;
// Get the area for this direction.
weights.ba = SMAAArea(u_smaaArea, u_smaaAreaSampler, sqrtD, e1, e2);
}
return weights;
}
// SmaaFinal
typedef struct
{
float4 position [[position]];
float4 offset;
float2 texCoords;
} SmaaFinalFragment_T;
vertex SmaaFinalFragment_T vsSmaaFinal(const SmaaVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
SmaaFinalFragment_T out;
float2 tcoord = float2(in.a_tcoord.x, 1.0 - in.a_tcoord.y);
out.position = float4(in.a_pos, 0.0, 1.0);
out.offset = uniforms.u_framebufferMetrics.xyxy * float4(1.0, 0.0, 0.0, 1.0) + tcoord.xyxy;
out.texCoords = tcoord;
return out;
}
fragment float4 fsSmaaFinal(const SmaaFinalFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]],
texture2d<float> u_blendingWeightTex [[texture(1)]],
sampler u_blendingWeightTexSampler [[sampler(1)]])
{
// Fetch the blending weights for current pixel.
float4 a;
a.x = u_blendingWeightTex.sample(u_blendingWeightTexSampler, in.offset.xy).a; // Right
a.y = u_blendingWeightTex.sample(u_blendingWeightTexSampler, in.offset.zw).g; // Top
a.wz = u_blendingWeightTex.sample(u_blendingWeightTexSampler, in.texCoords).xz; // Bottom / Left
// Is there any blending weight with a value greater than 0.0?
if (dot(a, float4(1.0, 1.0, 1.0, 1.0)) < 1e-5)
return u_colorTex.sample(u_colorTexSampler, in.texCoords);
// Calculate the blending offsets.
float4 blendingOffset = float4(0.0, a.y, 0.0, a.w);
float2 blendingWeight = a.yw;
if (max(a.x, a.z) > max(a.y, a.w))
{
blendingOffset = float4(a.x, 0.0, a.z, 0.0);
blendingWeight = a.xz;
}
blendingWeight /= dot(blendingWeight, float2(1.0, 1.0));
// Calculate the texture coordinates.
float4 bc = blendingOffset * float4(uniforms.u_framebufferMetrics.xy, -uniforms.u_framebufferMetrics.xy);
bc += in.texCoords.xyxy;
// We exploit bilinear filtering to mix current pixel with the chosen neighbor.
float4 color = blendingWeight.x * u_colorTex.sample(u_colorTexSampler, bc.xy, level(0));
color += blendingWeight.y * u_colorTex.sample(u_colorTexSampler, bc.zw, level(0));
return color;
}

View file

@ -0,0 +1,58 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
typedef struct
{
float2 a_position [[attribute(0)]];
} Vertex_T;
typedef struct
{
float4 position [[position]];
} Fragment_T;
typedef struct
{
float4 u_color;
} Uniforms_T;
typedef struct
{
float4 color [[color(0)]];
float depth [[depth(any)]];
} Fragment_Output;
typedef struct
{
float depth [[depth(any)]];
} Fragment_DepthOutput;
vertex Fragment_T vsCleaner(const Vertex_T in [[stage_in]])
{
Fragment_T out;
out.position = float4(in.a_position, 0.0, 1.0);
return out;
}
fragment float4 fsClearColor(const Fragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]])
{
return uniforms.u_color;
}
fragment Fragment_DepthOutput fsClearDepth(const Fragment_T in [[stage_in]])
{
Fragment_DepthOutput out;
out.depth = 1.0;
return out;
}
fragment Fragment_Output fsClearColorAndDepth(const Fragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]])
{
Fragment_Output out;
out.color = uniforms.u_color;
out.depth = 1.0;
return out;
}

View file

@ -0,0 +1,208 @@
#include <metal_stdlib>
#include <simd/simd.h>
#include "shaders_lib.h"
using namespace metal;
typedef struct
{
float4x4 u_modelView;
float4x4 u_projection;
float4x4 u_pivotTransform;
float4 u_trafficParams;
packed_float3 u_outlineColor;
float u_dummy1; // alignment
packed_float3 u_lightArrowColor;
float u_dummy2; // alignment
packed_float3 u_darkArrowColor;
float u_dummy3; // alignment
float u_outline;
float u_opacity;
} Uniforms_T;
// Traffic
typedef struct
{
float3 a_position [[attribute(0)]];
float4 a_normal [[attribute(1)]];
float4 a_colorTexCoord [[attribute(2)]];
} TrafficVertex_T;
typedef struct
{
float4 position [[position]];
float4 color;
float2 maskTexCoord;
float halfLength;
} TrafficFragment_T;
vertex TrafficFragment_T vsTraffic(const TrafficVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
constexpr float kArrowVSize = 0.25;
TrafficFragment_T out;
float2 normal = in.a_normal.xy;
float2 transformedAxisPos = (float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView).xy;
if (dot(normal, normal) != 0.0)
{
float2 norm = normal * uniforms.u_trafficParams.x;
if (in.a_normal.z < 0.0)
norm = normal * uniforms.u_trafficParams.y;
transformedAxisPos = CalcLineTransformedAxisPos(transformedAxisPos, in.a_position.xy + norm,
uniforms.u_modelView, length(norm));
}
float uOffset = length(float4(kShapeCoordScalar, 0.0, 0.0, 0.0) * uniforms.u_modelView) * in.a_normal.w;
out.color = u_colorTex.sample(u_colorTexSampler, in.a_colorTexCoord.xy);
float v = mix(in.a_colorTexCoord.z, in.a_colorTexCoord.z + kArrowVSize, 0.5 * in.a_normal.z + 0.5);
out.maskTexCoord = float2(uOffset * uniforms.u_trafficParams.z, v) * uniforms.u_trafficParams.w;
out.maskTexCoord.x *= step(in.a_colorTexCoord.w, out.maskTexCoord.x);
out.halfLength = in.a_normal.z;
float4 pos = float4(transformedAxisPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
return out;
}
fragment float4 fsTraffic(const TrafficFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]],
texture2d<float> u_maskTex [[texture(0)]],
sampler u_maskTexSampler [[sampler(0)]])
{
constexpr float kAntialiasingThreshold = 0.92;
constexpr float kOutlineThreshold1 = 0.8;
constexpr float kOutlineThreshold2 = 0.5;
constexpr float kMaskOpacity = 0.7;
float4 color = in.color;
float alphaCode = color.a;
float4 mask = u_maskTex.sample(u_maskTexSampler, in.maskTexCoord);
color.a = uniforms.u_opacity * (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(in.halfLength)));
color.rgb = mix(color.rgb, mask.rgb * mix(uniforms.u_lightArrowColor, uniforms.u_darkArrowColor, step(alphaCode, 0.6)), mask.a * kMaskOpacity);
if (uniforms.u_outline > 0.0)
{
float3 outlineColor = uniforms.u_outlineColor;
color.rgb = mix(color.rgb, outlineColor, step(kOutlineThreshold1, abs(in.halfLength)));
color.rgb = mix(color.rgb, outlineColor, smoothstep(kOutlineThreshold2, kOutlineThreshold1, abs(in.halfLength)));
}
return color;
}
// TrafficLine
typedef struct
{
float3 a_position [[attribute(0)]];
float2 a_colorTexCoord [[attribute(1)]];
} TrafficLineVertex_T;
typedef struct
{
float4 position [[position]];
float4 color;
} TrafficLineFragment_T;
vertex TrafficLineFragment_T vsTrafficLine(const TrafficLineVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
TrafficLineFragment_T out;
float2 transformedAxisPos = (float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView).xy;
float4 pos = float4(transformedAxisPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.color = float4(u_colorTex.sample(u_colorTexSampler, in.a_colorTexCoord).rgb, uniforms.u_opacity);
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
return out;
}
fragment float4 fsTrafficLine(const TrafficLineFragment_T in [[stage_in]])
{
return in.color;
}
// TrafficCircle
typedef struct
{
float4 a_position [[attribute(0)]];
float4 a_normal [[attribute(1)]];
float2 a_colorTexCoord [[attribute(2)]];
} TrafficCircleVertex_T;
typedef struct
{
float4 position [[position]];
float4 color;
float3 radius;
} TrafficCircleFragment_T;
vertex TrafficCircleFragment_T vsTrafficCircle(const TrafficCircleVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]],
texture2d<float> u_colorTex [[texture(0)]],
sampler u_colorTexSampler [[sampler(0)]])
{
TrafficCircleFragment_T out;
float2 normal = in.a_normal.xy;
float2 transformedAxisPos = (float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView).xy;
int index = int(in.a_position.w);
float3 leftSizes = uniforms.u_lightArrowColor;
float leftSize = leftSizes[index];
float3 rightSizes = uniforms.u_darkArrowColor;
float rightSize = rightSizes[index];
if (dot(normal, normal) != 0.0)
{
// offset by normal = rightVec * (rightSize - leftSize) / 2
float2 norm = normal * 0.5 * (rightSize - leftSize);
transformedAxisPos = CalcLineTransformedAxisPos(transformedAxisPos, in.a_position.xy + norm,
uniforms.u_modelView, length(norm));
}
// radius = (leftSize + rightSize) / 2
out.radius = float3(in.a_normal.zw, 1.0) * 0.5 * (leftSize + rightSize);
float2 finalPos = transformedAxisPos + out.radius.xy;
out.color = u_colorTex.sample(u_colorTexSampler, in.a_colorTexCoord);
float4 pos = float4(finalPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
return out;
}
typedef struct
{
float4 color [[color(0)]];
float depth [[depth(any)]];
} TrafficCircleOut_T;
fragment TrafficCircleOut_T fsTrafficCircle(const TrafficCircleFragment_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(0)]])
{
constexpr float kAntialiasingThreshold = 0.92;
TrafficCircleOut_T out;
float4 color = in.color;
float smallRadius = in.radius.z * kAntialiasingThreshold;
float stepValue = smoothstep(smallRadius * smallRadius, in.radius.z * in.radius.z,
in.radius.x * in.radius.x + in.radius.y * in.radius.y);
color.a = uniforms.u_opacity * (1.0 - stepValue);
if (color.a < 0.001)
out.depth = 1.0;
else
out.depth = in.position.z * in.position.w;
out.color = color;
return out;
}

View file

@ -0,0 +1,155 @@
#include <metal_stdlib>
#include <simd/simd.h>
#include "shaders_lib.h"
using namespace metal;
typedef struct
{
float4x4 u_modelView;
float4x4 u_projection;
float4x4 u_pivotTransform;
packed_float3 u_params;
float u_dummy1;
float u_lineHalfWidth;
float u_maxRadius;
} Uniforms_T;
typedef struct
{
float3 a_position [[attribute(0)]];
float4 a_normal [[attribute(1)]];
float4 a_color [[attribute(2)]];
} TransitVertex_T;
// Transit
typedef struct
{
float4 position [[position]];
float4 color;
} TransitFragment_T;
vertex TransitFragment_T vsTransit(const TransitVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
TransitFragment_T out;
float2 normal = in.a_normal.xy;
float2 transformedAxisPos = (float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView).xy;
if (dot(normal, normal) != 0.0)
{
float2 norm = normal * uniforms.u_lineHalfWidth;
transformedAxisPos = CalcLineTransformedAxisPos(transformedAxisPos, in.a_position.xy + norm,
uniforms.u_modelView, length(norm));
}
out.color = in.a_color;
float4 pos = float4(transformedAxisPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
return out;
}
fragment float4 fsTransit(const TransitFragment_T in [[stage_in]])
{
return in.color;
}
// Transit marker
typedef struct
{
float4 position [[position]];
float4 offsets;
float4 color;
} TransitMarkerFragment_T;
vertex TransitMarkerFragment_T vsTransitMarker(const TransitVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
TransitMarkerFragment_T out;
float4 pos = float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView;
float3 params = uniforms.u_params;
float2 normal = float2(in.a_normal.x * params.x - in.a_normal.y * params.y,
in.a_normal.x * params.y + in.a_normal.y * params.x);
float2 shiftedPos = normal * params.z + pos.xy;
pos = float4(shiftedPos, in.a_position.z, 1.0) * uniforms.u_projection;
float2 offsets = abs(in.a_normal.zw);
out.offsets = float4(in.a_normal.zw, offsets - 1.0);
out.color = in.a_color;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
return out;
}
fragment float4 fsTransitMarker(const TransitMarkerFragment_T in [[stage_in]])
{
float4 finalColor = in.color;
float2 radius;
radius.x = max(0.0, abs(in.offsets.x) - in.offsets.z);
radius.y = max(0.0, abs(in.offsets.y) - in.offsets.w);
float maxRadius = 1.0;
float aaRadius = 0.9;
float stepValue = 1.0 - smoothstep(aaRadius * aaRadius, maxRadius * maxRadius, dot(radius.xy, radius.xy));
finalColor.a *= stepValue;
return finalColor;
}
// Transit circle
typedef struct
{
float4 position [[position]];
float3 radius;
float4 color;
} TransitCircleFragment_T;
vertex TransitCircleFragment_T vsTransitCircle(const TransitVertex_T in [[stage_in]],
constant Uniforms_T & uniforms [[buffer(1)]])
{
TransitCircleFragment_T out;
float2 normal = in.a_normal.xy;
float2 transformedAxisPos = (float4(in.a_position.xy, 0.0, 1.0) * uniforms.u_modelView).xy;
if (dot(normal, normal) != 0.0)
{
float2 norm = normal * uniforms.u_lineHalfWidth;
transformedAxisPos = CalcLineTransformedAxisPos(transformedAxisPos, in.a_position.xy + norm,
uniforms.u_modelView, length(norm));
}
transformedAxisPos += in.a_normal.zw * uniforms.u_lineHalfWidth;
float4 pos = float4(transformedAxisPos, in.a_position.z, 1.0) * uniforms.u_projection;
out.position = ApplyPivotTransform(pos, uniforms.u_pivotTransform, 0.0);
out.color = in.a_color;
out.radius = float3(in.a_normal.zw, uniforms.u_maxRadius) * uniforms.u_lineHalfWidth;
return out;
}
typedef struct
{
float4 color [[color(0)]];
float depth [[depth(any)]];
} TransitCircleOut_T;
fragment TransitCircleOut_T fsTransitCircle(const TransitCircleFragment_T in [[stage_in]])
{
constexpr float kAntialiasingPixelsCount = 2.5;
TransitCircleOut_T out;
float4 finalColor = in.color;
float smallRadius = in.radius.z - kAntialiasingPixelsCount;
float stepValue = smoothstep(smallRadius * smallRadius, in.radius.z * in.radius.z,
dot(in.radius.xy, in.radius.xy));
finalColor.a = finalColor.a * (1.0 - stepValue);
if (finalColor.a < 0.001)
out.depth = 1.0;
else
out.depth = in.position.z * in.position.w;
out.color = finalColor;
return out;
}

Some files were not shown because too many files have changed in this diff Show more