We have redirected you to our new domain: store.godotengine.org. Please update your bookmarks!

Description
Changelog
Reviews

             

Godot Vision Plugin

A Godot plugin that provides a unified GDScript interface for ML Kit face mesh detection on Android and iOS. Pass any Image to the Vision node and receive rich per-face data including 468 3-D landmark points, triangle mesh indices, and named facial contours — all in a single async call.

Key Features:

  • Detect one or more faces in any Image using ML Kit's Face Mesh API
  • Receive 468 normalised 3-D landmark points per face (x/y ∈ [0, 1], z = relative depth)
  • Access the full triangle mesh (indices into the landmark array) for each detected face
  • Query individual named contours — face oval, eyes, eyebrows, lips, and nose bridge — via FaceMeshInfo constants
  • Built-in wireframe drawing utilities: overlay a mesh on an existing image or generate a transparent mesh layer for compositing
  • Typed result and error classes (FaceScanResult, FaceMeshInfo, ScanError) for clean, idiomatic GDScript

Table of Contents

Installation

_Before installing this plugin, make sure to uninstall any previous versions of the same plugin._

_If installing both Android and iOS versions of the plugin in the same project, then make sure that both versions use the same addon interface version._

There are 2 ways to install the Vision plugin into your project:

  • Through the Godot Editor's AssetLib
  • Manually by downloading archives from Github

Installing via AssetLib

Steps:

  • search for and select the Vision plugin in Godot Editor
  • click Download button
  • on the installation dialog...
    • keep Change Install Folder setting pointing to your project's root directory
    • keep Ignore asset root checkbox checked
    • click Install button
  • enable the plugin via the Plugins tab of Project->Project Settings... menu, in the Godot Editor
Installing both Android and iOS versions of the plugin in the same project

When installing via AssetLib, the installer may display a warning that states "_[x number of]_ files conflict with your project and won't be installed." You can ignore this warning since both versions use the same addon code.

Installing manually

Steps:

  • download release archive from Github
  • unzip the release archive
  • copy to your Godot project's root directory
  • enable the plugin via the Plugins tab of Project->Project Settings... menu, in the Godot Editor

Usage

Add a Vision node to your main scene or an autoload global scene.

  • connect Vision node signals before calling scan_face()
    • face_mesh_ready(result: FaceScanResult) — emitted when detection succeeds
    • face_mesh_failed(error: ScanError) — emitted when detection fails
  • call vision.scan_face(image) with any Image; the image is automatically converted to FORMAT_RGBA8 if needed
  • in the face_mesh_ready callback, iterate over result.get_faces() to access per-face landmark data
  • optionally use the static drawing helpers to render the mesh directly onto an image

Basic face scan example:

@onready var vision := $Vision

func _ready() -> void:
    vision.face_mesh_ready.connect(_on_face_mesh_ready)
    vision.face_mesh_failed.connect(_on_face_mesh_failed)

func scan(image: Image) -> void:
    vision.scan_face(image)

func _on_face_mesh_ready(result: FaceScanResult) -> void:
    print("Detected %d face(s)" % result.get_face_count())
    for face in result.get_faces():
        print("  Points: %d, Triangles: %d" % [face.get_points().size(), face.get_triangles().size()])

func _on_face_mesh_failed(error: ScanError) -> void:
    print("Scan failed [%s]: %s" % [error.get_code(), error.get_description()])

Drawing the mesh overlay onto an image:

func _on_face_mesh_ready(result: FaceScanResult) -> void:
    # Returns a new Image with the wireframe painted on top
    var annotated: Image = Vision.draw_face_mesh_on_image(original_image, result, Color.CYAN)
    $TextureRect.texture = ImageTexture.create_from_image(annotated)

Generating a transparent mesh layer for compositing:

func _on_face_mesh_ready(result: FaceScanResult) -> void:
    var mesh_layer: Image = Vision.generate_face_mesh_image(
        result, original_image.get_width(), original_image.get_height(), Color.LIME)
    $MeshOverlay.texture = ImageTexture.create_from_image(mesh_layer)

Accessing individual contours:

func _on_face_mesh_ready(result: FaceScanResult) -> void:
    var face: FaceMeshInfo = result.get_face(0)
    if face:
        var oval: Array = face.get_contour(FaceMeshInfo.CONTOUR_FACE_OVAL)
        for point in oval:
            print("Oval point: ", point)  # Vector3 — x/y normalised, z = depth

Signals

Register listeners to the following signals of the Vision node:

Signal Description
face_mesh_ready(result: FaceScanResult) Emitted when face mesh detection succeeds. result contains the image dimensions and an array of FaceMeshInfo objects, one per detected face.
face_mesh_failed(error: ScanError) Emitted when detection fails. error contains a ScanError.Code enum value and a human-readable description.

Methods

Vision node methods

Method Description
scan_face(a_image: Image) -> void Sends a_image to the native plugin for ML Kit face mesh detection. The image is automatically converted to FORMAT_RGBA8 internally. Results are delivered asynchronously via the face_mesh_ready or face_mesh_failed signals.

