A normal or normal vector is a vector that represents the direction perpendicular to a surface. Think of it as an arrow pointing directly outward from an object's surface at a 90-degree angle to it. In games, normal vectors help determine how light interacts with surfaces or how objects collide.
If you think of the ground plane, the normal vector points straight up, perpendicular to the plane.
For a vertical wall, the normal would point straight out from the wall.
You can use normal vectors in various ways in game development:
- To find where the mouse cursor points in a 3D game environment.
- To calculate how light interacts with a 3D model in shaders.
- To determine how objects get pulled off each other when collisions occur in a physics simulation.
- To reflect or bounce objects off surfaces.
When you want to know where the mouse cursor points in a 3D game environment, you can use the normal vector of the camera and a RayCast3D
node to detect what the mouse is pointing at. Here's an example of how you can do this in Godot:
var camera: Camera3D = %Camera3D
var raycast: RayCast3D = %RayCast3D
func _physics_process(delta: float) -> void:
const PROJECT_RAY_LENGTH := 40.0
var mouse_position_2d := get_viewport().get_mouse_position()
var mouse_ray := PROJECT_RAY_LENGTH * camera.project_ray_normal(mouse_position_2d)
raycast.cast_to = mouse_ray
if raycast.is_colliding():
var collision_point := raycast.get_collision_point()
When two objects collide, you can get the normal vector of the collision to determine how the objects should react. When a collision occurs, Godot provides you with a KinematicCollision2D
or KinematicCollision3D
object, depending on whether you're working in 2D or 3D. This object contains information about the collision, including the normal vector.
For example, when calling CharacterBody3D.move_and_collide()
in 3D, you can get the normal vector like this:
extends CharacterBody3D
func _physics_process(delta: float) -> void:
var collision := move_and_collide(velocity * delta)
if collision != null:
var normal := collision.get_normal()
See Also
Related terms in the Glossary