Smoothen line on linerender - c#

I've created a square using linerenderer but my problem now is that the line is not smooth. see below picture. I've tried enabling anti-aliasing and setting lr.numCapVertices to no avail.
private void DrawLine()
{
GameObject myLine = new GameObject();
myLine.transform.position = start;
myLine.AddComponent<LineRenderer>();
lr = myLine.GetComponent<LineRenderer>();
lr.material = new Material(Shader.Find("Sprites/Default"));
lr.positionCount = 4;
lr.startWidth = .1f;
lr.endWidth = .1f;
lr.SetPosition(0, new Vector3(1, 0, 0));
lr.SetPosition(1, new Vector3(2, 0, 0));
lr.SetPosition(2, new Vector3(2, -1, 0));
lr.SetPosition(3, new Vector3(1, -1, 0));
lr.loop = true;
Gradient gradient = new Gradient();
gradient.SetKeys(
new GradientColorKey[]
{
new GradientColorKey(Color.red, 0.25f),
new GradientColorKey(Color.green, 0.50f),
new GradientColorKey(Color.blue, 0.75f),
new GradientColorKey(Color.yellow, 1f),
},
new GradientAlphaKey[] { new GradientAlphaKey(1f, 0.0f)
}
);
lr.colorGradient = gradient;
}

Have a look at line renderer documentation. Specifically the following properties:
Corner vertices
End cap vertices
Alignment
The corner and cap vertices will determine the 'roundness' of corners and line endings.
Different alignment settings may give you a more orthogonal view of the line which should prevent the illusion of varying thickness as can be seen at the green corner in your image.

Related

c# / Monogame : Draw a Polygon primitive?

I'm trying to draw a polygon of a solid color. I'm given a vector of 2D vectors, ordered such that there will be an edge from v0 to v1 to v2 to ... to vn to v0.
Does such a primitive exist?
Credit to Stefan Agartsson for the post this answer's code is based upon.
To describe the vertices as edges instead of triangles, You can use the PrimitiveType.LineStrip instead of PrimitiveType.TriangleList you have to adjust the index and counts as well since each vertex is used only once.
BasicEffect basicEffect = new BasicEffect(device);
basicEffect.Texture = myTexture;
basicEffect.TextureEnabled = true;
VertexPositionTexture[] vert = new VertexPositionTexture[4];
vert[0].Position = new Vector3(0, 0, 0); //These connect in order
vert[1].Position = new Vector3(100, 0, 0);
vert[2].Position = new Vector3(100, 100, 0);
vert[3].Position = new Vector3(0, 100, 0);
vert[0].TextureCoordinate = new Vector2(0, 0);
vert[1].TextureCoordinate = new Vector2(1, 0);
vert[2].TextureCoordinate = new Vector2(1, 1);
vert[3].TextureCoordinate = new Vector2(0, 1);
short[] ind = new short[n+1]; // the +1 is to close the shape
for(int i = 0; i < n; i++)
ind[i] = i;
ind[n] = 0; // return to start to close.
Then in your render loop you do this:
foreach (EffectPass effectPass in basicEffect.CurrentTechnique.Passes)
{
effectPass.Apply();
device.DrawUserIndexedPrimitives<VertexPositionTexture>(
PrimitiveType.LineStrip, vert, 0, vert.Length, ind, 0, ind.Length);
}

Changing color for each element in linerenderer not working

I want to change color for each line(element) just like in color switch. But my code is not working. Whats wrong with my code?
void Start()
{
lineGeneratorPrefab = new GameObject();
DrawLine();
}
private void DrawLine()
{
GameObject myLine = new GameObject();
myLine.transform.position = start;
myLine.AddComponent<LineRenderer>();
LineRenderer lr = myLine.GetComponent<LineRenderer>();
lr.positionCount = 4;
lr.SetPosition(0, new Vector3(-2, 0, 0));
lr.SetPosition(1, new Vector3(2, 0, 0));
lr.SetPosition(2, new Vector3(2, -2, 0));
lr.SetPosition(3, new Vector3(-2, -2, 0));
lr.materials[2].color = Color.blue;
lr.materials[3].color = Color.red;
}
Take at look here.
Instead of altering the various materials, you could instead change the gradient of the line renderer through the colorGradient property.
So in your case you could add the following:
gradient.SetKeys(
new GradientColorKey[] {
new GradientColorKey(Color.red,0.0f),
new GradientColorKey(Color.red, 0.25f),
new GradientColorKey(Color.blue, 0.5f),
new GradientColorKey(Color.blue, 1.0f)},
// Alpha key
);
If you want a more abrupt transition, you could add color keys at 0.49 and 0.51 for example.

