If your triangles are all aligned to CW or CCW, the following algorithm works very quickly:
When rendering the entire mesh with an orthographic projection from one direction (e.g., in the X direction) with the depth test disabled, each triangle that spans an area is rasterized. Inside the fragment shader, the depth value and the triangle direction ('bool gl_FrontFacing') are obtained.
These two information can be stored as a node in a linked list in a SHADER_STORAGE_BUFFER per pixel.
After rendering, one has to sort the linked lists by the depth values of the pixels.
When iterating a single pixel list, one should get a frontface node immediately followed by a backface node.This is not only the case, it can appear, that two following face directions are same. This usually occurs at edges were two triangles share the same edge. This need to be corrected by deleting the following one:
For two consecutive frontface nodes, keep only the node that is closer to the camera. For two consecutive backface nodes, keep the node which is farther away and delete the other.
Now you can check your 3D point by first calculating the pixel position of the point. Now find out between which nodes of the pixel the point is located. (the depth value)
If the point is closer to the camera than the first node, it is outside.
If the point is further away than the last node, it is outside.
If the point is between a front and a back node, it is inside.
If the point is between a back node and a front node, it is outside.
Now that we understand how the algorithm works, I have to say that you have to do this three times: in the X direction, in the Y direction, and in the Z direction.
If the point is outside in all 3 direction tests, it is outside. Otherwise it is inside.
Why do you have to do this three times? If a triangle is aligned in the X direction, it will not be rendered. If you do it in all (X, Y, Z) directions, each triangle will span an area in at least one of the three frames.
Additional positive effects:
After creating the three images (each with resolution_x * rosolution_y linked lists) as preprocessing step, you can check very fast if 3d Points are inside the mesh. The size of a single linked list within the image is very small (depends on the complexity of your mesh), so finding the correct position within the nodes can be very fast.