Search Projects

Showing posts with label poke ball. Show all posts
Showing posts with label poke ball. Show all posts

Wednesday, June 17, 2026

OpenGL Python Program for Rendering Poké Ball

 


1. Render a Normal 3D Poké Ball

The Poké Ball itself is usually just a sphere mesh with:

  • A red upper hemisphere
  • A white lower hemisphere
  • A black center band
  • A circular button on the front

The geometry can be:

  • A UV sphere
  • An icosphere
  • A procedurally generated sphere

The fragment shader might assign colors based on position:

if (worldPos.y > 0.0)
    color = vec3(1.0, 0.0, 0.0); // red
else
    color = vec3(1.0);            // white

The black band can be created using latitude calculations or a separate mesh.


2. Use Low-Resolution Rendering

A common pixel-art trick is rendering to a small framebuffer first.

For example:

320 x 180

instead of:

1920 x 1080

The scene is rendered into an off-screen texture (FBO).

Then that texture is stretched to the screen using:

GL_NEAREST

filtering.

This creates large visible pixels.

glTexParameteri(
    GL_TEXTURE_2D,
    GL_TEXTURE_MIN_FILTER,
    GL_NEAREST
);


3. Quantized Lighting

Instead of smooth lighting:

float diffuse = max(dot(N, L), 0.0);

you reduce it to a few discrete levels.

Example:

float diffuse = max(dot(N, L), 0.0);

diffuse = floor(diffuse * 4.0) / 4.0;

This produces only 4 brightness levels.

Result:

  • Bright region
  • Mid-bright
  • Mid-dark
  • Dark

Very similar to retro sprite shading.


4. Palette Reduction

Pixel-art renderers often limit colors intentionally.

Example:

vec3 color = baseColor * diffuse;

color = floor(color * 8.0) / 8.0;

This converts continuous colors into a small palette.

Instead of thousands of shades, you might have:

  • 8 reds
  • 8 grays
  • 8 blacks

giving a classic pixel-art appearance.


5. Pixel Grid Snapping

Many projects quantize screen coordinates.

Example:

vec2 pixelSize = vec2(4.0);

vec2 snappedUV =
    floor(gl_FragCoord.xy / pixelSize)
    * pixelSize;

All fragments within a block sample the same value.

This creates chunky pixels even when rendering at higher resolutions.


6. Dithering

To fake additional colors, retro-style renderers often use dithering.

Common patterns:

Bayer Matrix

0  8  2 10
12 4 14 6
3 11 1  9
15 7 13 5

Shader:

if(diffuse < threshold)
    color *= 0.8;

This creates the checkerboard patterns often seen in pixel art.


7. Outline Rendering

Many stylized renders add outlines.

Two common methods:

Inverted Hull

Render the model twice:

  1. Normal render
  2. Render enlarged backfaces in black

position += normal * 0.02;

Produces a cartoon outline.

Edge Detection

Run a post-process pass using:

  • Depth buffer
  • Normal buffer

Detect sharp changes and draw black edges.


8. Shadow Quantization

If the image has sharp, stylized shadows, they may use toon shading:

if(diffuse > 0.7)
    shade = 1.0;
else if(diffuse > 0.4)
    shade = 0.7;
else
    shade = 0.3;

Instead of smooth gradients, you get discrete shadow bands.


9. Specular Highlights

The shiny white highlight on the Poké Ball can be stylized:

float spec =
    pow(max(dot(R, V), 0.0), 32.0);

spec = step(0.5, spec);

Using step() creates a hard-edged highlight instead of a realistic glossy reflection.


10. Typical Rendering Pipeline

A common pipeline would be:

Sphere Mesh
     
Vertex Shader
     
Toon Lighting
     
Palette Reduction
     
Render to Low-Res FBO
     
Nearest Neighbor Upscaling
     
Dithering Pass
     
Display

The characteristic "3D object that looks like pixel art" usually comes primarily from:

  1. Rendering to a very low-resolution framebuffer
  2. Nearest-neighbor upscaling
  3. Quantized (toon) lighting
  4. Palette reduction
  5. Optional dithering and outlines

Those five techniques together can make a smooth 3D OpenGL model look remarkably similar to hand-drawn pixel art while still being fully real-time and rotatable.

It can be generate via below mentioned stacks - 

  • PyOpenGL + GLFW (closest to modern OpenGL tutorials)
  • PyOpenGL + Pygame
  • moderngl (cleaner Python API, often easier)
  • Pyglet
  • Ursina (higher-level engine)

  • Python Project

    Google Doc File • 7 KB

    Download