- Home /
vertices in current camera view
Hi,
New to Unity. Trying to get the list vertices for each object in the camera view. But not getting the correct result. Using bounding check i.e.
Vector3 tmp_screen_point = cam.WorldToViewportPoint(transform.TransformPoint(verts[vert]));
if (tmp_screen_point.z > 0 && (tmp_screen_point.x > 0 && tmp_screen_point.x < 1) && (tmp_screen_point.y > 0 && tmp_screen_point.y < 1))
and Ray cast method (Rays from the Camera). Using Raycast to exclude occluded vertices. Here is my code snippet:
void Start()
{
//Get the list of all active objetcs in the scene
MeshFilter[] object_mesh_list = FindObjectsOfType<MeshFilter>();
Camera cam = GameObject.Find("Main Camera").GetComponent<Camera>();
Vector3 camera_position = cam.transform.position;
Transform obj = transform;
//Debug.Log(camera_position);
RaycastHit ray_hit = new RaycastHit();
for (int i = 0; i < object_mesh_list.Length; i++)
{
Mesh obj_mesh = object_mesh_list[i].mesh;
Vector3[] verts = obj_mesh.vertices;
List<Vector3> in_frame_verts_raycast = new List<Vector3>();
List<Vector3> in_frame_verts_bound = new List<Vector3>();
for (int vert = 0; vert < verts.Length; vert++)
{
//Bounding Method
Vector3 tmp_screen_point = cam.WorldToViewportPoint(transform.TransformPoint(verts[vert]));
if (tmp_screen_point.z > 0 && (tmp_screen_point.x > 0 && tmp_screen_point.x < 1) && (tmp_screen_point.y > 0 && tmp_screen_point.y < 1))
{
in_frame_verts_bound.Add(verts[vert]);
}
//Camrea Ray cast method
Ray ray = cam.ViewportPointToRay(cam.WorldToViewportPoint(transform.TransformPoint(verts[vert])));
if (Physics.Raycast(ray, out ray_hit))
{
in_frame_verts_raycast.Add(verts[vert]);
}
}
Debug.Log("Raycast Method = Gameobject " + object_mesh_list[i].gameObject.name + " has total of: " + verts.Length.ToString() + " vertice and " + in_frame_verts_raycast.Count.ToString() + " are visible to camera");
Debug.Log("Bound Method = Gameobject " + object_mesh_list[i].gameObject.name + " has total of: " + verts.Length.ToString() + " vertice and " + in_frame_verts_bound.Count.ToString() + " are visible to camera");
}
}
and following screen shots show the output. Ray-cast method seems to working but not correct. Only 3 vertices of the quad are visible but it says all 4 are visible.
Imag1:
Now rotate camera and resits no vertices are visible.
--Thanks
any suggestion or pointer to fix the issue.
Answer by Bunny83 · Apr 21, 2020 at 01:15 AM
This piece in your code makes no sense:
transform.TransformPoint(verts[vert]))
The vertices are defined in local space of the object where the renderer / MeshFilter is attached to. You treat them as if they belong to the object this script is attached to. So your positions are all over the place.
You have to use:
object_mesh_list[i].transform.TransformPoint(verts[vert]))
Also note that you should not use the mesh property as even reading that property will instantiate the mesh for this MeshFilter. This creates a lot of garbage and also could breaks batching. You should use the "sharedMesh" property.
Thanks for the quick response. Now I see some correct results, but for now the occluded vertices are also include. Sample screen is attached. For the cube it saying all 24 vertices are visible and for the Quad 2 vertices are visible but in camera view we can see that only one is visible. could you please suggest the corrected approach to exclude the occluded vertices.
I'm not sure if I understand your current issue. Your whole code was about checking which vertices are in the camera frustum and the result you get looks right to me. If you're asking to check if a vertex is occluded by some other geometry (something completely different) it's not clear how you would define the "visibility" of a vertex. This would also be much more complicated. One of the easiest straight forward way to see if a vertex is actually be visible would be to use an additional LineCast from the camera to the vertex. This line cast should not hit anything. If it hits something it's not visible since something is blocking the view. However keep in $$anonymous$$d that raycasting only works against colliders, not the actual visible geometry. If the colliders fit the visuals perfectly this should not be an issue.
Also keep in $$anonymous$$d that the linecast could still hit your target object right at the corner where the vertex sits. So the line cast might need to be shorten a tiny bit, of you analyze the hit distance or hit point to see how close the ray got to the vertex. That way you can use a threshold and if it gets close enough you call it visible.