MeshTopology.Points very strange on iOS (Unity 2017.3.0.b10)

This has been driving me nuts. Rendering points on iOS using DrawProcedural or DrawProceduralIndirect seem to result in large quads.

Before posting a bug it would be nice to see if anyone else can reproduce it. I have attached an example package. Build to iOS, see if you get the same.

I testing on an iPhone7.

Carl Emil

using UnityEngine;

public class PointTopologyTest : MonoBehaviour
{
    public Shader shader;
    Material _material;

    void OnRenderObject()
    {
        if( !_material ) _material = new Material( shader );
        _material.SetPass(0);
        Graphics.DrawProcedural( MeshTopology.Points, 100, 1 );
    }
}
Shader "Hidden/PointTopologyTest"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma target 4.5
            #pragma vertex vert
            #pragma fragment frag
          
            #include "UnityCG.cginc"

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

            v2f vert( uint id : SV_VertexID )
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(float4(id*0.1,sin(id*0.1)*5,0,1));
                return o;
            }

            fixed4 frag( v2f i ) : SV_Target
            {
                return fixed4( 1, 1, 0, 1 );
            }
            ENDCG
        }
    }
}

3297222–255587–PointTopolyIOSExample.unitypackage (3.05 KB)

Oddly enough, MeshTopology.Lines works nicely on iOS. Really strange.

Yes, same experience here as well. (Unity 2017.3.0f3)
I haven’t tested with older versions of Unity.

Hi, I think the reason is “Metal” the graphics api.
In my case, I changed Graphics API OpenGLES2 from Metal.
Then, it became to looks like good.

Unity2017.3.0f.3
iPad iOS11.2

void Start () {
      MeshFilter meshFilter = GetComponent<MeshFilter>();
      meshFilter.mesh.SetIndices(meshFilter.mesh.GetIndices(0), MeshTopology.Points, 0);
}

(with OpenGLES2)!(http://~/Desktop/Image\ uploaded\ from\ iOS\ (1).png)

(with Metal)

regards.

Sorry to bring up an old post, but here’s a solution for anyone struggling with this issue.

In Metal, the size of drawn points is undefined unless otherwise specified, so you’re seeing points drawn at some arbitrary size (in this case, like half the screen!)

You can define a point size by specifying a value in your vertex shader using the PSIZE semantic.

float4 vert (appdata_base v, out float pointSize : PSIZE) : SV_Position {
    pointSize = 1;
    return UnityObjectToClipPos(v.vertex);
}
4 Likes

Thank you!

For anyone who needs more info on how to inject PSIZE into a shader, theres another example here: https://gamedev.stackexchange.com/questions/175239/specify-the-size-of-the-points-when-building-a-mesh-based-on-a-point-cloud