I’m going to try and explain this without being too confusing, but…
I’m essentially looking for a way to imitate the way one-sided planes render, but with 3D objects - meaning I want to be able to see through the object from one side, but have it render on the other.
The use case for this is hallway walls in an isometric game. I want the player to be able to see the floor and enemies through walls when view from the back side, but then have the front side render when looking down the hallway (see images for example).
I was using planes for this because it gave me the exact behavior I wanted, but when I started using more complex shapes to make the level, you know, interesting, I started running into issues.
The primary issue is that any surface that’s even sort of rotated backward in the direction of the camera will render - you can see this most clearly at the bottom of the second image. The horizontal gold stripe running down the middle of the floor is actually a strip of gold on the walls facing away from the camera, but the strip is angled slightly back toward the camera to give it some contouring.
A solution I had in mind for this was to use a dot product to see whether the camera was in front of the wall or not - if it isn’t, turn off the mesh renderer entirely - if it is, turn it back on. However, just in this scene alone, which is just a test scene, there are 71 small sections of wall that would all individually have to do this check regularly - and even if I grouped them up by sections of wall, we’re already talking about 17 sections and I’m not convinced that the dot product solution will scale to a production-sized level.
It feels like there ought to be a better solution to this - maybe something shader graphy, but my shader graph skills are admittedly not strong enough to be able to puzzle out the solution alone.
Dot products are super cheap. Unity is doing significantly more expensive operations on every single game object in the scene every frame to check if the bounds are in view or not. Adding a dot product on top of that isn’t really going to be an issue. It may even save you some time per frame to skip having to render those objects.
The main thing is you probably want to setup some kind of manager that handles this, maybe using c# jobs, rather than running the dot product in an LateUpdate for every frame. If you do that you can probably handle a few hundred thousand of these kinds of checks per frame without a noticeable problem.
That said, doing it with a shader isn’t a terrible idea either. There are nodes to get the object’s position, and you can transform a Vector3 from object to world space to get the world space “front” direction. Then there are nodes for getting the world space camera position, and a dot product node. And that’s all of the parts you need. The best option for hiding the mesh cheaply would be to override the Vertex Position with a hardcoded value, like Vector3(0,0,0), if the dot product fails (using Comparison and Branch nodes).