articles/graphics-pipeline (#1)
All checks were successful
continuous-integration/drone/push Build is passing

Reviewed-on: #1
Co-authored-by: light7734 <light7734@tuta.io>
Co-committed-by: light7734 <light7734@tuta.io>
This commit is contained in:
light7734 2025-04-28 15:00:11 +00:00 committed by light7734
parent 903d7358b0
commit 0cf1ecbb76
9 changed files with 127 additions and 3608 deletions

View file

@ -7,6 +7,7 @@ steps:
privileged: true privileged: true
image: node:latest image: node:latest
commands: commands:
- rm -rf ./node_modules
- npm install - npm install
- npm run build - npm run build
- cp -r ./build/* /dazzle/ - cp -r ./build/* /dazzle/

View file

@ -16,34 +16,35 @@
"test": "npm run test:unit -- --run" "test": "npm run test:unit -- --run"
}, },
"devDependencies": { "devDependencies": {
"@eslint/compat": "^1.2.5", "@eslint/compat": "^1.2.8",
"@eslint/js": "^9.18.0", "@eslint/js": "^9.25.1",
"@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/adapter-auto": "^6.0.0",
"@sveltejs/adapter-node": "^5.2.12", "@sveltejs/adapter-node": "^5.2.12",
"@sveltejs/adapter-static": "^3.0.8", "@sveltejs/adapter-static": "^3.0.8",
"@sveltejs/kit": "^2.16.0", "@sveltejs/kit": "^2.20.7",
"@sveltejs/vite-plugin-svelte": "^5.0.0", "@sveltejs/vite-plugin-svelte": "^5.0.3",
"@tailwindcss/forms": "^0.5.9", "@tailwindcss/forms": "^0.5.10",
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.16",
"@tailwindcss/vite": "^4.0.0", "@tailwindcss/vite": "^4.1.4",
"@testing-library/jest-dom": "^6.6.3", "@testing-library/jest-dom": "^6.6.3",
"@testing-library/svelte": "^5.2.4", "@testing-library/svelte": "^5.2.7",
"eslint": "^9.18.0", "eslint": "^9.25.1",
"eslint-config-prettier": "^10.0.1", "eslint-config-prettier": "^10.1.2",
"eslint-plugin-svelte": "^3.0.0", "eslint-plugin-prettier": "^5.2.6",
"eslint-plugin-svelte": "^3.5.1",
"globals": "^16.0.0", "globals": "^16.0.0",
"jsdom": "^26.0.0", "jsdom": "^26.1.0",
"mdsvex": "^0.12.3", "mdsvex": "^0.11.2",
"prettier": "^3.4.2", "prettier": "^3.5.3",
"prettier-plugin-svelte": "^3.3.3", "prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.11", "prettier-plugin-tailwindcss": "^0.6.11",
"svelte": "^5.0.0", "svelte": "^5.28.2",
"svelte-check": "^4.0.0", "svelte-check": "^4.1.6",
"tailwindcss": "^4.0.0", "tailwindcss": "^4.1.4",
"typescript": "^5.0.0", "typescript": "^5.8.3",
"typescript-eslint": "^8.20.0", "typescript-eslint": "^8.31.0",
"vite": "^6.2.5", "vite": "^6.3.3",
"vitest": "^3.0.0" "vitest": "^3.1.2"
}, },
"pnpm": { "pnpm": {
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [

3562
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,3 @@
@import 'tailwindcss'; @tailwind base;
@plugin '@tailwindcss/forms'; @tailwind components;
@plugin '@tailwindcss/typography'; @tailwind utilities;

View file

@ -3,6 +3,10 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" /> <link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"
rel="stylesheet"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head% %sveltekit.head%
</head> </head>

View file

@ -0,0 +1,14 @@
<script lang="ts">
import './article.css';
let { children } = $props();
</script>
<div class="body">
<div class="article_padding"></div>
<div class="article_body">
{@render children()}
</div>
<div class="article_padding"></div>
</div>

View file

@ -0,0 +1,47 @@
@import "tailwindcss";
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
* {
color: #ebdbb2;
font-family: "Inter", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
}
br {
margin-bottom: 1em;
}
h1 {
font-size: 2em;
margin-bottom: .3em;
}
h2 {
font-size: 1.7em;
margin-bottom: .3em;
margin-top: .6em;
}
.body {
background-color: #1d2021;
display: flex;
}
.article_body {
flex: 3;
margin-left: 10em;
margin-right: 10em;
padding: 1em;
background-color: #282828;
text-align: justify;
max-width: 80ch;
border-left: 1px solid #7c6f64;
border-right: 1px solid #7c6f64;
}
.article_padding {
flex: 1;
}

View file

@ -1,49 +1,56 @@
# The Graphics Pipeline # The Graphics Pipeline
Ever wondered how games put all that gore on your display? Well you're about to find out! Ever wondered how games put all that gore on your display? Well you're about to find out!
<br/>
At the heart of rendering, is the "Graphics Pipeline". And like any pipeline, it's comprised At the heart of rendering, is the "Graphics Pipeline". And like any pipeline, it's comprised
of several "stages", each of which can be a pipeline in itself or even parallelized. of several "stages", each of which can be a pipeline in itself or even parallelized.
Each stage takes some input data (and configuration), to generate some output for the next stage. Each stage takes some input data (and configuration), to generate some output for the next stage.
<br/>
We can coarsely divide the entire pipeline into 4 stages: We can coarsely divide the entire pipeline into 4 stages:
Application -> [Geometry Processing] -> Rasterization -> Pixel Processing Application -> [Geometry Processing] -> Rasterization -> Pixel Processing
The pipeline will then serve a "rendered image" to your pretty eyes using your display. The pipeline will then serve a "rendered image" to your pretty eyes using your display.
<br/>
But to avoid drowning you in overviews, let's jump right into the details of the "Geometry Processing" But to avoid drowning you in overviews, let's jump right into the details of the "Geometry Processing"
stage and have a recap afterwards to demystify our 4-stage division! stage and have a recap afterwards to demystify our 4-stage division!
# Vertices (points in space) ## Vertices (points in space)
In order to render a murder scene, we need to have a way of representing the deceased in computer memory. In order to render a murder scene, we need to have a way of representing the deceased in computer memory.
We only care about the "surface" since we won't be seeing the insides anyways--We don\'t want to either. We only care about the "surface" since we won't be seeing the insides anyways--We don\'t want to either.
At this stage, we only care about the "shape" or the "geometry" of the "surface", At this stage, we only care about the "shape" or the "geometry" of the "surface",
texturing, lighting and all the sweet gory details comes at a much later stage once all the "geometry" has been processed. texturing, lighting and all the sweet gory details comes at a much later stage once all the "geometry" has been processed.
<br/>
There are several ways to "represent 3d objects" for a computer to understand. There are several ways to "represent 3d objects" for a computer to understand.
For instance, _NURB_(Non-uniform rational B-spline) surfaces are great for representing "curves" For instance, _NURB_(Non-uniform rational B-spline) surfaces are great for representing "curves"
and it's all about the "high-precision" needed to do _CAD_(computer assisted design). and it's all about the "high-precision" needed to do _CAD_(computer assisted design).
We could also do "ray-tracing" using fancy equations for rendering photo-realistic images. We could also do "ray-tracing" using fancy equations for rendering photo-realistic images.
<br/>
These are all great--ignoring the fact that they would take "an eternity" to process. These are all great--ignoring the fact that they would take "an eternity" to process.
But what we need is a hardware-friendly approach that can do this for an entire scene with But what we need is a hardware-friendly approach that can do this for an entire scene with
hundereds of thousands of objects for at least 60 times undr a second. What we need is "polygonal modeling". hundereds of thousands of objects for at least 60 times undr a second. What we need is "polygonal modeling".
<br/>
"Polygonal modeling" allows us to do "real-time rendering". The idea is that we only need an "Polygonal modeling" allows us to do "real-time rendering". The idea is that we only need an
"approximation" of a surface to render it "realisticly-enough" for us to have some fun killing time! "approximation" of a surface to render it "realisticly-enough" for us to have some fun killing time!
We can achieve this approximation using a collection of "triangles", "lines" and "dots" (primitives), We can achieve this approximation using a collection of "triangles", "lines" and "dots" (primitives),
which themselves are composed of a series of "vertices" (points in space). which themselves are composed of a series of "vertices" (points in space).
<br/>
A "vertex" is simply a point in space. A "vertex" is simply a point in space.
Once we get enough of these "points", we can conncet them to form "primitives" such as "triangles", "lines" and "dots". Once we get enough of these "points", we can conncet them to form "primitives" such as "triangles", "lines" and "dots".
And once we have enough "primitives" together, they form a "model" or a "mesh" (that we need for our corpse). And once we have enough "primitives" together, they form a "model" or a "mesh" (that we need for our corpse).
With some interesting models, we can compose a "scene". With some interesting models, we can compose a "scene".
<br/>
But let's not get ahead of ourselves. The primary type of "primitive" we care about during "polygonal modeling" But let's not get ahead of ourselves. The primary type of "primitive" we care about during "polygonal modeling"
is a "triangle". But why not squares or polygons with variable number of edges? is a "triangle". But why not squares or polygons with variable number of edges?
# Why Triangles? ## Why Triangles?
"Always Planar": "Always Planar":
Triangles can never be __non-planar__(reside in more than 1 plane)! In Euclidean geometry, any Triangles can never be __non-planar__(reside in more than 1 plane)! In Euclidean geometry, any
3
"Normal surface:" "Normal surface:"
@ -52,38 +59,41 @@ Triangles can never be __non-planar__(reside in more than 1 plane)! In Euclidean
"Predictable Winding Order:" "Predictable Winding Order:"
# Primitive Topologies ## Primitive Topologies
# Indices ## Indices
# Input Assembler ## Input Assembler
# Coordinate System -- Local Space ## Coordinate System -- Local Space
# Coordinate System -- World Space ## Coordinate System -- World Space
# Coordinate system -- View Space ## Coordinate system -- View Space
# Coordinate system -- Clip Space ## Coordinate system -- Clip Space
# Coordinate system -- Screen Space ## Coordinate system -- Screen Space
# Vertex Shader ## Vertex Shader
# Tessellation & Geometry Shaders ## Tessellation & Geometry Shaders
# Rasterizer ## Rasterizer
# Pixel Shader ## Pixel Shader
# Output Merger ## Output Merger
# The Future ## The Future
# Conclusion ## Conclusion
# Sources ## Sources
[Tomas Akenine Moller - Real-Time Rendering 4th Edition](https://www.realtimerendering.com/intro.html) [Tomas Akenine Moller - Real-Time Rendering 4th Edition](https://www.realtimerendering.com/intro.html)
<br/>
[LearnOpenGL - Hello Triangle](https://learnopengl.com/Getting-started/Hello-Triangle) [LearnOpenGL - Hello Triangle](https://learnopengl.com/Getting-started/Hello-Triangle)
[LearnOpenGL - Face Culling](https://learnopengl.com/Advanced-OpenGL/Face-culling) [LearnOpenGL - Face Culling](https://learnopengl.com/Advanced-OpenGL/Face-culling)
[Wikipedia - Polygonal Modeling](https://en.wikipedia.org/wiki/Polygonal_modeling) [Wikipedia - Polygonal Modeling](https://en.wikipedia.org/wiki/Polygonal_modeling)

View file

@ -6,7 +6,12 @@ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = { const config = {
// Consult https://svelte.dev/docs/kit/integrations // Consult https://svelte.dev/docs/kit/integrations
// for more information about preprocessors // for more information about preprocessors
preprocess: [vitePreprocess(), mdsvex()], preprocess: [
vitePreprocess(),
mdsvex({
extensions: ['.md', '.svx'],
})
],
kit: { kit: {
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
@ -15,8 +20,7 @@ const config = {
adapter: adapter() adapter: adapter()
}, },
extensions: ['.svelte', '.svx'] extensions: ['.svelte', '.svx', '.md']
}; };
export default config; export default config;