Static drawing utilities

These are pure-GDScript helpers that operate on a FaceScanResult returned by the face_mesh_ready signal. They require no scene nodes or rendering server calls.

Method Description
Vision.generate_face_mesh_image(a_result: FaceScanResult, a_width: int, a_height: int, a_color: Color) -> Image Creates a new FORMAT_RGBA8 image of the given dimensions with a fully transparent background, then draws the face mesh wireframe in a_color. Use this to composite the mesh as a separate layer on top of your camera frame.
Vision.draw_face_mesh_on_image(a_original: Image, a_result: FaceScanResult, a_color: Color) -> Image Returns a new FORMAT_RGBA8 copy of a_original with the face mesh wireframe painted on top in a_color. The original image is not modified.

Classes

FaceScanResult

Encapsulates the full result of a scan_face() call. Received via the face_mesh_ready signal.

Method Return type Description
get_image_width() int Width (px) of the image that was scanned.
get_image_height() int Height (px) of the image that was scanned.
get_face_count() int Number of faces detected in the image.
get_face(a_index: int) FaceMeshInfo Returns the FaceMeshInfo at the given index, or null if out of range.
get_faces() Array Returns all detected faces as an Array of FaceMeshInfo objects.
is_valid() bool Returns true when all required fields are present in the result.
get_raw_data() Dictionary Returns the underlying raw data dictionary.

FaceMeshInfo

Encapsulates the mesh data for a single detected face.

Method Return type Description
get_points() Array All 468 landmark points as Vector3. x and y are normalised to [0, 1]; z is relative depth.
get_triangles() Array All mesh triangles as Vector3i. Each component (x, y, z) is an index into the get_points() array.
get_contours() Dictionary Raw contours dictionary keyed by contour name. Values are arrays of [x, y, z] sub-arrays.
get_contour(a_contour_name: String) Array Points of a named contour as Array of Vector3. Use the CONTOUR_* constants as the name argument.
is_valid() bool Returns true when points, triangles, and contours are all present.
get_raw_data() Dictionary Returns the underlying raw data dictionary.

Contour name constants (pass to get_contour()):

Constant Facial region
CONTOUR_FACE_OVAL Outer boundary of the face
CONTOUR_LEFT_EYE Left eye outline
CONTOUR_LEFT_EYEBROW_BOTTOM Bottom edge of the left eyebrow
CONTOUR_LEFT_EYEBROW_TOP Top edge of the left eyebrow
CONTOUR_LOWER_LIP_BOTTOM Outer bottom edge of the lower lip
CONTOUR_LOWER_LIP_TOP Inner top edge of the lower lip
CONTOUR_NOSE_BRIDGE Bridge of the nose
CONTOUR_RIGHT_EYE Right eye outline
CONTOUR_RIGHT_EYEBROW_BOTTOM Bottom edge of the right eyebrow
CONTOUR_RIGHT_EYEBROW_TOP Top edge of the right eyebrow
CONTOUR_UPPER_LIP_BOTTOM Inner bottom edge of the upper lip
CONTOUR_UPPER_LIP_TOP Outer top edge of the upper lip

ScanError

Encapsulates error information delivered via the face_mesh_failed signal.

Method Return type Description
get_code() ScanError.Code One of the Code enum values below.
get_description() String Human-readable description of the error.

ScanError.Code enum values:

Value Meaning
NONE No error.
INVALID_IMAGE The supplied image could not be processed.
NO_CODE_DETECTED No face was detected in the image.
SCANNER_FAILURE The underlying ML Kit scanner returned a failure.
INTERNAL_ERROR An unexpected internal error occurred.

ImageInfo

Wraps a Godot Image as a serialisable dictionary for transfer to the native plugin. Used internally by scan_face() — you do not normally need to use this class directly.

Method Return type Description
ImageInfo.create_from_image(a_image: Image) (static) ImageInfo Creates an ImageInfo from a Godot Image.
get_buffer() PackedByteArray Raw pixel bytes of the image.
get_width() int Image width in pixels.
get_height() int Image height in pixels.
get_format() Image.Format Pixel format of the image.
has_mipmaps() bool Whether the image has mipmaps.
is_valid() bool Returns true when width, height, and buffer are all present.
get_raw_data() Dictionary Returns the underlying raw data dictionary.

Platform-Specific Notes

Android

  • Download Android export template and enable gradle build from export settings
  • Troubleshooting:
  • Logs: adb logcat | grep 'godot' (Linux), adb.exe logcat | select-string "godot" (Windows)
  • You may find the following resources helpful:
    • https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_android.html
    • https://developer.android.com/tools/adb
    • https://developer.android.com/studio/debug
    • https://developer.android.com/courses

iOS

Links

Changelog for version v1.0-Multi

No changelog provided for this version.

Reviews (0)

Vision Plugin has no reviews yet.

Login to write a review.