Created
August 4, 2022 15:59
-
-
Save petertretyakov/b4f919ff3583d3cb334e2e653feeef0c to your computer and use it in GitHub Desktop.
Revisions
-
petertretyakov created this gist
Aug 4, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,86 @@ // Gradient Shader for arbitrary gradient stops, three gradient types and rotation // For the details please visit: https://mtldoc.com/metal/2022/08/04/shaders-explained-gradients.html // MARK: - Gradient Texture struct GradientTextureVertex { float4 position [[ position ]]; float4 color; }; [[ vertex ]] GradientTextureVertex gradientTextureVertex(constant float* positions [[ buffer(0) ]], constant float4* colors [[ buffer(1) ]], const ushort vid [[ vertex_id ]]) { return { .position = float4(fma(positions[vid], 2.0f, -1.0f), 0.0f, 0.0f, 1.0f), .color = colors[vid] }; } [[ fragment ]] float4 gradientTextureFragment(GradientTextureVertex in [[ stage_in ]]) { return in.color; } // MARK: - Gradient enum GradientType: uchar { kLinear, kRadial, kAngular }; struct GradientVertex { float4 position [[ position ]]; float2 uv; }; constant float2 positions[4] { { -1.0f, 1.0f }, { -1.0f, -1.0f }, { 1.0f, 1.0f }, { 1.0f, -1.0f } }; constant float2 uvs[4] { { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f } }; constant float PI = 3.1415926f; [[ vertex ]] GradientVertex gradientVertex(constant float2x2& rotationTransform [[ buffer(0) ]], const ushort vid [[ vertex_id ]]) { return { .position = float4(positions[vid], 0.0f, 1.0f), .uv = (uvs[vid] - float2(0.5f)) * rotationTransform + float2(0.5f) }; } [[ fragment ]] float4 gradientFragment(GradientVertex in [[ stage_in ]], texture2d<float, access::sample> gradientTexture [[ texture(0) ]], constant GradientType& gradientType [[ buffer(0) ]]) { constexpr sampler s(filter::linear, coord::normalized, address::clamp_to_edge); float2 texCoords; switch (gradientType) { case kLinear: texCoords = in.uv; break; case kRadial: texCoords = length(in.uv - float2(0.5f)) * 2.0f; break; case kAngular: const float2 offsetUV = in.uv - float2(0.5f); const float angle = atan2(offsetUV.y, offsetUV.x); texCoords = float2(fma(angle / PI, 0.5f, 0.5f), 0.0f); break; } return gradientTexture.sample(s, texCoords); }