Skip to content

Instantly share code, notes, and snippets.

@zvodd
Last active September 9, 2024 09:50
Show Gist options
  • Save zvodd/87dbf100de2c6d16e845a341846ecfbf to your computer and use it in GitHub Desktop.
Save zvodd/87dbf100de2c6d16e845a341846ecfbf to your computer and use it in GitHub Desktop.
3D Spaces and Matrices in Godot 4 Shaders

Vertex and Fragment Function Spaces

  1. Vertex Function:

    • Input: Model Space (Local Space)
    • Output: Clip Space
  2. Fragment Function:

    • Input: View Space (Camera Space)

Coordinate Spaces

  1. Model Space (Local Space)

    • The coordinate system relative to the object itself.
    • Origin is typically at the object's center or bottom-left corner.
  2. World Space

    • The global coordinate system of the entire scene.
    • All objects are positioned relative to a common origin.
  3. View Space (Camera Space)

    • Coordinates relative to the camera's position and orientation.
    • Camera is at (0,0,0) looking down the negative Z-axis.
  4. Clip Space

    • Coordinates after projection but before perspective division.
    • Ranges from -w to +w in all dimensions.
  5. Normalized Device Coordinates (NDC)

    • After perspective division, ranges from -1 to 1 in all dimensions.
  6. Screen Space

    • 2D coordinates mapped to the actual screen pixels.

Matrix Transformations

flowchart TD
    ModelSpace["Model Space"] -- MODEL_MATRIX --> WorldSpace["World Space"]
    WorldSpace -- INV_MODEL_MATRIX --> ModelSpace
    WorldSpace -- VIEW_MATRIX --> ViewSpace["View Space"]
    ViewSpace -- INV_VIEW_MATRIX --> WorldSpace
    ViewSpace -- PROJECTION_MATRIX --> ClipSpace["Clip Space"]
    ClipSpace -- INV_PROJECTION_MATRIX --> ViewSpace
    ClipSpace -- 1/w (Perspective Division) --> NDCSpace["NDC Space"]
    NDCSpace -- w --> ClipSpace
    NDCSpace -- VIEWPORT_TRANSFORM --> ScreenSpace["Screen Space"]
    ScreenSpace -- INV_VIEWPORT_TRANSFORM --> NDCSpace
    %%VertexShaderInput[/"Vertex Shader Input"/] -.-> ModelSpace
    %%VertexShaderOutput[/"Vertex Shader Output"/] -.-> ClipSpace
    %%FragmentShaderInput[/"Fragment Shader Input"/] -.-> ViewSpace
    classDef modelSpace fill:#FFD700,stroke:#FFA500,stroke-width:2px
    classDef worldSpace fill:#DC143C,stroke:#B22222,stroke-width:2px
    classDef viewSpace fill:#32CD32,stroke:#228B22,stroke-width:2px
    classDef clipSpace fill:#1E90FF,stroke:#1C86EE,stroke-width:2px
    classDef ndcSpace fill:#8A2BE2,stroke:#7A1E81,stroke-width:2px
    classDef screenSpace fill:#FF69B4,stroke:#FF1493,stroke-width:2px
    style ModelSpace fill:#C8E6C9
    style WorldSpace fill:#BBDEFB
    style ViewSpace fill:#FFD600
    style ClipSpace fill:#FFE0B2
    style NDCSpace fill:#E1BEE7
    linkStyle 0 stroke:#2962FF,fill:none
    linkStyle 1 stroke:#00C853,fill:none
    linkStyle 2 stroke:#FFD600,fill:none
    linkStyle 3 stroke:#2962FF,fill:none
    linkStyle 4 stroke:#FF6D00,fill:none
    linkStyle 5 stroke:#FFD600,fill:none
    linkStyle 6 stroke:#AA00FF,fill:none
    linkStyle 7 stroke:#FF6D00,fill:none
    linkStyle 8 stroke:#616161,fill:none
    linkStyle 9 stroke:#AA00FF,fill:none
Loading
Transformation Matrix
Model Space to World Space MODEL_MATRIX
World Space to View Space VIEW_MATRIX
View Space to Clip Space PROJECTION_MATRIX
Model Space to View Space MODELVIEW_MATRIX (MODEL_MATRIX * VIEW_MATRIX)
View Space to World Space INV_VIEW_MATRIX
Model Space to Clip Space PROJECTION_MATRIX * MODELVIEW_MATRIX

Space type in functions

flowchart TD
    A("IN: ModelSpace")
    B("vertex()")
    C("OUT: ClipSpace")
    D("IN: ViewSpace")
    E("fragment()")
    F("OUT: 2D")
    A --> B
    B --> C
    D --> E
    E --> F
Loading

Clip Space vs. View Space vs. NDC

  • View Space:

    • 3D space relative to camera
    • Z-axis represents depth
    • No perspective distortion
  • Clip Space:

    • After projection, before perspective division
    • Coordinates range from -w to +w
    • Perspective distortion applied
  • Normalized Device Coordinates (NDC):

    • After perspective division (clip coordinates divided by w)
    • Coordinates range from -1 to +1 in all dimensions
    • Ready for viewport transformation to screen space
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment