Line thickness behaves eratically near +/-Z axis

Avatar
  • updated
  • Fixed

Note: this issue may be related to https://shapes.userecho.com/en/communities/1/topics/154-. I am posting it separately because while that issue seems to be referring to pixel scaling being consistently off for a line that passes behind the camera, the specific behavior here is more extreme and in a very specific case.


I've run into an issue where pixel space thickness behaves erratically for points whose position is vaguely in the direction of +Z or -Z when drawn with Lines, while behaving as expected when drawn with Spheres.

In an ImmediateModeShapeDrawer, I am generating a set of points in a semicircle in local space of each currently rendering camera. I am drawing the points twice: once above with Draw.Sphere and once below with Draw.Line and have their respective Thickness spaces set to Pixel:

Youtube video

Note how in certain orientations the thickness of the lines (bottom) varies wildly, while the spheres (top) are always rock solid.

Particularly interesting is that the thickness variation of the lines appears to be most extreme around the vanishing point of the +Z/-Z axis, and is more pronounced the further towards the edges of the screen it is.

Here is the code used in this example:

using UnityEngine;
using Shapes;

[ExecuteAlways]
public class ScreenspaceSize : ImmediateModeShapeDrawer
{
    public int pointCount = 30;
    public float pointThickness = 30;
    public float pointDistance = 5;
    public float colorAlpha = 0.5f;

    public override void DrawShapes(Camera cam)
    {
        using (Draw.Command(cam))
        {
            Draw.Matrix = cam.transform.localToWorldMatrix;
            Draw.LineGeometry = LineGeometry.Volumetric3D;
            Draw.SphereRadiusSpace = ThicknessSpace.Pixels;
            Draw.LineThicknessSpace = ThicknessSpace.Pixels;
            
            for (int i = 0; i < pointCount; ++i)
            {
                float param01 = i / (float) (pointCount - 1);
                Color color = Color.HSVToRGB(param01, 0.9f, 1);
                color.a = colorAlpha;
                Quaternion localRot = Quaternion.Euler(0, Mathf.Lerp(-75, 75, param01), 0);
                Vector3 localPos = localRot * Vector3.forward * pointDistance;
                Draw.Sphere(localPos + Vector3.up, pointThickness/2, color);
                Draw.Line(localPos - Vector3.up, localPos - Vector3.up, pointThickness, color);
            }
        }
    }
}


For clarification, here is a visualization of where relative to the camera the points are being drawn, and what the camera itself sees:

Image 279


Note that in the screencapture I am using a debug script to move both the game and the scene view together, but that is not relevant to this issue.

Reporting a bug? please specify Unity version:
2019.4.16f1
Reporting a bug? please specify Shapes version:
3.0.0
Reporting a bug? please specify Render Pipeline:
Built-in render pipeline
Pinned replies
Avatar
Freya Holmér creator
  • Answer
  • Fixed

looks like this is specifically because of how lines behave when they are in the degenerate state of having 0 (or very near 0) length

I've cleaned up that degenerate line case now in 3.0.1 so it behaves just like the spheres, but also, why are you making degenerate lines? c:

Avatar
JohannesMP

In an attempt to visualize the distortion I modified the above code to draw a flat grid of 80x50 zero-length lines with pixel thickness 30 and alpha 0.05, with an fov of 120 to magnify the effect:

You can now clearly see that the distortion affects the whole screen, but far more severely when the vanishing point of +/-Z approaches the edges of the viewport.

using UnityEngine;
using Shapes;

[ExecuteAlways]
public class ScreenspaceSize2 : ImmediateModeShapeDrawer
{
    public int pointCountX = 80;
    public int pointCountY = 50;
    public float pointThickness = 30;
    public float pointDistance = 2;
    public float colorAlpha = 0.05f;

    public override void DrawShapes(Camera cam)
    {
        using (Draw.Command(cam))
        {
            Draw.Matrix = cam.transform.localToWorldMatrix;
            Draw.LineGeometry = LineGeometry.Volumetric3D;
            Draw.SphereRadiusSpace = ThicknessSpace.Pixels;
            Draw.LineThicknessSpace = ThicknessSpace.Pixels;

            for (int x = 0; x < pointCountX; ++x)
            {
                float param01X = x / (float) (pointCountX - 1);
                float xPos = Mathf.Lerp(-5, 5, param01X);
                for (int y = 0; y < pointCountY; ++y)
                {
                    float param01Y = y / (float) (pointCountY - 1);
                    Color color = Color.white;
                    color.a = colorAlpha;
                    float yPos = Mathf.Lerp(-3, 3, param01Y);
                    Vector3 pos = new Vector3(xPos, yPos, pointDistance);
                    //Draw.Sphere(pos, pointThickness/2, color);
                    Draw.Line(pos, pos, pointThickness, color);
                }
            }
        }
    }
}
Avatar
Freya Holmér creator
  • Answer
  • Fixed

looks like this is specifically because of how lines behave when they are in the degenerate state of having 0 (or very near 0) length

I've cleaned up that degenerate line case now in 3.0.1 so it behaves just like the spheres, but also, why are you making degenerate lines? c:

Avatar
JohannesMP

At the time I was experimenting I think I observed something similar with non-degenerate lines, but maybe they were just very very short? This test case evolved specifically as I was trying to track it down, but no longer have the original scenario.

If I run into the issue again after the update goes live, or in a case with clearly non-degenerate lines I will update here