022. Modern Graphics Cards, Part III

I originally intended this section mainly to explain the difference between a fixed-function pipeline and a programmable pipeline.

There are many experts on Zhihu, so I will borrow the diagrams from this answer:
What advantages does a programmable rendering pipeline have over a fixed-function pipeline? What are its applications? – Wang Tianqi’s answer – Zhihu
https://www.zhihu.com/question/28024422/answer/39097192

The task of the rendering pipeline is what the diagram below illustrates: converting a 3D scene into a 2D image.

Several steps are required to accomplish this:

Vertex Shader

1. Coordinate Transformation

A scene generally contains multiple 3D objects. When such a 3D object is designed, its position in the scene cannot be taken into account, because that position may change over time. Therefore, when a 3D object is designed, its coordinate system generally uses the object’s center as the origin.

Nor is it possible to account for screen size when designing a 3D object, especially since the object may also be scaled up or down. Consequently, the object’s coordinate range is usually not an integer range such as 0–1080, but normalized floating-point values such as 0.0–1.0.

To display an object in a scene, one must first determine where in the scene it should be placed. Each vertex is then transformed by a transformation matrix into scene coordinates, also known as world-space coordinates.

Objects in the scene are viewed by a camera. To make camera rendering convenient, the coordinates of every object in the scene must also be converted into a coordinate system whose origin is the camera. The relationship between camera coordinates and world coordinates is not fixed either, because in a game the player can control the camera to view different parts of the world.

2. Lighting

A model consists of a mesh, and a mesh is defined by a set of vertices together with the connections between them. A vertex in a model contains not only coordinate information but also color information. The color may be an RGBA value, or it may be specified indirectly by texture coordinates that identify a location in a texture. Colors across a mesh surface are obtained by interpolating the colors of its vertices. Thus, to render a colored object, every vertex in the object’s model must first be processed. In addition to a fixed color, each vertex also has normal information. The normal specifies the direction in which the vertex reflects light when illuminated. This is also very important: if the reflected light does not travel toward the camera, the point may appear very dark—or even black—to the camera.

In addition to direct illumination from a light source, lighting includes scattering, self-emission, and other cases. For details, see:
https://blog.csdn.net/xuexiaokkk/article/details/49513463

Both operations above must be performed on every vertex, and both follow certain patterns. In hardware, they are implemented by something called a vertex shader.

In a fixed-function pipeline GPU, the operations that the vertex shader can perform are limited and can be selected through configuration parameters.
In a programmable pipeline GPU, you can write a program that specifies what operations should be performed on every vertex, providing much more flexible control.

The inputs to a vertex shader are the attributes of a point, such as its coordinates, texture coordinates, color, and normal. Its outputs include the point’s transformed camera-space coordinates, color, and texture coordinates.

A vertex shader’s inputs also include certain controls—the Uniforms and Samplers shown in the diagram. They are supplied to the shader program through the OpenGL or Direct3D API and have the same values for every vertex.

Fragment Shader (fragment shader, also called pixel shader)

Each vertex now has a color, or texture coordinates, as well as a z-coordinate. The next step is to assign a color and z-coordinate to every point on a surface.

First, according to the display resolution, the surface must be discretized into a finite number of points. The color of each point is obtained by interpolating the vertices of the surface on which it lies. If a texture is used, each point’s texture coordinates are obtained by interpolating the vertices’ texture coordinates. These points are called fragments. Each ultimately corresponds to a pixel displayed on the screen.

In a fixed-function pipeline GPU, options such as the interpolation method can be configured.
In a programmable pipeline GPU, the fragment shader can accept a small program that controls what this stage does.

The inputs to a fragment shader include the 2D coordinates and z-coordinate of a rasterized pixel, along with the corresponding texture coordinates.
Its outputs include the pixel’s color and z-coordinate.

In addition to running the shader program, the subsequent work shown below must also be done:

Unified Shader Hardware

Whether it is a vertex shader or a fragment shader, its operations consist of floating-point calculations. A large portion of these operations is common to both, so it is reasonable to combine the two pieces of hardware into one.

This unified shader hardware is called a GPU core. Clearly, this core can execute a program and perform floating-point operations. Modern GPUs contain thousands of such cores. By comparison, CPUs with more than a hundred cores remain rare.

For workloads that apply the same kinds of operations to large amounts of data, a GPU is much faster than a CPU.

The next section will compare OpenGL and OpenCL to examine how a graphics card becomes a computing platform.

Last modified: 2026年7月13日

Author

Comments

Write a Reply or Comment

Your email address will not be published.