- Home /
Mesh rendered wierdley without depth buffer
I'm trying to achieve an optical illusion.
In order to do so I cut my mesh into two pieces. One of them should be rendered in front of the other even though it's behind it. This is my setup: that's how it looks like in the end:
Now my question is: How to remove the wrongly rendered part at the left edge?
Btw: It happens not only there, but on the other site too.
Thank you.
Answer by Bunny83 · Jul 27, 2016 at 02:36 PM
Well, since you disabled the depth test, the triangles are rendered in the order they are specified in the Mesh. You problem is that the lower left part of the mesh is most likely more at the beginning of the mesh triangle list while that part that "looks through" is more to the end of your mesh triangle list.
If you disable the depthbuffer you actually could have used a single mesh. You just have to make sure you ordered the triangles the way you need them. If that extra part would be added to the first mesh at the end of the triangle list it would appear above the other.
So your solutions are:
either use the depth buffer, render the first object, clear the depth buffer and then render the second mesh.
If you don't use the depth buffer you should reorder your triangles of your mesh so they are drawn in the right order.
edit
Here's a script that you should simply add to your mesh and it should reorder the triangles from right to left.
// ReorderMeshTriangles.cs
using UnityEngine;
using System.Collections.Generic;
public class ReorderMeshTriangles : MonoBehaviour
{
private struct Triangle
{
public int I1;
public int I2;
public int I3;
public Vector3 center;
public Triangle(int aI1, int aI2, int aI3, Vector3[] verts)
{
I1 = aI1;
I2 = aI2;
I3 = aI3;
center = (verts[I1] + verts[I2] + verts[I3]) / 3;
}
}
void Start()
{
var mf = GetComponent<MeshFilter>();
var m = mf.mesh;
var verts = m.vertices;
var indices = m.triangles;
var tris = new List<Triangle>(indices.Length / 3);
for(int i = 0; i < indices.Length; i+=3)
{
tris.Add(new Triangle(indices[i], indices[i + 1], indices[i + 2], verts));
}
tris.Sort((a,b)=>a.center.x.CompareTo(b.center.x));
for (int i = 0; i < tris.Count; i++)
{
indices[i * 3 ] = tris[i].I1;
indices[i * 3 + 1] = tris[i].I2;
indices[i * 3 + 2] = tris[i].I3;
}
m.triangles = indices;
}
}
When you run your game it should look right.
Note: I haven't tested it so i'm not sure if the sorting direction is correct. If it's not you just want to swap "a" and "b" inside the sorting function:
tris.Sort((a,b)=>b.center.x.CompareTo(a.center.x));
/|\ /|\
| |
// here and here
Of course if "right" isn't the x axis you have to change the "x" as well to whatever you need.
@Bunny83 Thanks for your answer. But how can I reorder the triangles in the right order? - I could't find anything here.
And how could I clear the depth buffer after one mesh has already been rendered?OnPostRender?
Also what would the depth be now? Still 1.0?
Sorry the many questions.
Well, reordering the triangles can be tricky and it depends on where does this mesh come from? If it's created in a modelling application you could search for such a feature there. However a lot exporter don't give a damn about the order ^^.
An imported mesh can't be edited in place as the imported mesh could reimported and any changes would be lost. With an editor script you could save a modifed mesh as seperate asset.
Apart from creating a new asset you can also edit the mesh during runtime. In your case an automatic sorting in some direction would probably be enough. So sorting them from right to left should fix the problem. Calculating the center of each triangle and sorting them based on the x component should do the trick.
ps: I've edited my answer and added a script that will reorder the triangles based on their x position.
Thanks for the script. When I run it the $$anonymous$$esh gets both times replaced by the first mesh and both are scaled up and rotated somewhere in the space. Also it shows two different errors:
Not allowed to access vertices on mesh 'Combined $$anonymous$$esh (root: scene) Instance' UnityEngine.$$anonymous$$esh:get_vertices() Reorder$$anonymous$$eshTriangles:Start() (at Assets/Scripts/Reorder$$anonymous$$eshTriangles.cs:25)
(also at line 26)Not allowed to access triangles on mesh 'Combined $$anonymous$$esh (root: scene) Instance' UnityEngine.$$anonymous$$esh:set_triangles(Int32[]) Reorder$$anonymous$$eshTriangles:Start() (at Assets/Scripts/Reorder$$anonymous$$eshTriangles.cs:41)
I think I'll find another way doing this Thanks anyway.
Since it says "Combined $$anonymous$$esh" seems that you either have combined the meshes yourself or they are statically batched. Have you marked them as static? Try to unceck the static checkbox if it is checked.
Where does the mesh actually come from? Is it an imported FBX file? It's clear that the meshes got combined into one.
I don't have your mesh to test it. If i attach the script to a default sphere gameobject i don't get any errors.
Yes I could get rid of the error by unchecking the static box.
I created the model in blender an exported it as a FBX file.
But somehow my problem won't go away.