Home>

The lines displayed using Mesh are not displayed properly.

When Grid is displayed using Mesh,
When the aspect ratio of the screen is set to "Free Aspect", it is displayed neatly as shown below,

If i specify the aspect ratio instead of "Free Aspect", it will not be displayed as well as the image below.
(I think that it is a matter of screen resolution rather than specifying the aspect ratio)

What should I do in order to display clearly even if the screen resolution is specified?
From my knowledge, I could only come up with the technique of changing the thickness depending on the resolution...

Thank you.

Addendum

I used the following code.
The final goal is to keep the thickness almost unchanged even when the camera is zoomed in and out.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestGrid: MonoBehaviour
{
    [SerializeField]
    private UnityEngine.Grid m_grid;
    [SerializeField]
    private MeshRenderer m_meshRenderer;
    [SerializeField]
    private MeshFilter m_meshFilter;
    private Mesh m_gridMesh = null;
    [SerializeField]
    private Material m_gridMaterial;

    private const float k_GridGizmoDistanceFalloff = 50f;

    void Start()
    {
        m_gridMesh = Generate(m_grid, Color.white, 0.0f, new RectInt(0, 0, 10, 10));
        m_meshFilter.sharedMesh = m_gridMesh;
        m_meshRenderer.material = m_gridMaterial;
    }

    public static Mesh Generate(GridLayout gridLayout, Color color, float screenPixelSize, RectInt bounds)
    {
        Mesh mesh = new Mesh();mesh.hideFlags = HideFlags.HideAndDontSave;
        int vertex = 0;
        int totalVertices = 4 * (bounds.size.x + bounds.size.y);
        Vector3 horizontalPixelOffset = new Vector3(screenPixelSize, 0f, 0f);
        Vector3 verticalPixelOffset = new Vector3(0f, screenPixelSize, 0f);
        Vector3[] vertices = new Vector3[totalVertices];
        Vector2[] uvs2 = new Vector2[totalVertices];
        Vector3 cellStride = gridLayout.cellSize + gridLayout.cellGap;
        Vector3Int minPosition = new Vector3Int(0, bounds.min.y, 0);
        Vector3Int maxPosition = new Vector3Int(0, bounds.max.y, 0);
        Vector3 cellGap = Vector3.zero;
        if (!Mathf.Approximately(cellStride.x, 0f))
        {
            cellGap.x = gridLayout.cellSize.x/cellStride.x;
        }
        for (int x = bounds.min.x;x<bounds.max.x;x++)
        {
            minPosition.x = x;
            maxPosition.x = x;
            vertices[vertex + 0] = gridLayout.CellToLocal(minPosition);
            vertices[vertex + 1] = gridLayout.CellToLocal(maxPosition);
            uvs2[vertex + 0] = Vector2.zero;
            uvs2[vertex + 1] = new Vector2(0f, cellStride.y * bounds.size.y);
            vertex += 2;
            vertices[vertex + 0] = gridLayout.CellToLocalInterpolated(minPosition + cellGap);
            vertices[vertex + 1] = gridLayout.CellToLocalInterpolated(maxPosition + cellGap);
            uvs2[vertex + 0] = Vector2.zero;
            uvs2[vertex + 1] = new Vector2(0f, cellStride.y * bounds.size.y);
            vertex += 2;
        }
        minPosition = new Vector3Int(bounds.min.x, 0, 0);
        maxPosition = new Vector3Int(bounds.max.x, 0, 0);
        cellGap = Vector3.zero;
        if (!Mathf.Approximately(cellStride.y, 0f))
        {
            cellGap.y = gridLayout.cellSize.y/cellStride.y;
        }
        for (int y = bounds.min.y;y<bounds.max.y;y++)
        {
            minPosition.y = y;maxPosition.y = y;
            vertices[vertex + 0] = gridLayout.CellToLocal(minPosition);
            vertices[vertex + 1] = gridLayout.CellToLocal(maxPosition);
            uvs2[vertex + 0] = Vector2.zero;
            uvs2[vertex + 1] = new Vector2(cellStride.x * bounds.size.x, 0f);
            vertex += 2;
            vertices[vertex + 0] = gridLayout.CellToLocalInterpolated(minPosition + cellGap);
            vertices[vertex + 1] = gridLayout.CellToLocalInterpolated(maxPosition + cellGap);
            uvs2[vertex + 0] = Vector2.zero;
            uvs2[vertex + 1] = new Vector2(cellStride.x * bounds.size.x, 0f);
            vertex += 2;
        }
        var uv0 = new Vector2(k_GridGizmoDistanceFalloff, 0f);
        var uvs = new Vector2[vertex];
        var indices = new int[vertex];
        var colors = new Color[vertex];
        var normals = new Vector3[totalVertices];
        var uvs3 = new Vector2[totalVertices];
        for (int i = 0;i<vertex;i++)
        {
            uvs[i] = uv0;
            indices[i] = i;
            colors[i] = color;
            var alternate = i + ((i %2) == 0 ?1 :-1);
            normals[i] = vertices[alternate];
            uvs3[i] = uvs2[alternate];
        }
        mesh.vertices = vertices;
        mesh.uv = uvs;
        mesh.uv2 = uvs2;
        mesh.uv3 = uvs3;
        mesh.colors = colors;
        mesh.normals = normals;
        mesh.SetIndices(indices, MeshTopology.Lines, 0);
        return mesh;
    }

}
  • Answer # 1

    "If you specify the aspect ratio instead of "Free Aspect"", it says that the display setting at the top of the game view is set to the aspect ratio (setting name is something like "16:10") and fixed resolution Which does it mean when the setting name is something like "... (???x???)"?

    When I tried the code you presented, I found that the latter fixed resolution caused faint lines like the image presented. At this time, the "Scale" at the top of the game view is less than 1, and in my case, no blurring occurred when I adjusted the Scale slider to 1x.

    If the questioner has the same behavior as this, I think it is necessary to worry about this blurring.
    "We are aiming for a thickness that does not change much even if the camera is zoomed in and out," but in the code you presented, MeshTopology is set to Lines, "The thickness changes depending on the resolution" Even if you don't take any measures like that, you should already be able to draw with the minimum thickness regardless of the resolution. Even if it looks faint when the scale of the game view is small, it is a phenomenon that occurs only as a result of reducing the image rendered in the specified resolution in the game view, and probably the game It will be rendered properly in the actual environment in which you play.

    What if you try to change the "Size" of the camera variously under the condition that it is displayed properly in the game view without fading? Perhaps with the current method of making meshes, I think that any size will be consistently drawn with thin lines. If that is the case, even if the camera is zoomed in and out, it should be displayed with a constant line as well.

    However, even if it is called the "minimum thickness line," it may not be a sharp 1-pixel line due to the fractional number of vertex positions.

    Figure 1

    If you care, use a material like this for your grid...

    Shader "Unlit/PixelSnap"
    {
        Properties
        {
            _Color ("Color", Color) = (1, 1, 1, 1)
        }
        SubShader
        {
            Tags {"Queue"="Transparent" "RenderType"="Transparent"}
            Pass
            {
                Blend SrcAlpha OneMinusSrcAlpha
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                float4 _Color;
                float4 vert(float4 vertex: POSITION): SV_POSITION
                {
                    float4 clipPos = UnityObjectToClipPos(vertex);
                    float2 screenPos = _ScreenParams.xy * clipPos.xy * 0.5/clipPos.w;
                    screenPos = round(screenPos-0.5) + 0.5;
                    clipPos.xy = screenPos * clipPos.w * 2.0/_ScreenParams.xy;
                    return clipPos;
                }
                fixed4 frag(): SV_Target
                {
                    return _Color;
                }
                ENDCG
            }
        }
    }

    I think that it will improve if the vertex position is forcibly corrected.

    Figure 2