Getting the surfaces of a part that are visible to the camera

I currently have a texture system that’s optimal enough as it is, that places textures on parts depending on the configured render distance. (Textures are for roads, walls, and for buildings)

The problem is that I am currently applying textures on all four sides of each part which is not good at all and generally could hog up a bunch of memory. That being said I haven’t been able to come up with a definitive method for detecting what surfaces are visible to the players camera.

I thought of the idea of using raycasts to determine which surfaces are visible to the camera but I am unsure how performance heavy it would be (Assuming it would be very performance heavy giving the length of the raycasts themselves.)

If you have any possible ideas on how I could go about achieving this let me know, much would be appreciated.

1 Like

Something like this should work:

function isSurfaceVisible(part, surface, fromPoint)
	return part.CFrame:VectorToWorldSpace( Vector3.FromNormalID(surface) ):Dot(fromPoint - part.Position) < 0
end

You call it like so: isSurfaceVisible(thePart, Enum.NormalId.Front, theCamera.CFrame.Position).

Here’s a version that might be easier to understand:

function isSurfaceVisible(part, surface, fromPoint)
	--The direction in world space that the given surface of the part is facing
	local surfaceNormal = part.CFrame:VectorToWorldSpace( Vector3.FromNormalID(surface) )
	
	--The vector from "fromPoint" to the part
	local vectorTo = (fromPoint - part.Position)

	--[[If the dot product of these is < 0, then they're facing somewhat "away" from  each other.
	If it's > 0, they're somewhat towards each other
	If it's 0, they're at right angles to each other]]
	return surfaceNormal:Dot(vectorTo) < 0
end
Here's an illustration of what's going on:

‘’

The feint blue lines show the view frustum of the camera. Notice that they don’t actually matter in this case. The surface is facing towards the camera, so the dot product is positive.


Here the surface is facing away from the camera, so the dot product is positive.

These examples are in 2D, but it also works in 3D.

You should probably also check if the part is inside the view frustum of the camera. Check out Camera.WorldToScreenPoint or Camera.WorldToViewportPoint. In both cases the 3rd returned value is a bool indicating whether the world point is on the screen or outside it.

Let me know if you have any questions

5 Likes