diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index fba145563b..09d3709054 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -238,7 +238,6 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) case Message::Type::FlushOverlays: { - if (m_apiVersion == dp::ApiVersion::Metal) return; // TODO(@darina, @rokuz): TEMPORARY ref_ptr msg = message; TOverlaysRenderData renderData = msg->AcceptRenderData(); for (auto & overlayRenderData : renderData) diff --git a/shaders/Metal/map.metal b/shaders/Metal/map.metal index 8f781f2af5..ac15d1f5f4 100644 --- a/shaders/Metal/map.metal +++ b/shaders/Metal/map.metal @@ -435,3 +435,320 @@ fragment float4 fsPathSymbol(const PathSymbolFragment_T in [[stage_in]], 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 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 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 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 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 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 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 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 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)]], + texture2d u_colorTex [[texture(0)]], + sampler u_colorTexSampler [[sampler(0)]]) +{ + 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 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 u_colorTex [[texture(0)]], + sampler u_colorTexSampler [[sampler(0)]], + texture2d 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; +} diff --git a/shaders/Metal/shaders_lib.h b/shaders/Metal/shaders_lib.h index 7f191eab66..110101df90 100644 --- a/shaders/Metal/shaders_lib.h +++ b/shaders/Metal/shaders_lib.h @@ -7,7 +7,11 @@ using namespace metal; // 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); diff --git a/shaders/Metal/shaders_lib.metal b/shaders/Metal/shaders_lib.metal index ac6c19d8b8..88b9426321 100644 --- a/shaders/Metal/shaders_lib.metal +++ b/shaders/Metal/shaders_lib.metal @@ -21,3 +21,11 @@ float2 CalcLineTransformedAxisPos(float2 originalAxisPos, float2 shiftedPos, flo 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); +} diff --git a/shaders/metal_program_pool.mm b/shaders/metal_program_pool.mm index 4dcea91285..a351dbe20d 100644 --- a/shaders/metal_program_pool.mm +++ b/shaders/metal_program_pool.mm @@ -47,15 +47,15 @@ std::array(SystemProgram::SystemProgramsCount)> }}; std::array(Program::ProgramsCount)> const kMetalProgramsInfo = {{ - ProgramInfo("", "", {}), // ColoredSymbol - ProgramInfo("", "", {}), // Texturing - ProgramInfo("", "", {}), // MaskedTexturing + ProgramInfo("vsColoredSymbol", "fsColoredSymbol", {{0, 2}}), // ColoredSymbol + ProgramInfo("vsTexturing", "fsTexturing", {{0, 2}}), // Texturing + ProgramInfo("vsMaskedTexturing", "fsMaskedTexturing", {{0, 3}}), // MaskedTexturing ProgramInfo("", "", {}), // Bookmark ProgramInfo("", "", {}), // BookmarkAnim - ProgramInfo("", "", {}), // TextOutlined - ProgramInfo("", "", {}), // Text - ProgramInfo("", "", {}), // TextFixed - ProgramInfo("vsTextStaticOutlinedGui", "fsTextOutlinedGui", {{0, 4}}), // TextStaticOutlinedGui + ProgramInfo("vsTextOutlined", "fsText", {{0, 2}, {3, 4}}), // TextOutlined + ProgramInfo("vsText", "fsText", {{0, 1}, {2, 3}}), // Text + ProgramInfo("vsText", "fsTextFixed", {{0, 1}, {2, 3}}), // TextFixed + ProgramInfo("vsTextStaticOutlinedGui", "fsTextOutlinedGui", {{0, 2}, {3, 4}}), // TextStaticOutlinedGui ProgramInfo("vsTextOutlinedGui", "fsTextOutlinedGui", {{0, 2}, {3, 4}}), // TextOutlinedGui ProgramInfo("vsArea", "fsArea", {{0, 1}}), // Area ProgramInfo("vsArea", "fsArea", {{0, 1}}), // AreaOutline @@ -83,14 +83,14 @@ std::array(Program::ProgramsCount)> const kMeta ProgramInfo("vsArrow3d", "fsArrow3d", {{0, 0}, {1, 1}}), // Arrow3d ProgramInfo("vsArrow3dShadow", "fsArrow3dShadow", {{0, 0}}), // Arrow3dShadow ProgramInfo("vsArrow3dShadow", "fsArrow3dOutline", {{0, 0}}), // Arrow3dOutline - ProgramInfo("", "", {}), // ColoredSymbolBillboard - ProgramInfo("", "", {}), // TexturingBillboard - ProgramInfo("", "", {}), // MaskedTexturingBillboard + ProgramInfo("vsColoredSymbolBillboard", "fsColoredSymbol", {{0, 2}}), // ColoredSymbolBillboard + ProgramInfo("vsTexturingBillboard", "fsTexturing", {{0, 2}}), // TexturingBillboard + ProgramInfo("vsMaskedTexturingBillboard", "fsMaskedTexturing", {{0, 3}}), // MaskedTexturingBillboard ProgramInfo("", "", {}), // BookmarkBillboard ProgramInfo("", "", {}), // BookmarkAnimBillboard - ProgramInfo("", "", {}), // TextOutlinedBillboard - ProgramInfo("", "", {}), // TextBillboard - ProgramInfo("", "", {}), // TextFixedBillboard + ProgramInfo("vsTextOutlinedBillboard", "fsText", {{0, 2}, {3, 4}}), // TextOutlinedBillboard + ProgramInfo("vsTextBillboard", "fsText", {{0, 1}, {2, 3}}), // TextBillboard + ProgramInfo("vsTextBollboard", "fsTextFixed", {{0, 1}, {2, 3}}), // TextFixedBillboard ProgramInfo("vsTraffic", "fsTraffic", {{0, 2}}), // Traffic ProgramInfo("vsTrafficLine", "fsTrafficLine", {{0, 1}}), // TrafficLine ProgramInfo("vsTrafficCircle", "fsTrafficCircle", {{0, 2}}), // TrafficCircle