How draw round point in view with Metal ?

In my tutorial for study Metal , I want to draw the points in view,

I can now present in view of the square points, but I can not draw of round points.

how can I do ?


i have set Shaders.metal:

struct VertexOut {
    float4 position [[position]];
    float pointSize [[point_size]];
};
struct Uniforms {
    float4x4  ncdMatrix;
    float ptmRatio;
    float pointSize;
};
vertex VertexOut polipoint_vertex(const device packed_float3* vertex_array [[buffer(2)]],
                                 const device Uniforms& uniforms [[buffer(3)]],
                                 unsigned int vid [[vertex_id]])
{
    VertexOut vertexOut;
    float3 position = vertex_array[vid];
    vertexOut.position = float4(position.x , position.y , 0 , 1);
    vertexOut.pointSize = uniforms.pointSize;

     return vertexOut;
}



set drawInMTKView:

let commandEncoder3 = commandEncoder.renderCommandEncoder()
            commandEncoder3.setRenderPipelineState(pipelinePointState)
            commandEncoder3.setVertexBuffer(vertexPointBuffer, offset: 0, atIndex: 2)
            commandEncoder3.setVertexBuffer(uniformBuffer, offset: 0, atIndex: 3)
            commandEncoder3.drawPrimitives(.Point, vertexStart: 0, vertexCount: 2, instanceCount: 1)
            commandEncoder3.endEncoding()



how set Metal for return a round point with position and pointSize ?


Help me please ?

fragment half4 point_fragment(VertexOut fragData [[stage_in]],
                              float2 pointCoord  [[point_coord]])
{
    if (length(pointCoord - float2(0.5)) > 0.5) {
        discard_fragment();
    }
    return half4(fragData.color);
}

Note that this will produce hard edges. For softer edges, use alpha blending to fade out to zero at the edges. Alpha blending will also perform better than discard on iOS GPUs but does require you to sort your sprites from back to front (assuming source-over blending). Also note that you can use a single channel texture to define any sprite shape you want.

Here's a smoothstep version.


fragment half4 fragment_Points(VertexOut fragData [[stage_in]],
                                float2 pointCoord [[point_coord]])
{
    float dist = length(pointCoord - float2(0.5));
    float4 out_color = fragData.color;
    out_color.a = 1.0 - smoothstep(0.4, 0.5, dist); 
    return half4(out_color);
}



I include the following code to enable blending but am not sure it is all required.


        let attachmentDesc:MTLRenderPipelineColorAttachmentDescriptor =
            pipelineDesc.colorAttachments[0]
    
        attachmentDesc.blendingEnabled = true
    
        attachmentDesc.rgbBlendOperation = MTLBlendOperation.Add
        attachmentDesc.sourceRGBBlendFactor = MTLBlendFactor.SourceAlpha
        attachmentDesc.destinationRGBBlendFactor = MTLBlendFactor.OneMinusSourceAlpha
    
        attachmentDesc.alphaBlendOperation = MTLBlendOperation.Add
        attachmentDesc.sourceAlphaBlendFactor = MTLBlendFactor.SourceAlpha
        attachmentDesc.destinationAlphaBlendFactor = MTLBlendFactor.OneMinusSourceAlpha


I didn't get results I liked until I wacked the depthStencil which I had set as my default.


        let depthStencilDesc = MTLDepthStencilDescriptor()
        depthStencilDesc.depthCompareFunction = .Always
        depthStencilDesc.depthWriteEnabled = false
        mNoDepthTest = device.newDepthStencilStateWithDescriptor(depthStencilDesc)


and finally


       encoder.setDepthStencilState(mNoDepthTest!)

Your blending is not doing anything meaningful.


instead you should use msaa to 'soften' edges with a resolvetexture

How draw round point in view with Metal ?
 
 
Q