r245
r245

Reputation: 11

Hide an object for a specific camera

I use godot to create my 3d game. I ran into a problem while creating portals using camera viewport rendering to texture. The problem is that the camera captures unnecessary objects that are behind portal. I partially solved this problem by setting the parameter "near " for the camera at a distance from the camera itself to the portal, but the part behind the portal began to be cut off. The question is, is it possible to hide objects for a particular camera so that other cameras can see them? Perhaps there is another way to do this, for example by creating a static clipping plane?

Upvotes: 1

Views: 3142

Answers (1)

Theraot
Theraot

Reputation: 40170


Proximity Fade

Probably not what you are looking for, but I'll mention it for completeness sake.

The default material has proximity fade and distance fade, which you can use to make the material disappear if it is too close or to distant from the camera, respectively.

It is important to note that this is not a cull plane, and that the fading is gradual.

Thus, using proximity fade you can make objects near the camera appear semitransparent.


Using Visibility layers and cull mask

is it possible to hide objects for a particular camera so that other cameras can see them?

Every VisualInstance (you know, all things that are visible in 3D) has layers. And every Camera has a cull_mask. If the cull_mask of the Camera does not include any of the layers of a VisualInstance, then the Camera does not see that VisualInstance.

A VisualInstance with no layers will not show on no Camera, even if the Camera has all the layers in its cull_mask (which is the default).

You can either edit the cull_mask of the camera to not include the layers of the VisualInstance, or edit the layers of the VisualInstance, or both.


Using a custom shader cull plane

Perhaps there is another way to do this, for example by creating a static clipping plane?

You can use a custom spatial shader to cut things out based on a plane.

You need to define the plane as a uniforms. For this answer I'll use a point-normal definition of a plane:

n·(r - r_0)

That is:

dot(plane_normal, (world_position - plane_point)

Thus, we define a plane_normal and plane_point uniforms:

uniform vec3 plane_normal;
uniform vec3 plane_point;

The plane_normal gives us the orientation of the plane, while the plane_point is a point on the plane which allows us to position it.

And then use this logic:

vec3 wold_position = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
ALPHA = clamp(sign(dot(plane_normal, wold_position - plane_point)), 0.0, 1.0);

Here we are converting the coordinates of the current point to world space, and then using definition of the plane to find the points on one side (using sign), and set ALPHA based on that, such that everything on one side of the plane becomes invisible.

Note: This is not the only way to define the plane. Another popular definition is a 4D vector, where the xyz are the normal, and the w is the distance from plane to the origin.

Sadly, I don't think there is a way to make this work with multiple material passes, because ALPHA controls the blending of the passes, and will not result in transparency. And no, using discard; does not solve it either, because the other passes can write the fragment regardless. Thus, you are going to need to modify your materials to include that.

Further Sadly Godot 3.x does not support global uniforms (see Godot 4.0 gets global and per-instance shader uniforms). Which means you will have to set these parameter everywhere you need them.


Using Constructive Solid Geometry (CSG)

Add a CSGCombiner make the geometry that needs to disappear with other CSG nodes as children.

Then you can, for example, add a CSGSphere with operation set to "Subtraction", and move it with the Camera (for this purpose, I suggest to add a RemoteTransform node as child to the Camera and set its remote path to the CSGSphere).

Of course, it does not have to be a CSGSphere, you can use any CSG nodes for this purpose. For the portal, I imagine you could use a CSGBox and align it to the portal plane.

Note: Currently on Godot 3.3 CSG nodes do not support baking lights. This is a regression. See: Unable to bake lightmap with CSG due to the lack of ability to generate UV2 for CSG nodes.


Portals, actually

Bartleby Lawnjelly has a portal (godot-lportal) module for Godot 3.x.

Being a module, they require to build Godot from source. See Compiling on the official Godot documentation. It is not that bad, I promise. Or use build from godot-titan.

I have to explain that these portals are not portals in the Valve Portal video game series sense… The module lets you define areas as "rooms", and planes as "portals" that connect those rooms, in such way that you can look from one to the other. The purpose of this is to cull entire rooms unless you are looking through one of the portals.

Hopefully that makes more sense with a video. This is a somewhat old one, but good to get the idea across: Portal rendering module in Godot 3.2 - Improved performance. Seeing shadow pooping in the video? Bartleby Lawnjelly also has a custom lightmapper.

Upvotes: 1

Related Questions