How would I hide an object from a specific camera in Godot 3D? - game-development

I'm working on a multiplayer horror game in Godot and I want to make it so you can't see your own body but others can. I heard about culling masks for this but I have no idea how they work and if what I'm trying to achieve is possible using them. The body is a Skeleton node and others should be able to see it but my camera (a sibling of the skeleton node) shouldn't be able to. Could someone explain how I might be able to do this?

The Skeleton is not visible. However, you must have some children VisualInstances (usually MeshInstance) which are actually visible.
In the usual setup, you have a Skeleton node, with multiple MeshInstance as children, which also have their skeleton property set to the Skeleton node.
I don't know how you are setting up your multiplayer, but if it is not split-screen you probably can swap or remove the player character but not those of the other players. If removing the Skeleton is not viable, you should still be able to remove or hide its children VisualInstances.
Anyway, if you do need to setup multiple cameras, you can se the layers on the MeshInstance (or whatever VisualInstance you are using) and the cull_mask on the Camera. If they overlap (they have common bit flags) then the Camera will render that MeshInstance, otherwise it wont.
See also Hide an object for a specific camera.

Related

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?
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.

Getting Contact Information with Tiles in Godot

Can I somehow get information that the player has touched a specific tile located in the resource (tilemap.res)?
It is necessary to determine which tile it stands on (for example, on land or in water)
It depends on what kind of behavior you're expecting. There's two major ways to do this:
In each individual script that you want to be affected by the tiles, get the tile it's on every time it moves, then run the logic directly from there.
As above, get the tile the unit is on each time it moves, but instead of just running the logic every time, emit a signal whenever the tile changes, and keep the current tile cached so you can check when it's on a new tile; have the TileMap itself attach to the signal, and when it receives the signal, act on the Node2D until it leaves. This is what I'd do.
The exact method to find the tile is TileMap.world_to_map(TileMap.get_cellv(Node2D.position))--you just need to have the Node2D and the TileMap, and you can get both in the same function using the above two methods.
Technically, you could also procedurally add Area2Ds to the tilemap based on the tiles at various positions using TileMap.get_used_cells_by_id, making sure that the ID is the one that has the special behavior, then attaching the TileMap to those areas' body/area_entered and body/area_exited and using that, but spamming a whole lot of Area2Ds isn't necessary when you can check the tile a Node2D is on directly.

Exclude objects from camera in Three.js

i'm wondering if it's possible to hide a list of objects from a camera (used to build a reflaction map over a plan, simulating the water).
So basicly i'd want to hide a list of objects from the water reflaction.
The Object3D.visible property will of course hide the object for the main camera too so it's useless.
Any idea?
before you update the reflection camera, hide the objects, when the reflection map is rendered, make them visible again.
without your current code i wouldnt be able to provide you with example code since there are several ways to accomplish reflection.

Three.js 3rd person camera

I'm trying to create a 3rd person camera view in three.js
I'm using the THREE.FirstPersonControls(); on my camera. Then setting the rotation and positions of my "player" objects to be the same as the camera with some offsets.
This does not seem to work.
What i'm more wondering is if I should be adding my FirstPersonControls to the camera and then rendering the "player" infront of it. Or adding the controls to the player then making the camera always point at the back of the player?
EDIT:
I've tried setting the player object to be a sub object of the camera using camera.add(player);
but moving the camera around is not moving the player. I thought adding an child element would mean they move together?
EDIT 2:
I took another approach of adding both the camera and the player to a group then adding my 1st person controls to that group... Now both the camera and the player do get rendered. But it's completely thrown off how the first person controls worked. (e.g. looking down goes left etc etc)
Thanks for any help,
James
First of all, the Controls were designed to be controlling a camera, and not an object. And since by default, objects look "up" the z-axis, and cameras look "down" the z-axis, it is unlikely that the Controls will work as expected when applied to something other than a camera.
Secondly, the Controls are part of the examples, and not the library, so they are not officially supported. You are free to hack away at them.
One way to achieve what you want is to make the camera a child of your player. Something like this:
player.add( camera );
camera.position.set( 0, 50, 100 );
You may, in your render loop, need to set:
camera.lookAt( player.position );
Then you want to control the player with the mouse or keyboard. Your best bet is to write your own controller to do that. There are plenty of examples on the net.

Creating a Quartz Composer Style interface

I'm wanting to add a Quartz Composer "patch editor" style interface element to my Cocoa/Objective C(++) application. For those unfamiliar with QC, the patch editor is a visual representation of the patch graph: effectively showing each node and it's properties, and providing a mouse driven select/click/drag interface. It looks like...
Quartz Composer Example http://files.me.com/archgrove/ya1xhh
I'll be using it to render a specific type of multi-rooted tree, where each node has some associated text and an arc joining it to its children. Users will be clicking on the tree nodes to select them, as well as dragging them around.
At the moment, I'm using a custom NSView inside a scroll view that Quartz draws each node, the arcs etc at each render, and processes mouse and keyboard input by hand (including hit testing, movement and so forth). This seems brutally wheel reinventive, and doesn't interact all that well with Core Animation. I'm hoping someone has some general alternative advice. I'm pondering along the lines of...
An existing control/3rd party library I've overlooked
Make each node in the tree an NSView, and use the normal view structure to handle the input, whilst drawing the graphics in the same way. But then, the inter-node arc rendering doesn't seem to fit naturally into the design
Something using a single NSView still, but making each tree node and arc an individual layer
Something else
Thanks kindly,
adamw
You might want to give EFLaceView a look: FlowChartView on CocoaDev
Edit: download link on page above is dead. There is a version of EFLaceView on github.