Assigning different materials to different meshes on the same object

I initially had a function that created a rectangular mesh given a specific height/width:
void BoxMesh(float width, float height)
{
MeshFilter mf = GetComponent<MeshFilter>();
Mesh mesh = new Mesh();
mf.mesh = mesh;
//Verticies
Vector3[] verticies = new Vector3[4]
{
new Vector3(0,0,0), new Vector3(0, height, 0), new Vector3(width, height, 0), new Vector3(width, 0, 0)
};
//Triangles
int[] tri = new int[6];
tri[0] = 0;
tri[1] = 1;
tri[2] = 3;
tri[3] = 1;
tri[4] = 2;
tri[5] = 3;
//normals
Vector3[] normals = new Vector3[4];
normals[0] = -Vector3.forward;
normals[1] = -Vector3.forward;
normals[2] = -Vector3.forward;
normals[3] = -Vector3.forward;
//UVs
Vector2[] uv = new Vector2[4];
uv[0] = new Vector2(0, 0);
uv[1] = new Vector2(0, 1);
uv[2] = new Vector2(1, 1);
uv[3] = new Vector2(1, 0);
//initialise
mesh.vertices = verticies;
mesh.triangles = tri;
mesh.normals = normals;
mesh.uv = uv;
//setting up collider
polyCollider.pathCount = 1;
Vector2[] path = new Vector2[4]
{
new Vector2(0,0), new Vector2(0, height), new Vector2(width, height), new Vector2(width, 0)
};
polyCollider.SetPath(0, path);
}
I then decided I wanted this mesh to have an outline so I edited the function so it is now:
void BoxMesh(float width, float height, float OLwidth)
{
MeshFilter mf = GetComponent<MeshFilter>();
Mesh mesh = new Mesh();
mf.mesh = mesh;
MeshFilter mfOL = GetComponent<MeshFilter>();
Mesh meshOL = new Mesh();
mfOL.mesh = meshOL;
//Verticies
Vector3[] verticies = new Vector3[4]
{
new Vector3(0,0,0), new Vector3(0, height, 0), new Vector3(width, height, 0), new Vector3(width, 0, 0)
};
//Verticies Outline
Vector3[] verticiesOL = new Vector3[4]
{
new Vector3(-OLwidth,-OLwidth,0), new Vector3(-OLwidth, height + OLwidth, 0), new Vector3(width + OLwidth, height + OLwidth, 0), new Vector3(width + OLwidth, -OLwidth, 0)
};
//Triangles
int[] tri = new int[6];
tri[0] = 0;
tri[1] = 1;
tri[2] = 3;
tri[3] = 1;
tri[4] = 2;
tri[5] = 3;
//normals
Vector3[] normals = new Vector3[4];
normals[0] = -Vector3.forward;
normals[1] = -Vector3.forward;
normals[2] = -Vector3.forward;
normals[3] = -Vector3.forward;
//UVs
Vector2[] uv = new Vector2[4];
uv[0] = new Vector2(0, 0);
uv[1] = new Vector2(0, 1);
uv[2] = new Vector2(1, 1);
uv[3] = new Vector2(1, 0);
//initialise
mesh.vertices = verticies;
mesh.triangles = tri;
mesh.normals = normals;
mesh.uv = uv;
meshOL.vertices = verticiesOL;
meshOL.triangles = tri;
meshOL.normals = normals;
meshOL.uv = uv;
//setting up collider
polyCollider.pathCount = 1;
Vector2[] path = new Vector2[4]
{
new Vector3(-OLwidth,-OLwidth,0), new Vector3(-OLwidth, height + OLwidth, 0), new Vector3(width + OLwidth, height + OLwidth, 0), new Vector3(width + OLwidth, -OLwidth, 0)
};
polyCollider.SetPath(0, path);
}
So i now have two meshes one outside the other. However I want the one on the outside to have a different material: so it looks like an outline.
I have these two materials in my mesh renderer, so how would I go about assigning one material to the outer mesh, and another to the inner mesh.
The concept you might be missing here is "SubMesh", each submesh of a mesh will be rendered using a material from the list at a given index.
To create a submesh you can call
mesh.SetTriangles(int[] triangles, int submesh);
You can re-use your vertexes, by specifying different faces basing on the same list of points. If you specify more submeshes than materials, remaining submeshes will be rendered solid magenta.

