Skip to content

Guide: CGI Coordinate Systems

DSri Seah edited this page Nov 20, 2024 · 2 revisions

SNA Coordinate System Reference

Viewport - This class manages a ThreeJS WebGLRenderer with the cameras that render the game world. There are several coordinate systems to manage.

PIXEL-BASED COORDINATES - The Viewport uses pixel-based coordinates for...

  • GLRenderer Coordinate Systems - This framebuffer is the viewport into the game world. The buffer origin starts at 0,0 at the bottom left with positive x,y pixel coordinates. However, calculations are performed in "normalized device space" with values between -1 and 1, and the origin in the center of the screen. After calculations, the display results are mapped to the framebuffer's coordinate system.

  • DOM Element Coordinates - The HTML container that holds the GLRenderer <canvas> uses CSS box model coordinates. The origin is at the top left, and x,y are positive. Because the container might be a different size in pixels than the GLRenderer, the GLRenderer may be sized to fit the container by either scaling, resizing, or cropping to framebuffer.

  • World Coordinates - In the 3D space of WebGL, the coordinate system uses the right-hand rule (thumb is X, index is Y, middle is Z). Positive Z points towards the viewer. Positve x is to the right, positive y is up. Note that this does not match other renderers like DirectX, which uses a left-hand rule (positive Z is away from the viewer).

  • Angular Coordinates - For simple rotation, Euler angles are used to rotate using the right-handed coordinate system where positive rotation is counter-clockwise. Angles are measured in radians. For more complex rotations, quaternions are used.

  • Angular conventions - Looking at the world from above, positive rotation is counter-clockwise around the z-axis, where an angle of 0 degrees points to the positive x-axis (right) and 90 degrees points along the positive y-axis (up). This is a right-handed coordinate system, used for mapping a 2D X-Y plane and a Z-depth axis (negative Z is away from the viewer).

CAMERAS - Viewport uses two kinds of cameras: Orthographic and Perspective.

  • The OrthographicCamera defines left, right, top, bottom, near, and farclipping planes. The near and far planes define the range of distances. It has no perspective, but uses lookAt() and up vectors to orient the camera from a position.

  • The PerspectiveCamera defines a fov, aspectratio, near, and far clipping planes. It also has a position, lookAt(), and up vector. The field of view is the angle in degrees that determines how much of the scene is visible.

SPRITE-BASED COORDINATES - In ThreeJS, sprites are Point objects with no dimension. Their position is in world coordinates and set through the position property. For the classic 2D image sprite, the material is a SpriteMaterial with a texture map. The Sprite is a simplified version of a Mesh with a PlaneGeometry, handling the details of rotation, scaling, and uv mapping for spritesheets.

  • scale - The scale property of the sprite is a Vector3 that scales the sprite in all dimensions. The default scale is 1,1,1, which draws the sprite in a 1 x 1 square unit in world coordinates. To draw the sprite in another aspect ratio, the scale can be set to the desired width and height.

  • rotation - Since sprites are point objects, sprite.material.map.rotation is used to rotate the sprite around its center. The center is set through sprite.materia.map.center.

  • spritesheets - for textures that are spritesheets, texture.repeat is set to the size of a cell in the spritesheet, and the texture.offset is set to the cell position in the spritesheet (origin at top-left).

  • position - as mentioned above, sprite.position is available to set in world coordinates. The position is the center of the sprite, which is aligned with material.map.center.

WORLD SCALE - Our world uses a convention where a world unit corresponds to 10cm in real space. Additionally, a world "pixel" is 1/10th of a world unit. So, to render a 10x10 world unit square with 1:1 pixel mapping, the square would be 100x100 pixels (assuming an orthgraphic camera). This is useful for designing pixel art and textures for the game world.