Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3213820
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T14:59:19+00:00 2026-05-17T14:59:19+00:00

I am rendering 3D objects on a 2D canvas by doing all necessary calculations

  • 0

I am rendering 3D objects on a 2D canvas by doing all necessary calculations in software. I am not using graphics acceleration.

Initially all the objects were cubes of same size, so I could sort them based on their distance in Z from camera and that would order them correctly. But now I am trying to draw cubes of varying dimensions. That makes my simple z-ordering algorithm fail in perspective projection.

I looked into computer graphics books and found the techniques used, they eventually recommend pixel based comparision of two polygons to determine which one is ahead of other. Probably that’s what they do in graphics card. But doing so in software seems overly difficult and I guess it will be slow for practical use even if I can do it.

Is there a simple trick to do this in software? Any examples from early days of 3D graphics, when graphics cards were not available?

Although this is generic 3D graphics question, if it helps, I am doing this on top of HTML5 Canvas 2D API.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T14:59:19+00:00Added an answer on May 17, 2026 at 2:59 pm

    As @ybungalobill has already mentioned, z-buffer is the easiest algorithm to implement. When you are filling the triangles/polygons that make up your cubes, interpolate the Z coordinate between them and store it per-pixel. If you later fill another polygon that renders on the same X, Y coordinate, check if its Z is less than the Z already stored in the buffer. Do not forget to clear the Z buffer to infinity before repainting. Pseudocode:

    foreach (scanline in polygon)  {
      int length = scanline.right.x - scanline.left.x;
      foreach (pixel in scanline)  {
        float t = (float)pixel.x / length;
        float z = (1 - t) * scanline.left.z + t * scanline.right.z;  // Interpolate the Z coordinate
        if (z < zbuffer[scanline.y][pixel.x])
          drawPixel(pixel.x, scanline.y, polygon.color);  // The pixel is closer, paint it
      }
    }
    

    A revised approach of Z buffer that performs better on CPU by not drawing pixels that would be overwritten is called segment buffer: http://www.gamedev.net/reference/articles/article668.asp

    Another approach is the Warnock’s algorithm. It uses recursion which makes it hard to use on GPUs but CPU should do fine if you use your own stack to avoid stack overflow. The idea lies in dividing the scene into 4 parts and checking if there’s only one polygon covering the whole part. If not split it again until the condition is met (it will be met at the pixel level in worst case). Pseudocode:

    void warnock(Rectangle rect)
    {
      float minZ = infinity;
      foreach (polygon in polygons)  {
        if (rect is inside polygon)  {
          float z = interpolateZ(polygon, rect.x + rect.width / 2, rect.y + rect.height / 2);  // Get Z coordinate at the centre of the rectangle
          if (z < minZ)  {  // If there are more polygons in this rectangle, make sure the topmost one gets drawn last
            fillRect(polygon.color);
            minZ = z;
          }
        } else {
          // Divide to 4 subrectangles
          warnock(Rectangle(rect.x, rect.y, rect.width / 2, rect.height / 2));  // Top left
          warnock(Rectangle(rect.x, rect.y + rect.height / 2, rect.width / 2, rect.height / 2));  // Bottom left
          warnock(Rectangle(rect.x + rect.width / 2, rect.y, rect.width / 2, rect.height / 2));  // Bottom right
          warnock(Rectangle(rect.x + rect.width / 2, rect.y + rect.height / 2, rect.width / 2, rect.height / 2));  // Top right
        }
      }
    }
    

    The painter’s algorithm is what you have done with your cubes, the only difference is that it sorts the polygons instead of whole objects. Even then it is difficult to solve various polygon intersections and I personally wouldn’t use it for non-trivial scenes.

    Another algorithm you might use is the backface culling algorithm. This works only for convex objects that do not overlap though. The algorithm calculates the normal of each polygon and if it points in the direction from the camera, it is removed.

    Raycasting is another way to determine the visibility per-pixel. It is, however, quite CPU intensive. The basic idea is to check for each pixel of the screen, what polygon intersects it (what polygon gets hit by the ray casted from the current pixel). The origin of the rays is eye position. Pseudocode:

    foreach (pixel in screen)  {
      float minZ = infinity;  // Can be zfar from the perspective projection
      Color pixelColor = backgroundColor;
      foreach (polygon in projectedPolygons)  {
        if (polygon contains Point(pixel.x, pixel.y))  {
          float z = interpolateZ(polygon, pixel.x, pixel.y);  // Get the current Z for (x, y) and this polygon using bilinear interpolation
          if (z < minZ)  {
            minZ = z;
            pixelColor = polygon.color;
          }
        }
      }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm not happy with the rendering of HTML by Swing's JEditorPane. In particular bullets
I've been trying to make off screen rendering to work, using Java3D 1.5.2 .
I want to do pixel-true rendering of some images on my Canvas. Right now,
I am drawing a graph on a <canvas> that requires expensive calculations. I would
If I'm rendering a regular view in asp.net mvc the only domain object properties
I am rendering a rails partial and I want to alternate the background color
I'm having major rendering issues in Safari with the web application I'm working on.
I am rendering an OpenGL scene that include some bitmap text. It is my
I am actually rendering an excel file in the browser. I use the Response.Writefile(filePath)
I'm rendering some HTML in a QT QLabel. The HTML looks like this: <pre>foo\tbar</pre>

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.