How to render 3D to 2D pixel art in Godot

What is 3D to 2D Rendering?

3D to 2D rendering is the process of automatically converting three-dimensional models into two-dimensional images using a computer. It’s a fundamental technique in computer graphics that allows artists and developers to leverage the flexibility of 3D modeling for creating traditional 2D art.

Why Use 3D to 2D Rendering?

The primary advantage of this method lies in its efficiency and scalability, especially for character animation. Consider a game like Dead Cells, which features detailed, fluid pixel art animations.

Creating these animations directly by hand is an incredibly labor-intensive process. A single second of motion might require a dozen or more individual frames, meaning hundreds or even thousands of unique images are needed to animate just one character. This workload increases exponentially with more characters, weapons, or actions.

A more efficient approach is to build a single 3D model of the character. Once the model is complete, animators can apply motions and animations to it in a 3D environment. The software then automatically renders these animated 3D sequences into 2D images or sprite sheets. This technique, which Dead Cells uses, significantly reduces the manual workload, allowing for a much higher volume of high-quality, fluid animations with a fraction of the effort required for traditional frame-by-frame drawing. It offers the best of both worlds: the visual style of 2D art with the production efficiency of 3D technology.

How to Implement 3D to 2D Rendering in Godot

  • Arrange a 3d scene and model as you like

    • First, put your 3d model in a separate scene and setup everything you need to display the model (like reflection, animator, light and so on).

      P.S.: If you want your item looks better after rendering to 2d, you can choose the “Diffusion Mode” and “Specular Mode” as “Toon”, which is the godot inherit shading method compatiable with 3D to 2D rendering

  • Add SubViewPort Node in 3D Scene

    • Create a SubViewPoint Node and Put all the 3D-related nodes under the SubViewPoint node.

      Then create a Sprite2D node under root, choose “NewViewPoint Texture” in texture feature in this node and select the SubViewPoint we just created.

      Now we can see the view of camera in 3D is projected on the 2D scene like the following:

      P.S.: Remember to select “Transparent BG” in SubViewPoint Node if you don’t want to see the background in 3D view.

  • Create a shader for 2D sprite image

    • In the material of Sprite2D node, we choose to create new metariel and new shader for this image.

      After creation, we can see the shader editor and initial shader code at the bottom of screen like this:

      Now we start to code the shader, first we create 3 uniform global values:

      1
      2
      3
      uniform vec2 pixel_count = vec2(64);  // Number of pixel after rendering the image
      uniform float outline_width = 1.0;
      uniform vec4 outline_color : source_color = vec4(0,0,0,1);

      Then we add the following two functions:

      1
      2
      3
      4
      5
      6
      vec2 pixelate(vec2 uv, vec2 count) {  // return uv
      uv *= count;
      uv = floor(uv);
      uv /= count;
      return uv;
      }

      This function is intended to pixelate the image

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      vec4 add_outline(vec2 uv, vec4 color, sampler2D obj_texture, vec2 obj_pixel_size) {  // return color
      vec4 outline = texture(obj_texture, uv + vec2(0, obj_pixel_size.y) * outline_width) +
      texture(obj_texture, uv + vec2(0, -obj_pixel_size.y) * outline_width) +
      texture(obj_texture, uv + vec2(obj_pixel_size.x, 0) * outline_width) +
      texture(obj_texture, uv + vec2(-obj_pixel_size.x, 0) * outline_width) +
      texture(obj_texture, uv + vec2(obj_pixel_size.x, obj_pixel_size.y) * outline_width * (sqrt(2) / 2.0)) +
      texture(obj_texture, uv + vec2(obj_pixel_size.x, -obj_pixel_size.y) * outline_width * (sqrt(2) / 2.0)) +
      texture(obj_texture, uv + vec2(-obj_pixel_size.x, obj_pixel_size.y) * outline_width * (sqrt(2) / 2.0)) +
      texture(obj_texture, uv + vec2(-obj_pixel_size.x, -obj_pixel_size.y) * outline_width * (sqrt(2) / 2.0));
      outline.rgb = color.rgb;
      outline.a = min(outline.a, 1);
      vec4 origin = texture(obj_texture, uv);
      return mix(outline, origin, origin.a);
      }

      This function is intended to add a border for the object.

      Finally, we adding the following line to the fragment function:

      1
      2
      3
      4
      void fragment() {
      // Called for every pixel the material is visible on.
      COLOR = add_outline(pixelate(UV, pixel_count), outline_color, TEXTURE, TEXTURE_PIXEL_SIZE);
      }

      Now save the code and we can see our picture in 2D scene changed to this:

    • Go to the main scene of your project and link the object into the main scene, add a simple background for it, now we sucessfully convert our 3D model to 2D pixel image:

      If we add an animation to the 3D object, the 2D picture will move as well:

Conclusion

Here are all the steps for basic 3D model to 2D pixel image rendering. You can explore by yourself for more features like adding HDR, setting the fps of pixel animation, create better outline to represent shadow and so on.


How to render 3D to 2D pixel art in Godot
https://huaiyuan-jing.github.io/posts/a9781501/
Beitragsautor
HackThink
Veröffentlicht am
September 5, 2025
Urheberrechtshinweis