Master the fundamental concepts of modern graphics apis (low level) through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksVertex shaders output attributes (color, UVs, normals) per vertex. The rasterizer interpolates these across the triangle so the fragment shader receives smoothly varying values at each pixel. In GLSL these are varyings; in HLSL they are interpolants.
Straight lines in 3D project to straight lines in 2D, but attribute values are not linear in screen space under perspective. Equal screen-space steps correspond to unequal world-space steps due to foreshortening.
The GPU interpolates A/w and 1/w, then divides:
cLoading…
For example, three vertices with colors red, green, blue and w values 1, 2, 1 produce different results at screen position (5,3) depending on whether you interpolate linearly or with perspective correction. Texture coordinates show swimming artifacts without correction; normals produce wrong lighting on angled surfaces.
noperspective qualifier: rare GLSL escape hatch for screen-linear interpolationYou will simulate color interpolation at a fragment position, computing both naive linear and perspective-correct results. This task asks you to print barycentric coordinates, both color values, and explain the difference. Getting this wrong is invisible on flat polygons but immediately visible as texture warping on steep angles.
The rasterizer works in screen space, but attributes like texture coordinates vary linearly in eye space. Interpolating them with plain screen-space barycentrics (affine interpolation) produces the warped textures of the original PlayStation. GPUs instead do perspective-correct interpolation: they interpolate a/w and 1/w linearly across the screen, then divide per fragment. Compute both for fragments of a triangle and report the error.
# starts a comment.
cLoading…
area = (x1-x0)(y2-y0) - (y1-y0)(x2-x0). Then:
λ0 = ((x1-px)(y2-py) - (y1-py)(x2-px)) / area;λ1 = ((x2-px)(y0-py) - (y2-py)(x0-px)) / area;λ2 = 1 - λ0 - λ1. outside the triangle, but it is still evaluated, as extrapolation.qᵢ = λᵢ / wᵢ and 1/w = Σqᵢ. The weights are qᵢ / (1/w), and the corrected attribute is Σ qᵢaᵢ / (1/w).Σ λᵢaᵢ. The error is affine - correct.cLoading…
Numbers are printed with %.4f, except that a value with |x| < 0.00005 prints as 0.0000.
Errors:
attrs: N (1-4)vertex: I (0-2) X Y W ATTRS...vertex I: w must be > 0 (the vertex was clipped)vertex I: expected N attribute(s)sample: X Y, sample: define vertices 0, 1 and 2 first, sample: degenerate triangleunknown command XA rejected vertex keeps its previous value.
Input:
cLoading…
Output:
cLoading…
1/w and a/w, never w or a. Only quantities divided by w are linear in screen space.Hidden tests cover a strongly foreshortened edge, extrapolation outside the triangle, equal w values (where affine is exact), a degenerate triangle, and argument errors.