Reduce symbol buffers memory by using instancing (Core optimization) (#4383)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -289,7 +289,7 @@ protected:
|
||||
/// Stores a collection of vertex attributes by name
|
||||
class VertexAttributeArray {
|
||||
public:
|
||||
using AttributeVector = std::array<std::unique_ptr<VertexAttribute>, shaders::maxVertexAttributeCountPerShader>;
|
||||
using AttributeVector = std::array<std::unique_ptr<VertexAttribute>, shaders::maxAttributeCountPerShader>;
|
||||
VertexAttributeArray() = default;
|
||||
VertexAttributeArray(VertexAttributeArray&&);
|
||||
VertexAttributeArray(const VertexAttributeArray&) = delete; // Would need to use the virtual assignment operator
|
||||
|
||||
@@ -72,6 +72,7 @@ enum {
|
||||
|
||||
#define MLN_UBO_CONSOLIDATION (MLN_RENDER_BACKEND_METAL || MLN_RENDER_BACKEND_VULKAN || MLN_RENDER_BACKEND_WEBGPU)
|
||||
#define MLN_USE_FILL_EXTRUSION_INSTANCING (MLN_RENDER_BACKEND_METAL || MLN_RENDER_BACKEND_VULKAN)
|
||||
#define MLN_USE_SYMBOL_INSTANCING (MLN_RENDER_BACKEND_METAL || MLN_RENDER_BACKEND_VULKAN)
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mln
|
||||
|
||||
@@ -45,10 +45,17 @@ float4 decode_color(const float2 encoded) {
|
||||
return float4(unpack_float(encoded[0]) / 255, unpack_float(encoded[1]) / 255);
|
||||
}
|
||||
// Unpack a pair of paint values and interpolate between them.
|
||||
float unpack_mix_float(device const float packedValue[2], const float t) {
|
||||
return mix(packedValue[0], packedValue[1], t);
|
||||
}
|
||||
float unpack_mix_float(const float2 packedValue, const float t) {
|
||||
return mix(packedValue[0], packedValue[1], t);
|
||||
}
|
||||
// Unpack a pair of paint values and interpolate between them.
|
||||
float4 unpack_mix_color(device const float packedColors[4], const float t) {
|
||||
return mix(decode_color(float2(packedColors[0], packedColors[1])),
|
||||
decode_color(float2(packedColors[2], packedColors[3])), t);
|
||||
}
|
||||
float4 unpack_mix_color(const float4 packedColors, const float t) {
|
||||
return mix(decode_color(float2(packedColors[0], packedColors[1])),
|
||||
decode_color(float2(packedColors[2], packedColors[3])), t);
|
||||
|
||||
@@ -84,10 +84,10 @@ struct VertexStage {
|
||||
float4 color [[attribute(2)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_base)
|
||||
float base [[attribute(3)]];
|
||||
float2 base [[attribute(3)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_height)
|
||||
float height [[attribute(4)]];
|
||||
float2 height [[attribute(4)]];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -206,10 +206,10 @@ struct VertexStage {
|
||||
float4 color [[attribute(3)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_base)
|
||||
float base [[attribute(4)]];
|
||||
float2 base [[attribute(4)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_height)
|
||||
float height [[attribute(5)]];
|
||||
float2 height [[attribute(5)]];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -344,10 +344,10 @@ struct VertexStage {
|
||||
ushort2 decimals_ed [[attribute(1)]];
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_base)
|
||||
float base [[attribute(2)]];
|
||||
float2 base [[attribute(2)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_height)
|
||||
float height [[attribute(3)]];
|
||||
float2 height [[attribute(3)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_pattern_from)
|
||||
ushort4 pattern_from [[attribute(4)]];
|
||||
@@ -530,10 +530,10 @@ struct VertexStage {
|
||||
short2 pos [[attribute(0)]];
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_base)
|
||||
float base [[attribute(3)]];
|
||||
float2 base [[attribute(3)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_height)
|
||||
float height [[attribute(4)]];
|
||||
float2 height [[attribute(4)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_pattern_from)
|
||||
ushort4 pattern_from [[attribute(5)]];
|
||||
|
||||
@@ -81,22 +81,41 @@ struct ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static const std::array<AttributeInfo, 6> attributes;
|
||||
static constexpr std::array<AttributeInfo, 0> instanceAttributes{};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<AttributeInfo, 10> instanceAttributes;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto prelude = symbolShaderPrelude;
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
float4 pos_offset [[attribute(0)]];
|
||||
float4 data [[attribute(1)]];
|
||||
float4 pixeloffset [[attribute(2)]];
|
||||
float3 projected_pos [[attribute(3)]];
|
||||
float fade_opacity [[attribute(4)]];
|
||||
float2 pos [[attribute(0)]];
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_sorted_instance)
|
||||
ushort sorted_instance [[attribute(1)]];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct SymbolInstance {
|
||||
short2 pos_scale[2];
|
||||
short2 offset_tltr[2];
|
||||
short2 offset_blbr[2];
|
||||
ushort2 texture_rect[2];
|
||||
short2 pixeloffset[2];
|
||||
ushort2 size_sdf;
|
||||
};
|
||||
|
||||
struct DynamicInstance {
|
||||
float projected_pos[3];
|
||||
};
|
||||
|
||||
struct OpacityInstance {
|
||||
float fade_opacity;
|
||||
};
|
||||
|
||||
struct DataInstance {
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float opacity [[attribute(5)]];
|
||||
float opacity[2];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -116,18 +135,33 @@ struct FragmentStage {
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(idGlobalPaintParamsUBO)]],
|
||||
device const uint32_t& uboIndex [[buffer(idGlobalUBOIndex)]],
|
||||
device const SymbolDrawableUBO* drawableVector [[buffer(idSymbolDrawableUBO)]]) {
|
||||
device const SymbolDrawableUBO* drawableVector [[buffer(idSymbolDrawableUBO)]],
|
||||
uint instanceID [[ instance_id ]],
|
||||
device const SymbolInstance* symbolInstances [[buffer(symbolUBOCount + 2)]],
|
||||
device const DynamicInstance* dynamicInstances [[buffer(symbolUBOCount + 3)]],
|
||||
device const OpacityInstance* opacityInstances [[buffer(symbolUBOCount + 4)]],
|
||||
device const DataInstance* dataInstances [[buffer(symbolUBOCount + 5)]]) {
|
||||
|
||||
#if defined(HAS_UNIFORM_u_sorted_instance)
|
||||
const uint instance = instanceID;
|
||||
#else
|
||||
const uint instance = vertx.sorted_instance;
|
||||
#endif
|
||||
|
||||
device const SymbolDrawableUBO& drawable = drawableVector[uboIndex];
|
||||
device const SymbolInstance& symbol = symbolInstances[instance];
|
||||
device const DynamicInstance& dynamic = dynamicInstances[instance];
|
||||
device const OpacityInstance& opacity = opacityInstances[instance];
|
||||
device const DataInstance& data = dataInstances[instance];
|
||||
|
||||
const float2 raw_fade_opacity = unpack_opacity(vertx.fade_opacity);
|
||||
const float2 raw_fade_opacity = unpack_opacity(opacity.fade_opacity);
|
||||
const float fade_change = raw_fade_opacity[1] > 0.5 ? paintParams.symbol_fade_change : -paintParams.symbol_fade_change;
|
||||
const float fade_opacity = max(0.0, min(1.0, raw_fade_opacity[0] + fade_change));
|
||||
|
||||
#if defined(HAS_UNIFORM_u_opacity)
|
||||
const half fo = half(fade_opacity);
|
||||
#else
|
||||
const half fo = half(unpack_mix_float(vertx.opacity, drawable.opacity_t) * fade_opacity);
|
||||
const half fo = half(unpack_mix_float(data.opacity, drawable.opacity_t) * fade_opacity);
|
||||
#endif
|
||||
|
||||
// This will check to see if the opacity is zero and push the triangle offscreen if it is
|
||||
@@ -140,17 +174,17 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
};
|
||||
}
|
||||
|
||||
const float2 a_pos = vertx.pos_offset.xy;
|
||||
const float2 a_offset = vertx.pos_offset.zw;
|
||||
const float2 a_pos = float2(symbol.pos_scale[0]);
|
||||
const float2 a_offset = float2(select(symbol.offset_tltr[uint(vertx.pos.x)], symbol.offset_blbr[uint(vertx.pos.x)], uint(vertx.pos.y)));
|
||||
|
||||
const float2 a_tex = vertx.data.xy;
|
||||
const float2 a_size = vertx.data.zw;
|
||||
const float2 a_tex = float2(symbol.texture_rect[0]) + vertx.pos * float2(symbol.texture_rect[1]);
|
||||
const float2 a_size = float2(symbol.size_sdf);
|
||||
|
||||
const float a_size_min = floor(a_size[0] * 0.5);
|
||||
const float2 a_pxoffset = vertx.pixeloffset.xy;
|
||||
const float2 a_minFontScale = vertx.pixeloffset.zw / 256.0;
|
||||
const float2 a_pxoffset = float2(symbol.pixeloffset[0]) + vertx.pos * float2(symbol.pixeloffset[1] - symbol.pixeloffset[0]);
|
||||
const float2 a_minFontScale = float2(symbol.pos_scale[1]) / 256.0;
|
||||
|
||||
const float segment_angle = -vertx.projected_pos[2];
|
||||
const float segment_angle = -dynamic.projected_pos[2];
|
||||
|
||||
float size;
|
||||
if (!drawable.is_size_zoom_constant && !drawable.is_size_feature_constant) {
|
||||
@@ -192,7 +226,7 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
const float angle_cos = cos(segment_angle + symbol_rotation);
|
||||
const float2x2 rotation_matrix = float2x2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
||||
|
||||
const float4 projected_pos = drawable.label_plane_matrix * float4(vertx.projected_pos.xy, 0.0, 1.0);
|
||||
const float4 projected_pos = drawable.label_plane_matrix * float4(dynamic.projected_pos[0], dynamic.projected_pos[1], 0.0, 1.0);
|
||||
const float2 pos0 = projected_pos.xy / projected_pos.w;
|
||||
const float2 posOffset = a_offset * max(a_minFontScale, fontScale) / 32.0 + a_pxoffset / 16.0;
|
||||
const float4 position = drawable.coord_matrix * float4(pos0 + rotation_matrix * posOffset, 0.0, 1.0);
|
||||
@@ -237,34 +271,53 @@ struct ShaderSource<BuiltIn::SymbolSDFShader, gfx::Backend::Type::Metal> {
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static const std::array<AttributeInfo, 10> attributes;
|
||||
static constexpr std::array<AttributeInfo, 0> instanceAttributes{};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<AttributeInfo, 14> instanceAttributes;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto prelude = symbolShaderPrelude;
|
||||
static constexpr auto source = R"(
|
||||
|
||||
struct VertexStage {
|
||||
float4 pos_offset [[attribute(0)]];
|
||||
float4 data [[attribute(1)]];
|
||||
float4 pixeloffset [[attribute(2)]];
|
||||
float3 projected_pos [[attribute(3)]];
|
||||
float fade_opacity [[attribute(4)]];
|
||||
float2 pos [[attribute(0)]];
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_sorted_instance)
|
||||
ushort sorted_instance [[attribute(1)]];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct SymbolInstance {
|
||||
short2 pos_scale[2];
|
||||
short2 offset_tltr[2];
|
||||
short2 offset_blbr[2];
|
||||
ushort2 texture_rect[2];
|
||||
short2 pixeloffset[2];
|
||||
ushort2 size_sdf;
|
||||
};
|
||||
|
||||
struct DynamicInstance {
|
||||
float projected_pos[3];
|
||||
};
|
||||
|
||||
struct OpacityInstance {
|
||||
float fade_opacity;
|
||||
};
|
||||
|
||||
struct DataInstance {
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float opacity[2];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_fill_color)
|
||||
float4 fill_color [[attribute(5)]];
|
||||
float fill_color[4];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_color)
|
||||
float4 halo_color [[attribute(6)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float opacity [[attribute(7)]];
|
||||
float halo_color[4];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_width)
|
||||
float halo_width [[attribute(8)]];
|
||||
float halo_width[2];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_blur)
|
||||
float halo_blur [[attribute(9)]];
|
||||
float halo_blur[2];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -297,11 +350,26 @@ struct FragmentStage {
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(idGlobalPaintParamsUBO)]],
|
||||
device const uint32_t& uboIndex [[buffer(idGlobalUBOIndex)]],
|
||||
device const SymbolDrawableUBO* drawableVector [[buffer(idSymbolDrawableUBO)]]) {
|
||||
device const SymbolDrawableUBO* drawableVector [[buffer(idSymbolDrawableUBO)]],
|
||||
uint instanceID [[ instance_id ]],
|
||||
device const SymbolInstance* symbolInstances [[buffer(symbolUBOCount + 2)]],
|
||||
device const DynamicInstance* dynamicInstances [[buffer(symbolUBOCount + 3)]],
|
||||
device const OpacityInstance* opacityInstances [[buffer(symbolUBOCount + 4)]],
|
||||
device const DataInstance* dataInstances [[buffer(symbolUBOCount + 5)]]) {
|
||||
|
||||
#if defined(HAS_UNIFORM_u_sorted_instance)
|
||||
const uint instance = instanceID;
|
||||
#else
|
||||
const uint instance = vertx.sorted_instance;
|
||||
#endif
|
||||
|
||||
device const SymbolDrawableUBO& drawable = drawableVector[uboIndex];
|
||||
device const SymbolInstance& symbol = symbolInstances[instance];
|
||||
device const DynamicInstance& dynamic = dynamicInstances[instance];
|
||||
device const OpacityInstance& opacity = opacityInstances[instance];
|
||||
device const DataInstance& data = dataInstances[instance];
|
||||
|
||||
const float2 fade_opacity = unpack_opacity(vertx.fade_opacity);
|
||||
const float2 fade_opacity = unpack_opacity(opacity.fade_opacity);
|
||||
const float fade_change = (fade_opacity[1] > 0.5) ? paintParams.symbol_fade_change : -paintParams.symbol_fade_change;
|
||||
const half fo = half(max(0.0, min(1.0, fade_opacity[0] + fade_change)));
|
||||
|
||||
@@ -315,16 +383,16 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
};
|
||||
}
|
||||
|
||||
const float2 a_pos = vertx.pos_offset.xy;
|
||||
const float2 a_offset = vertx.pos_offset.zw;
|
||||
const float2 a_pos = float2(symbol.pos_scale[0]);
|
||||
const float2 a_offset = float2(select(symbol.offset_tltr[uint(vertx.pos.x)], symbol.offset_blbr[uint(vertx.pos.x)], uint(vertx.pos.y)));
|
||||
|
||||
const float2 a_tex = vertx.data.xy;
|
||||
const float2 a_size = vertx.data.zw;
|
||||
const float2 a_tex = float2(symbol.texture_rect[0]) + vertx.pos * float2(symbol.texture_rect[1]);
|
||||
const float2 a_size = float2(symbol.size_sdf);
|
||||
|
||||
const float a_size_min = floor(a_size[0] * 0.5);
|
||||
const float2 a_pxoffset = vertx.pixeloffset.xy;
|
||||
const float2 a_pxoffset = float2(symbol.pixeloffset[0]) + vertx.pos * float2(symbol.pixeloffset[1] - symbol.pixeloffset[0]);
|
||||
|
||||
const float segment_angle = -vertx.projected_pos[2];
|
||||
const float segment_angle = -dynamic.projected_pos[2];
|
||||
|
||||
float size;
|
||||
if (!drawable.is_size_zoom_constant && !drawable.is_size_feature_constant) {
|
||||
@@ -373,7 +441,7 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
const float angle_sin = sin(segment_angle + symbol_rotation);
|
||||
const float angle_cos = cos(segment_angle + symbol_rotation);
|
||||
const auto rotation_matrix = float2x2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
||||
const float4 projected_pos = drawable.label_plane_matrix * float4(vertx.projected_pos.xy, 0.0, 1.0);
|
||||
const float4 projected_pos = drawable.label_plane_matrix * float4(dynamic.projected_pos[0], dynamic.projected_pos[1], 0.0, 1.0);
|
||||
const float2 pos_rot = a_offset / 32.0 * fontScale + a_pxoffset;
|
||||
const float2 pos0 = projected_pos.xy / projected_pos.w + rotation_matrix * pos_rot;
|
||||
const float4 position = drawable.coord_matrix * float4(pos0, 0.0, 1.0);
|
||||
@@ -381,19 +449,19 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
return {
|
||||
.position = position,
|
||||
#if !defined(HAS_UNIFORM_u_fill_color)
|
||||
.fill_color = half4(unpack_mix_color(vertx.fill_color, drawable.fill_color_t)),
|
||||
.fill_color = half4(unpack_mix_color(data.fill_color, drawable.fill_color_t)),
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_color)
|
||||
.halo_color = half4(unpack_mix_color(vertx.halo_color, drawable.halo_color_t)),
|
||||
.halo_color = half4(unpack_mix_color(data.halo_color, drawable.halo_color_t)),
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_width)
|
||||
.halo_width = half(unpack_mix_float(vertx.halo_width, drawable.halo_width_t)),
|
||||
.halo_width = half(unpack_mix_float(data.halo_width, drawable.halo_width_t)),
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_blur)
|
||||
.halo_blur = half(unpack_mix_float(vertx.halo_blur, drawable.halo_blur_t)),
|
||||
.halo_blur = half(unpack_mix_float(data.halo_blur, drawable.halo_blur_t)),
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
.opacity = half(unpack_mix_float(vertx.opacity, drawable.opacity_t)),
|
||||
.opacity = half(unpack_mix_float(data.opacity, drawable.opacity_t)),
|
||||
#endif
|
||||
.tex = half2(a_tex / drawable.texsize),
|
||||
.gamma_scale = half(position.w),
|
||||
@@ -470,8 +538,8 @@ struct ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>
|
||||
static constexpr auto vertexMainFunction = "vertexMain";
|
||||
static constexpr auto fragmentMainFunction = "fragmentMain";
|
||||
|
||||
static const std::array<AttributeInfo, 9> attributes;
|
||||
static constexpr std::array<AttributeInfo, 0> instanceAttributes{};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<AttributeInfo, 14> instanceAttributes;
|
||||
static const std::array<TextureInfo, 2> textures;
|
||||
|
||||
static constexpr auto prelude = symbolShaderPrelude;
|
||||
@@ -481,25 +549,45 @@ struct ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Metal>
|
||||
#define ICON 0.0
|
||||
|
||||
struct VertexStage {
|
||||
float4 pos_offset [[attribute(0)]];
|
||||
float4 data [[attribute(1)]];
|
||||
float3 projected_pos [[attribute(2)]];
|
||||
float fade_opacity [[attribute(3)]];
|
||||
float2 pos [[attribute(0)]];
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_sorted_instance)
|
||||
ushort sorted_instance [[attribute(1)]];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct SymbolInstance {
|
||||
short2 pos_scale[2];
|
||||
short2 offset_tltr[2];
|
||||
short2 offset_blbr[2];
|
||||
ushort2 texture_rect[2];
|
||||
short2 pixeloffset[2];
|
||||
ushort2 size_sdf;
|
||||
};
|
||||
|
||||
struct DynamicInstance {
|
||||
float projected_pos[3];
|
||||
};
|
||||
|
||||
struct OpacityInstance {
|
||||
float fade_opacity;
|
||||
};
|
||||
|
||||
struct DataInstance {
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float opacity[2];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_fill_color)
|
||||
float4 fill_color [[attribute(4)]];
|
||||
float fill_color[4];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_color)
|
||||
float4 halo_color [[attribute(5)]];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float opacity [[attribute(6)]];
|
||||
float halo_color[4];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_width)
|
||||
float halo_width [[attribute(7)]];
|
||||
float halo_width[2];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_blur)
|
||||
float halo_blur [[attribute(8)]];
|
||||
float halo_blur[2];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -534,11 +622,26 @@ struct FragmentStage {
|
||||
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
device const GlobalPaintParamsUBO& paintParams [[buffer(idGlobalPaintParamsUBO)]],
|
||||
device const uint32_t& uboIndex [[buffer(idGlobalUBOIndex)]],
|
||||
device const SymbolDrawableUBO* drawableVector [[buffer(idSymbolDrawableUBO)]]) {
|
||||
device const SymbolDrawableUBO* drawableVector [[buffer(idSymbolDrawableUBO)]],
|
||||
uint instanceID [[ instance_id ]],
|
||||
device const SymbolInstance* symbolInstances [[buffer(symbolUBOCount + 2)]],
|
||||
device const DynamicInstance* dynamicInstances [[buffer(symbolUBOCount + 3)]],
|
||||
device const OpacityInstance* opacityInstances [[buffer(symbolUBOCount + 4)]],
|
||||
device const DataInstance* dataInstances [[buffer(symbolUBOCount + 5)]]) {
|
||||
|
||||
#if defined(HAS_UNIFORM_u_sorted_instance)
|
||||
const uint instance = instanceID;
|
||||
#else
|
||||
const uint instance = vertx.sorted_instance;
|
||||
#endif
|
||||
|
||||
device const SymbolDrawableUBO& drawable = drawableVector[uboIndex];
|
||||
device const SymbolInstance& symbol = symbolInstances[instance];
|
||||
device const DynamicInstance& dynamic = dynamicInstances[instance];
|
||||
device const OpacityInstance& opacity = opacityInstances[instance];
|
||||
device const DataInstance& data = dataInstances[instance];
|
||||
|
||||
const float2 fade_opacity = unpack_opacity(vertx.fade_opacity);
|
||||
const float2 fade_opacity = unpack_opacity(opacity.fade_opacity);
|
||||
const float fade_change = (fade_opacity[1] > 0.5) ? paintParams.symbol_fade_change : -paintParams.symbol_fade_change;
|
||||
const half fo = half(max(0.0, min(1.0, fade_opacity[0] + fade_change)));
|
||||
|
||||
@@ -552,16 +655,16 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
};
|
||||
}
|
||||
|
||||
const float2 a_pos = vertx.pos_offset.xy;
|
||||
const float2 a_offset = vertx.pos_offset.zw;
|
||||
const float2 a_pos = float2(symbol.pos_scale[0]);
|
||||
const float2 a_offset = float2(select(symbol.offset_tltr[uint(vertx.pos.x)], symbol.offset_blbr[uint(vertx.pos.x)], uint(vertx.pos.y)));
|
||||
|
||||
const float2 a_tex = vertx.data.xy;
|
||||
const float2 a_size = vertx.data.zw;
|
||||
const float2 a_tex = float2(symbol.texture_rect[0]) + vertx.pos * float2(symbol.texture_rect[1]);
|
||||
const float2 a_size = float2(symbol.size_sdf);
|
||||
|
||||
const float a_size_min = floor(a_size[0] * 0.5);
|
||||
const float is_sdf = a_size[0] - 2.0 * a_size_min;
|
||||
|
||||
const float segment_angle = -vertx.projected_pos[2];
|
||||
const float segment_angle = -dynamic.projected_pos[2];
|
||||
|
||||
float size;
|
||||
if (!drawable.is_size_zoom_constant && !drawable.is_size_feature_constant) {
|
||||
@@ -611,7 +714,7 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
const float angle_cos = cos(segment_angle + symbol_rotation);
|
||||
const float2x2 rotation_matrix = float2x2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
||||
|
||||
const float4 projected_pos = drawable.label_plane_matrix * float4(vertx.projected_pos.xy, 0.0, 1.0);
|
||||
const float4 projected_pos = drawable.label_plane_matrix * float4(dynamic.projected_pos[0], dynamic.projected_pos[1], 0.0, 1.0);
|
||||
const float2 pos_rot = a_offset / 32.0 * fontScale;
|
||||
const float2 pos0 = projected_pos.xy / projected_pos.w + rotation_matrix * pos_rot;
|
||||
const float4 position = drawable.coord_matrix * float4(pos0, 0.0, 1.0);
|
||||
@@ -627,19 +730,19 @@ FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
|
||||
.is_icon = is_icon,
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_fill_color)
|
||||
.fill_color = half(unpack_mix_color(vertx.fill_color, drawable.fill_color_t));
|
||||
.fill_color = half(unpack_mix_color(data.fill_color, drawable.fill_color_t));
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_color)
|
||||
.halo_color = half(unpack_mix_color(vertx.halo_color, drawable.halo_color_t));
|
||||
.halo_color = half(unpack_mix_color(data.halo_color, drawable.halo_color_t));
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
.opacity = half(unpack_mix_float(vertx.opacity, drawable.opacity_t));
|
||||
.opacity = half(unpack_mix_float(data.opacity, drawable.opacity_t));
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_width)
|
||||
.halo_width = half(unpack_mix_float(vertx.halo_width, drawable.halo_width_t));
|
||||
.halo_width = half(unpack_mix_float(data.halo_width, drawable.halo_width_t));
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_blur)
|
||||
.halo_blur = half(unpack_mix_float(vertx.halo_blur, drawable.halo_blur_t));
|
||||
.halo_blur = half(unpack_mix_float(data.halo_blur, drawable.halo_blur_t));
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
@@ -163,15 +163,26 @@ static constexpr uint32_t drawableSSBOStartId = std::max({static_cast<uint32_t>(
|
||||
|
||||
enum {
|
||||
#if MLN_USE_FILL_EXTRUSION_INSTANCING
|
||||
idFillExtrusionInstanced = getEnumValue(fillExtrusionLayerUBOCount, drawableSSBOStartId),
|
||||
idFillExtrusionInstancedDrawableUBO = getEnumValue(fillExtrusionLayerUBOCount, drawableSSBOStartId),
|
||||
#endif
|
||||
fillExtrusionDrawableSSBOCount
|
||||
};
|
||||
|
||||
enum {
|
||||
#if MLN_USE_SYMBOL_INSTANCING
|
||||
idSymbolInstancedDrawableUBO = getEnumValue(symbolLayerUBOCount, drawableSSBOStartId),
|
||||
idSymbolDynamicInstancedDrawableUBO,
|
||||
idSymbolOpacityInstancedDrawableUBO,
|
||||
idSymbolDataInstancedDrawableUBO,
|
||||
#endif
|
||||
symbolDrawableSSBOCount
|
||||
};
|
||||
|
||||
// drawable UBOs
|
||||
|
||||
static constexpr uint32_t drawableUBOStartId = std::max(
|
||||
{static_cast<uint32_t>(drawableSSBOStartId), static_cast<uint32_t>(fillExtrusionDrawableSSBOCount)});
|
||||
static constexpr uint32_t drawableUBOStartId = std::max({static_cast<uint32_t>(drawableSSBOStartId),
|
||||
static_cast<uint32_t>(fillExtrusionDrawableSSBOCount),
|
||||
static_cast<uint32_t>(symbolDrawableSSBOCount)});
|
||||
|
||||
enum {
|
||||
backgroundUBOCount = getEnumValue(backgroundLayerUBOCount, drawableUBOStartId)
|
||||
@@ -521,20 +532,34 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
idSymbolPosOffsetVertexAttribute,
|
||||
idSymbolDataVertexAttribute,
|
||||
idSymbolPixelOffsetVertexAttribute,
|
||||
idSymbolProjectedPosVertexAttribute,
|
||||
idSymbolFadeOpacityVertexAttribute,
|
||||
#if MLN_USE_SYMBOL_INSTANCING
|
||||
idSymbolPosAttribute,
|
||||
|
||||
idSymbolSortedInstanceAttribute,
|
||||
|
||||
idSymbolPosScaleAttribute,
|
||||
idSymbolOffsetTlTrAttribute,
|
||||
idSymbolOffsetBlBrAttribute,
|
||||
idSymbolTextureRectAttribute,
|
||||
idSymbolPixelOffsetAttribute,
|
||||
idSymbolSizeSdfAttribute,
|
||||
#else
|
||||
idSymbolPosOffsetAttribute,
|
||||
idSymbolDataAttribute,
|
||||
idSymbolPixelOffsetAttribute,
|
||||
#endif
|
||||
|
||||
idSymbolProjectedPosAttribute,
|
||||
idSymbolFadeOpacityAttribute,
|
||||
|
||||
// Data driven
|
||||
idSymbolOpacityVertexAttribute,
|
||||
idSymbolColorVertexAttribute,
|
||||
idSymbolHaloColorVertexAttribute,
|
||||
idSymbolHaloWidthVertexAttribute,
|
||||
idSymbolHaloBlurVertexAttribute,
|
||||
idSymbolOpacityAttribute,
|
||||
idSymbolColorAttribute,
|
||||
idSymbolHaloColorAttribute,
|
||||
idSymbolHaloWidthAttribute,
|
||||
idSymbolHaloBlurAttribute,
|
||||
|
||||
symbolVertexAttributeCount
|
||||
symbolAttributeCount
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -554,7 +579,7 @@ enum {
|
||||
wideVectorInstanceAttributeCount
|
||||
};
|
||||
|
||||
static constexpr uint32_t maxVertexAttributeCountPerShader = std::max({
|
||||
static constexpr uint32_t maxAttributeCountPerShader = std::max({
|
||||
static_cast<uint32_t>(backgroundVertexAttributeCount),
|
||||
static_cast<uint32_t>(circleVertexAttributeCount),
|
||||
static_cast<uint32_t>(clippingMaskVertexAttributeCount),
|
||||
@@ -570,7 +595,7 @@ static constexpr uint32_t maxVertexAttributeCountPerShader = std::max({
|
||||
static_cast<uint32_t>(lineVertexAttributeCount),
|
||||
static_cast<uint32_t>(locationIndicatorVertexAttributeCount),
|
||||
static_cast<uint32_t>(rasterVertexAttributeCount),
|
||||
static_cast<uint32_t>(symbolVertexAttributeCount),
|
||||
static_cast<uint32_t>(symbolAttributeCount),
|
||||
static_cast<uint32_t>(wideVectorAttributeCount),
|
||||
static_cast<uint32_t>(wideVectorInstanceAttributeCount),
|
||||
});
|
||||
|
||||
@@ -49,11 +49,19 @@ vec4 decode_color(const vec2 encodedColor) {
|
||||
}
|
||||
|
||||
// Unpack a pair of paint values and interpolate between them.
|
||||
float unpack_mix_float(const float packedValue[2], const float t) {
|
||||
return mix(packedValue[0], packedValue[1], t);
|
||||
}
|
||||
float unpack_mix_float(const vec2 packedValue, const float t) {
|
||||
return mix(packedValue[0], packedValue[1], t);
|
||||
}
|
||||
|
||||
// Unpack a pair of paint values and interpolate between them.
|
||||
vec4 unpack_mix_color(const float packedColors[4], const float t) {
|
||||
vec4 minColor = decode_color(vec2(packedColors[0], packedColors[1]));
|
||||
vec4 maxColor = decode_color(vec2(packedColors[2], packedColors[3]));
|
||||
return mix(minColor, maxColor, t);
|
||||
}
|
||||
vec4 unpack_mix_color(const vec4 packedColors, const float t) {
|
||||
vec4 minColor = decode_color(vec2(packedColors[0], packedColors[1]));
|
||||
vec4 maxColor = decode_color(vec2(packedColors[2], packedColors[3]));
|
||||
@@ -89,7 +97,7 @@ vec2 unpack_uint(uint value) {
|
||||
#define layerSSBOStartId 0
|
||||
#define layerUBOStartId 3
|
||||
#define drawableSSBOStartId 0
|
||||
#define drawableUBOStartId 1
|
||||
#define drawableUBOStartId 4
|
||||
|
||||
#define idDrawableReservedVertexOnlyUBO layerSSBOStartId
|
||||
#define idDrawableReservedFragmentOnlyUBO idDrawableReservedVertexOnlyUBO + 1
|
||||
@@ -140,7 +148,7 @@ void applySurfaceTransform() {
|
||||
#define layerSSBOStartId 0
|
||||
#define layerUBOStartId 3
|
||||
#define drawableSSBOStartId 0
|
||||
#define drawableUBOStartId 1
|
||||
#define drawableUBOStartId 4
|
||||
|
||||
#define idDrawableReservedVertexOnlyUBO layerSSBOStartId
|
||||
#define idDrawableReservedFragmentOnlyUBO idDrawableReservedVertexOnlyUBO + 1
|
||||
|
||||
@@ -8,9 +8,13 @@ namespace shaders {
|
||||
|
||||
constexpr auto symbolShaderPrelude = R"(
|
||||
|
||||
#define idSymbolDrawableUBO idDrawableReservedVertexOnlyUBO
|
||||
#define idSymbolTilePropsUBO idDrawableReservedFragmentOnlyUBO
|
||||
#define idSymbolEvaluatedPropsUBO layerUBOStartId
|
||||
#define idSymbolDrawableUBO idDrawableReservedVertexOnlyUBO
|
||||
#define idSymbolTilePropsUBO idDrawableReservedFragmentOnlyUBO
|
||||
#define idSymbolEvaluatedPropsUBO layerUBOStartId
|
||||
#define idSymbolInstancedDrawableUBO drawableSSBOStartId
|
||||
#define idSymbolDynamicInstancedDrawableUBO drawableSSBOStartId + 1
|
||||
#define idSymbolOpacityInstancedDrawableUBO drawableSSBOStartId + 2
|
||||
#define idSymbolDataInstancedDrawableUBO drawableSSBOStartId + 3
|
||||
|
||||
)";
|
||||
|
||||
@@ -18,21 +22,17 @@ template <>
|
||||
struct ShaderSource<BuiltIn::SymbolIconShader, gfx::Backend::Type::Vulkan> {
|
||||
static constexpr const char* name = "SymbolIconShader";
|
||||
|
||||
static const std::array<AttributeInfo, 6> attributes;
|
||||
static constexpr std::array<AttributeInfo, 0> instanceAttributes{};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<AttributeInfo, 10> instanceAttributes;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto prelude = symbolShaderPrelude;
|
||||
static constexpr auto vertex = R"(
|
||||
|
||||
layout(location = 0) in ivec4 in_pos_offset;
|
||||
layout(location = 1) in uvec4 in_data;
|
||||
layout(location = 2) in ivec4 in_pixeloffset;
|
||||
layout(location = 3) in vec3 in_projected_pos;
|
||||
layout(location = 4) in float in_fade_opacity;
|
||||
layout(location = 0) in ivec2 in_pos;
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
layout(location = 5) in vec2 in_opacity;
|
||||
#if !defined(HAS_UNIFORM_u_sorted_instance)
|
||||
layout(location = 1) in uint in_sorted_instance;
|
||||
#endif
|
||||
|
||||
layout(push_constant) uniform Constants {
|
||||
@@ -69,23 +69,72 @@ layout(std140, set = LAYER_SET_INDEX, binding = idSymbolDrawableUBO) readonly bu
|
||||
SymbolDrawableUBO drawable_ubo[];
|
||||
} drawableVector;
|
||||
|
||||
struct SymbolInstance {
|
||||
int pos_scale[2];
|
||||
int offset_tltr[2];
|
||||
int offset_blbr[2];
|
||||
uint texture_rect[2];
|
||||
int pixeloffset[2];
|
||||
uint size_sdf;
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolInstancedDrawableUBO) readonly buffer SymbolInstanceDrawableUBOVector {
|
||||
SymbolInstance instance[];
|
||||
} symbolInstanceVector;
|
||||
|
||||
struct DynamicInstance {
|
||||
float projected_pos[3];
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolDynamicInstancedDrawableUBO) readonly buffer DynamicInstanceDrawableUBOVector {
|
||||
DynamicInstance instance[];
|
||||
} dynamicInstanceVector;
|
||||
|
||||
struct OpacityInstance {
|
||||
float fade_opacity;
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolOpacityInstancedDrawableUBO) readonly buffer OpacityInstanceDrawableUBOVector {
|
||||
OpacityInstance instance[];
|
||||
} opacityInstanceVector;
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
struct DataInstance {
|
||||
float opacity[2];
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolDataInstancedDrawableUBO) readonly buffer DataInstanceDrawableUBOVector {
|
||||
DataInstance instance[];
|
||||
} dataInstanceVector;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out mediump vec2 frag_tex;
|
||||
layout(location = 1) out mediump float frag_opacity;
|
||||
|
||||
void main() {
|
||||
#if defined(HAS_UNIFORM_u_sorted_instance)
|
||||
const uint instance = gl_InstanceIndex;
|
||||
#else
|
||||
const uint instance = in_sorted_instance;
|
||||
#endif
|
||||
|
||||
const SymbolDrawableUBO drawable = drawableVector.drawable_ubo[constant.ubo_index];
|
||||
const SymbolInstance symbol = symbolInstanceVector.instance[instance];
|
||||
const DynamicInstance dynamic = dynamicInstanceVector.instance[instance];
|
||||
const OpacityInstance opacity = opacityInstanceVector.instance[instance];
|
||||
|
||||
const vec2 a_pos = in_pos_offset.xy;
|
||||
const vec2 a_offset = in_pos_offset.zw;
|
||||
const vec2 a_pos = unpack_int(symbol.pos_scale[0]);
|
||||
const vec2 offset_tb[2] = {unpack_int(symbol.offset_tltr[in_pos.x]), unpack_int(symbol.offset_blbr[in_pos.x])};
|
||||
const vec2 a_offset = offset_tb[in_pos.y];
|
||||
|
||||
const vec2 a_tex = in_data.xy;
|
||||
const vec2 a_size = in_data.zw;
|
||||
const vec2 a_tex = unpack_uint(symbol.texture_rect[0]) + in_pos * unpack_uint(symbol.texture_rect[1]);
|
||||
const vec2 a_size = unpack_uint(symbol.size_sdf);
|
||||
|
||||
const float a_size_min = floor(a_size[0] * 0.5);
|
||||
const vec2 a_pxoffset = in_pixeloffset.xy;
|
||||
const vec2 a_minFontScale = in_pixeloffset.zw / 256.0;
|
||||
const vec2 a_pxoffset = unpack_int(symbol.pixeloffset[0]) + in_pos * (unpack_int(symbol.pixeloffset[1]) - unpack_int(symbol.pixeloffset[0]));
|
||||
const vec2 a_minFontScale = unpack_int(symbol.pos_scale[1]) / 256.0;
|
||||
|
||||
const float segment_angle = -in_projected_pos[2];
|
||||
const float segment_angle = -dynamic.projected_pos[2];
|
||||
|
||||
float size;
|
||||
if (!drawable.is_size_zoom_constant && !drawable.is_size_feature_constant) {
|
||||
@@ -127,13 +176,13 @@ void main() {
|
||||
const float angle_cos = cos(segment_angle + symbol_rotation);
|
||||
const mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
||||
|
||||
const vec4 projected_pos = drawable.label_plane_matrix * vec4(in_projected_pos.xy, 0.0, 1.0);
|
||||
const vec4 projected_pos = drawable.label_plane_matrix * vec4(dynamic.projected_pos[0], dynamic.projected_pos[1], 0.0, 1.0);
|
||||
const vec2 pos0 = projected_pos.xy / projected_pos.w;
|
||||
const vec2 posOffset = a_offset * max(a_minFontScale, fontScale) / 32.0 + a_pxoffset / 16.0;
|
||||
gl_Position = drawable.coord_matrix * vec4(pos0 + rotation_matrix * posOffset, 0.0, 1.0);
|
||||
applySurfaceTransform();
|
||||
|
||||
const vec2 raw_fade_opacity = unpack_opacity(in_fade_opacity);
|
||||
const vec2 raw_fade_opacity = unpack_opacity(opacity.fade_opacity);
|
||||
const float fade_change = raw_fade_opacity[1] > 0.5 ? paintParams.symbol_fade_change : -paintParams.symbol_fade_change;
|
||||
const float fade_opacity = max(0.0, min(1.0, raw_fade_opacity[0] + fade_change));
|
||||
|
||||
@@ -142,7 +191,7 @@ void main() {
|
||||
#if defined(HAS_UNIFORM_u_opacity)
|
||||
frag_opacity = fade_opacity;
|
||||
#else
|
||||
frag_opacity = unpack_mix_float(in_opacity, drawable.opacity_t) * fade_opacity;
|
||||
frag_opacity = unpack_mix_float(dataInstanceVector.instance[instance].opacity, drawable.opacity_t) * fade_opacity;
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
@@ -209,37 +258,17 @@ template <>
|
||||
struct ShaderSource<BuiltIn::SymbolSDFShader, gfx::Backend::Type::Vulkan> {
|
||||
static constexpr const char* name = "SymbolSDFShader";
|
||||
|
||||
static const std::array<AttributeInfo, 10> attributes;
|
||||
static constexpr std::array<AttributeInfo, 0> instanceAttributes{};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<AttributeInfo, 14> instanceAttributes;
|
||||
static const std::array<TextureInfo, 1> textures;
|
||||
|
||||
static constexpr auto prelude = symbolShaderPrelude;
|
||||
static constexpr auto vertex = R"(
|
||||
|
||||
layout(location = 0) in ivec4 in_pos_offset;
|
||||
layout(location = 1) in uvec4 in_data;
|
||||
layout(location = 2) in ivec4 in_pixeloffset;
|
||||
layout(location = 3) in vec3 in_projected_pos;
|
||||
layout(location = 4) in float in_fade_opacity;
|
||||
layout(location = 0) in ivec2 in_pos;
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_fill_color)
|
||||
layout(location = 5) in vec4 in_fill_color;
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_halo_color)
|
||||
layout(location = 6) in vec4 in_halo_color;
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
layout(location = 7) in vec2 in_opacity;
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_halo_width)
|
||||
layout(location = 8) in vec2 in_halo_width;
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_halo_blur)
|
||||
layout(location = 9) in vec2 in_halo_blur;
|
||||
#if !defined(HAS_UNIFORM_u_sorted_instance)
|
||||
layout(location = 1) in uint in_sorted_instance;
|
||||
#endif
|
||||
|
||||
layout(push_constant) uniform Constants {
|
||||
@@ -276,6 +305,59 @@ layout(std140, set = LAYER_SET_INDEX, binding = idSymbolDrawableUBO) readonly bu
|
||||
SymbolDrawableUBO drawable_ubo[];
|
||||
} drawableVector;
|
||||
|
||||
struct SymbolInstance {
|
||||
int pos_scale[2];
|
||||
int offset_tltr[2];
|
||||
int offset_blbr[2];
|
||||
uint texture_rect[2];
|
||||
int pixeloffset[2];
|
||||
uint size_sdf;
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolInstancedDrawableUBO) readonly buffer SymbolInstanceDrawableUBOVector {
|
||||
SymbolInstance instance[];
|
||||
} symbolInstanceVector;
|
||||
|
||||
struct DynamicInstance {
|
||||
float projected_pos[3];
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolDynamicInstancedDrawableUBO) readonly buffer DynamicInstanceDrawableUBOVector {
|
||||
DynamicInstance instance[];
|
||||
} dynamicInstanceVector;
|
||||
|
||||
struct OpacityInstance {
|
||||
float fade_opacity;
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolOpacityInstancedDrawableUBO) readonly buffer OpacityInstanceDrawableUBOVector {
|
||||
OpacityInstance instance[];
|
||||
} opacityInstanceVector;
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_opacity) || !defined(HAS_UNIFORM_u_fill_color) || !defined(HAS_UNIFORM_u_halo_color) || !defined(HAS_UNIFORM_u_halo_width) || !defined(HAS_UNIFORM_u_halo_blur)
|
||||
struct DataInstance {
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float opacity[2];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_fill_color)
|
||||
float fill_color[4];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_color)
|
||||
float halo_color[4];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_width)
|
||||
float halo_width[2];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_blur)
|
||||
float halo_blur[2];
|
||||
#endif
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolDataInstancedDrawableUBO) readonly buffer DataInstanceDrawableUBOVector {
|
||||
DataInstance instance[];
|
||||
} dataInstanceVector;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out mediump vec2 frag_tex;
|
||||
layout(location = 1) out mediump float frag_fade_opacity;
|
||||
layout(location = 2) out mediump float frag_font_scale;
|
||||
@@ -302,17 +384,27 @@ layout(location = 8) out mediump float frag_halo_blur;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
#if defined(HAS_UNIFORM_u_sorted_instance)
|
||||
const uint instance = gl_InstanceIndex;
|
||||
#else
|
||||
const uint instance = in_sorted_instance;
|
||||
#endif
|
||||
|
||||
const SymbolDrawableUBO drawable = drawableVector.drawable_ubo[constant.ubo_index];
|
||||
const SymbolInstance symbol = symbolInstanceVector.instance[instance];
|
||||
const DynamicInstance dynamic = dynamicInstanceVector.instance[instance];
|
||||
const OpacityInstance opacity = opacityInstanceVector.instance[instance];
|
||||
|
||||
const vec2 a_pos = in_pos_offset.xy;
|
||||
const vec2 a_offset = in_pos_offset.zw;
|
||||
const vec2 a_pos = unpack_int(symbol.pos_scale[0]);
|
||||
const vec2 offset_tb[2] = {unpack_int(symbol.offset_tltr[in_pos.x]), unpack_int(symbol.offset_blbr[in_pos.x])};
|
||||
const vec2 a_offset = offset_tb[in_pos.y];
|
||||
|
||||
const vec2 a_tex = in_data.xy;
|
||||
const vec2 a_size = in_data.zw;
|
||||
const vec2 a_tex = unpack_uint(symbol.texture_rect[0]) + in_pos * unpack_uint(symbol.texture_rect[1]);
|
||||
const vec2 a_size = unpack_uint(symbol.size_sdf);
|
||||
|
||||
const float a_size_min = floor(a_size[0] * 0.5);
|
||||
const vec2 a_pxoffset = in_pixeloffset.xy;
|
||||
const float segment_angle = -in_projected_pos[2];
|
||||
const vec2 a_pxoffset = unpack_int(symbol.pixeloffset[0]) + in_pos * (unpack_int(symbol.pixeloffset[1]) - unpack_int(symbol.pixeloffset[0]));
|
||||
const float segment_angle = -dynamic.projected_pos[2];
|
||||
|
||||
float size;
|
||||
if (!drawable.is_size_zoom_constant && !drawable.is_size_feature_constant) {
|
||||
@@ -361,13 +453,13 @@ void main() {
|
||||
const float angle_cos = cos(segment_angle + symbol_rotation);
|
||||
const mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
||||
|
||||
const vec4 projected_pos = drawable.label_plane_matrix * vec4(in_projected_pos.xy, 0.0, 1.0);
|
||||
const vec4 projected_pos = drawable.label_plane_matrix * vec4(dynamic.projected_pos[0], dynamic.projected_pos[1], 0.0, 1.0);
|
||||
const vec2 pos_rot = a_offset / 32.0 * fontScale + a_pxoffset;
|
||||
const vec2 pos0 = projected_pos.xy / projected_pos.w + rotation_matrix * pos_rot;
|
||||
gl_Position = drawable.coord_matrix * vec4(pos0, 0.0, 1.0);
|
||||
applySurfaceTransform();
|
||||
|
||||
const vec2 raw_fade_opacity = unpack_opacity(in_fade_opacity);
|
||||
const vec2 raw_fade_opacity = unpack_opacity(opacity.fade_opacity);
|
||||
const float fade_change = raw_fade_opacity[1] > 0.5 ? paintParams.symbol_fade_change : -paintParams.symbol_fade_change;
|
||||
|
||||
frag_tex = a_tex / drawable.texsize;
|
||||
@@ -376,19 +468,19 @@ void main() {
|
||||
frag_gamma_scale = gl_Position.w;
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_fill_color)
|
||||
frag_fill_color = unpack_mix_color(in_fill_color, drawable.fill_color_t);
|
||||
frag_fill_color = unpack_mix_color(dataInstanceVector.instance[instance].fill_color, drawable.fill_color_t);
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_color)
|
||||
frag_halo_color = unpack_mix_color(in_halo_color, drawable.halo_color_t);
|
||||
frag_halo_color = unpack_mix_color(dataInstanceVector.instance[instance].halo_color, drawable.halo_color_t);
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_width)
|
||||
frag_halo_width = unpack_mix_float(in_halo_width, drawable.halo_width_t);
|
||||
frag_halo_width = unpack_mix_float(dataInstanceVector.instance[instance].halo_width, drawable.halo_width_t);
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_blur)
|
||||
frag_halo_blur = unpack_mix_float(in_halo_blur, drawable.halo_blur_t);
|
||||
frag_halo_blur = unpack_mix_float(dataInstanceVector.instance[instance].halo_blur, drawable.halo_blur_t);
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
frag_opacity = unpack_mix_float(in_opacity, drawable.opacity_t);
|
||||
frag_opacity = unpack_mix_float(dataInstanceVector.instance[instance].opacity, drawable.opacity_t);
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
@@ -517,8 +609,8 @@ template <>
|
||||
struct ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Vulkan> {
|
||||
static constexpr const char* name = "SymbolTextAndIconShader";
|
||||
|
||||
static const std::array<AttributeInfo, 9> attributes;
|
||||
static constexpr std::array<AttributeInfo, 0> instanceAttributes{};
|
||||
static const std::array<AttributeInfo, 1> attributes;
|
||||
static const std::array<AttributeInfo, 14> instanceAttributes;
|
||||
static const std::array<TextureInfo, 2> textures;
|
||||
|
||||
static constexpr auto prelude = symbolShaderPrelude;
|
||||
@@ -527,29 +619,10 @@ struct ShaderSource<BuiltIn::SymbolTextAndIconShader, gfx::Backend::Type::Vulkan
|
||||
#define SDF 1.0
|
||||
#define ICON 0.0
|
||||
|
||||
layout(location = 0) in ivec4 in_pos_offset;
|
||||
layout(location = 1) in uvec4 in_data;
|
||||
layout(location = 2) in vec3 in_projected_pos;
|
||||
layout(location = 3) in float in_fade_opacity;
|
||||
layout(location = 0) in ivec2 in_pos;
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_fill_color)
|
||||
layout(location = 4) in vec4 in_fill_color;
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_halo_color)
|
||||
layout(location = 5) in vec4 in_halo_color;
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
layout(location = 6) in vec2 in_opacity;
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_halo_width)
|
||||
layout(location = 7) in vec2 in_halo_width;
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_halo_blur)
|
||||
layout(location = 8) in vec2 in_halo_blur;
|
||||
#if !defined(HAS_UNIFORM_u_sorted_instance)
|
||||
layout(location = 1) in uint in_sorted_instance;
|
||||
#endif
|
||||
|
||||
layout(push_constant) uniform Constants {
|
||||
@@ -586,6 +659,59 @@ layout(std140, set = LAYER_SET_INDEX, binding = idSymbolDrawableUBO) readonly bu
|
||||
SymbolDrawableUBO drawable_ubo[];
|
||||
} drawableVector;
|
||||
|
||||
struct SymbolInstance {
|
||||
int pos_scale[2];
|
||||
int offset_tltr[2];
|
||||
int offset_blbr[2];
|
||||
uint texture_rect[2];
|
||||
int pixeloffset[2];
|
||||
uint size_sdf;
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolInstancedDrawableUBO) readonly buffer SymbolInstanceDrawableUBOVector {
|
||||
SymbolInstance instance[];
|
||||
} symbolInstanceVector;
|
||||
|
||||
struct DynamicInstance {
|
||||
float projected_pos[3];
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolDynamicInstancedDrawableUBO) readonly buffer DynamicInstanceDrawableUBOVector {
|
||||
DynamicInstance instance[];
|
||||
} dynamicInstanceVector;
|
||||
|
||||
struct OpacityInstance {
|
||||
float fade_opacity;
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolOpacityInstancedDrawableUBO) readonly buffer OpacityInstanceDrawableUBOVector {
|
||||
OpacityInstance instance[];
|
||||
} opacityInstanceVector;
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_opacity) || !defined(HAS_UNIFORM_u_fill_color) || !defined(HAS_UNIFORM_u_halo_color) || !defined(HAS_UNIFORM_u_halo_width) || !defined(HAS_UNIFORM_u_halo_blur)
|
||||
struct DataInstance {
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
float opacity[2];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_fill_color)
|
||||
float fill_color[4];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_color)
|
||||
float halo_color[4];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_width)
|
||||
float halo_width[2];
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_blur)
|
||||
float halo_blur[2];
|
||||
#endif
|
||||
};
|
||||
|
||||
layout(std430, set = DRAWABLE_UBO_SET_INDEX, binding = idSymbolDataInstancedDrawableUBO) readonly buffer DataInstanceDrawableUBOVector {
|
||||
DataInstance instance[];
|
||||
} dataInstanceVector;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out mediump vec2 frag_tex;
|
||||
layout(location = 1) out mediump float frag_fade_opacity;
|
||||
layout(location = 2) out mediump float frag_font_scale;
|
||||
@@ -614,17 +740,27 @@ layout(location = 8) out mediump float frag_halo_blur;
|
||||
layout(location = 9) out int frag_is_icon;
|
||||
|
||||
void main() {
|
||||
#if defined(HAS_UNIFORM_u_sorted_instance)
|
||||
const uint instance = gl_InstanceIndex;
|
||||
#else
|
||||
const uint instance = in_sorted_instance;
|
||||
#endif
|
||||
|
||||
const SymbolDrawableUBO drawable = drawableVector.drawable_ubo[constant.ubo_index];
|
||||
const SymbolInstance symbol = symbolInstanceVector.instance[instance];
|
||||
const DynamicInstance dynamic = dynamicInstanceVector.instance[instance];
|
||||
const OpacityInstance opacity = opacityInstanceVector.instance[instance];
|
||||
|
||||
const vec2 a_pos = in_pos_offset.xy;
|
||||
const vec2 a_offset = in_pos_offset.zw;
|
||||
const vec2 a_pos = unpack_int(symbol.pos_scale[0]);
|
||||
const vec2 offset_tb[2] = {unpack_int(symbol.offset_tltr[in_pos.x]), unpack_int(symbol.offset_blbr[in_pos.x])};
|
||||
const vec2 a_offset = offset_tb[in_pos.y];
|
||||
|
||||
const vec2 a_tex = in_data.xy;
|
||||
const vec2 a_size = in_data.zw;
|
||||
const vec2 a_tex = unpack_uint(symbol.texture_rect[0]) + in_pos * unpack_uint(symbol.texture_rect[1]);
|
||||
const vec2 a_size = unpack_uint(symbol.size_sdf);
|
||||
|
||||
const float a_size_min = floor(a_size[0] * 0.5);
|
||||
const float is_sdf = a_size[0] - 2.0 * a_size_min;
|
||||
const float segment_angle = -in_projected_pos[2];
|
||||
const float segment_angle = -dynamic.projected_pos[2];
|
||||
|
||||
float size;
|
||||
if (!drawable.is_size_zoom_constant && !drawable.is_size_feature_constant) {
|
||||
@@ -673,13 +809,13 @@ void main() {
|
||||
const float angle_cos = cos(segment_angle + symbol_rotation);
|
||||
const mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
||||
|
||||
const vec4 projected_pos = drawable.label_plane_matrix * vec4(in_projected_pos.xy, 0.0, 1.0);
|
||||
const vec4 projected_pos = drawable.label_plane_matrix * vec4(dynamic.projected_pos[0], dynamic.projected_pos[1], 0.0, 1.0);
|
||||
const vec2 pos_rot = a_offset / 32.0 * fontScale;
|
||||
const vec2 pos0 = projected_pos.xy / projected_pos.w + rotation_matrix * pos_rot;
|
||||
gl_Position = drawable.coord_matrix * vec4(pos0, 0.0, 1.0);
|
||||
applySurfaceTransform();
|
||||
|
||||
const vec2 raw_fade_opacity = unpack_opacity(in_fade_opacity);
|
||||
const vec2 raw_fade_opacity = unpack_opacity(opacity.fade_opacity);
|
||||
const float fade_change = raw_fade_opacity[1] > 0.5 ? paintParams.symbol_fade_change : -paintParams.symbol_fade_change;
|
||||
|
||||
const bool is_icon = (is_sdf == ICON);
|
||||
@@ -691,19 +827,19 @@ void main() {
|
||||
frag_gamma_scale = gl_Position.w;
|
||||
|
||||
#if !defined(HAS_UNIFORM_u_fill_color)
|
||||
frag_fill_color = unpack_mix_color(in_fill_color, drawable.fill_color_t);
|
||||
frag_fill_color = unpack_mix_color(dataInstanceVector.instance[instance].fill_color, drawable.fill_color_t);
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_color)
|
||||
frag_halo_color = unpack_mix_color(in_halo_color, drawable.halo_color_t);
|
||||
frag_halo_color = unpack_mix_color(dataInstanceVector.instance[instance].halo_color, drawable.halo_color_t);
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_width)
|
||||
frag_halo_width = unpack_mix_float(in_halo_width, drawable.halo_width_t);
|
||||
frag_halo_width = unpack_mix_float(dataInstanceVector.instance[instance].halo_width, drawable.halo_width_t);
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_halo_blur)
|
||||
frag_halo_blur = unpack_mix_float(in_halo_blur, drawable.halo_blur_t);
|
||||
frag_halo_blur = unpack_mix_float(dataInstanceVector.instance[instance].halo_blur, drawable.halo_blur_t);
|
||||
#endif
|
||||
#if !defined(HAS_UNIFORM_u_opacity)
|
||||
frag_opacity = unpack_mix_float(in_opacity, drawable.opacity_t);
|
||||
frag_opacity = unpack_mix_float(dataInstanceVector.instance[instance].opacity, drawable.opacity_t);
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
|
||||
Reference in New Issue
Block a user