Giving 2D Scenes Depth with Perspective Quads in Godot.
by Vicente C.
Published |
8
Share
Perspective Quads gives 2D Godot scenes a sense of depth through texture warping, animated view changes and interfaces that stay interactive.
While working on first-person point-and-click games, BunkWire2X8 wanted to animate perspective changes on 2D textures. 

A four-point Polygon2D produced a diagonal seam, so they switched to shader-based UV warping and later developed Perspective Quads to make the approach easier to edit and reuse.
The addon builds on Viiragon’s homography shader, adapted from work by Haritha Thilakarathne and Florian Segginger. An inverse perspective matrix, calculated from the four corners, maps positions in the warped quad back to the texture’s original UVs.

Its PerspectiveQuad2D node extends Node2D and draws the texture directly. A custom bounding box accounts for the warped shape, keeping visible areas from being culled using the original texture bounds. 

The node also supports AtlasTexture, color modulation and optional edge antialiasing.

To prevent accidental material sharing when quads are duplicated, the material property stays read-only and is not saved with the scene. Custom shaders use material_override, with a unique ShaderMaterial based on the addon’s shader and Local to Scene enabled.

To animate between views, PerspectiveQuadShape stores four corners and a modulation color. These can blend along one axis or across a 2D grid. Matrices and bounds are cached and recalculated when the corners change.

When multiple quads need to respond together, Carousel2D broadcasts one view_position between 0 and 1. Connected quads use it to drive their blending, with an optional second carousel controlling the other axis.

Labels and other nodes can move with the scene through CarouselAnchor2D, which interpolates keyframed transforms using the carousel’s value.
The same mapping keeps warped interfaces interactive. PerspectiveViewportContainer2D displays a child SubViewport, converts pointer positions back to the original plane and forwards input to its controls. The local_to_plane_uv() helper exposes this conversion for custom nodes.

Each SubViewport also needs its own render pass, so using several warped interfaces adds rendering work.
Want to learn Godot VFX and shaders?
We just released our new Godot All About VFX Bundle, it covers shaders, particles, and VFX for 2D, UI, and 3D games with step-by-step examples. Over 600 pages of content. ✨
Jettelly wishes you success in your professional career! Did you find an error? No worries! Write to us at [email protected], and we'll fix it!

Subscribe to our newsletter to stay up to date with our latest offers

© 2026 Jettelly Inc. All rights reserved. Made with ❤️ in Toronto, Canada