How to rotate a camera around its own axis in WPF viewport3D?

I am working on a 3D application in WPF and having trouble with the camera. It should be possible to rotate the camera around its own axis (with other words, look around) using the mouse but I can not get it to work properly. I create the camera with the following code:
PerspectiveCamera perspectiveCamera = new PerspectiveCamera(new Point3D(0, 30, 0), new Vector3D(0, -1, 0), new Vector3D(0, 0, 1), 90);
perspectiveCamera.NearPlaneDistance = 0.001;
perspectiveCamera.FarPlaneDistance = 1000;
center = new TranslateTransform3D(0, 30, 0);
rot_x = new AxisAngleRotation3D(new Vector3D(1, 0, 0), 0);
rot_y = new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0);
rot_z = new AxisAngleRotation3D(new Vector3D(0, 0, 1), 0);
zoom = new ScaleTransform3D(1, 1, 1);
Transform3DGroup t = new Transform3DGroup();
t.Children.Add(zoom);
t.Children.Add(new RotateTransform3D(rot_x));
t.Children.Add(new RotateTransform3D(rot_y));
t.Children.Add(new RotateTransform3D(rot_z));
t.Children.Add(center);
perspectiveCamera.Transform = t;
myViewport3D.Camera = perspectiveCamera;
And then I try to rotate it using the following code:
private void OnViewportMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (mouseLeftIsDown)
{
Point position = e.GetPosition(this);
double rotZAngle = (rot_z.Angle % 360) + oldLeftPosition.X - position.X;
double rotXAngle = (rot_x.Angle % 360) + position.Y - oldLeftPosition.Y;
if (rotZAngle < 0) //rotZAngle is negative, make it positive
{
rotZAngle = 360 + rotZAngle;
}
if (rotXAngle < 0) //rotXAngle is negative, make it positive
{
rotXAngle = 360 + rotXAngle;
}
rot_z.Angle = rotZAngle;
rot_x.Angle = rotXAngle;
oldLeftPosition = position;
}
}
However, it seams that the rotation is not happening around the camera and instead somehere else. The model that I load at position (0,0,0) is becoming visible after I rotate 180 degrees around the z axis which should not be the case.
What am I missing?

Scrolling a 3D Object and it's Texture Upwards

So I'm building a windows game, and I've got some text as a texture on a primitive. I'm trying to scroll the primitive upwards, but cannot accomplish this. I've tried simply adding a value to the Y position of the Vector3, but there's issues here.
I initialize the vertexes with:
verts = new VertexPositionTexture[4];
verts[0] = new VertexPositionTexture(new Vector3(-xPosition, yPosition, 0), new Vector2(0,0));
verts[1] = new VertexPositionTexture(new Vector3(xPosition, yPosition, 0), new Vector2(1, 0));
verts[2] = new VertexPositionTexture(new Vector3(-xPosition, negY, 0), new Vector2(0, 1));
verts[3] = new VertexPositionTexture(new Vector3(xPosition, negY, 0), new Vector2(1, 1));
Then When I try to get this to scroll upwards by adding to the Y coordinates, several things can happen.
If I add to both the variables for the y coordinates like this :
yPosition += .01f;
negY += .01f;
verts[0].Position.Y = yPosition;
verts[1].Position.Y = yPosition;
verts[2].Position.Y = negY;
verts[3].Position.Y = negY;
The texture, or the primitive all together doesn't even show up anymore. If I comment out the negY += .01f, the top of the primitive scrolls upwards, but this begins to distort the texture obviously. Why doesn't this work?! Why does adding to the negY bork the whole deal?

Categories