Compare commits
32 commits
main
...
articles/g
Author | SHA1 | Date | |
---|---|---|---|
e40660c113 | |||
e19b3fedd3 | |||
8c4171319b | |||
cb1548c0ef | |||
77d4184ed1 | |||
9da0ac9d5e | |||
96469fa82e | |||
8497bd9ccb | |||
fc471e5244 | |||
0fe46fc866 | |||
1b7185728f | |||
d38341c9bc | |||
42c9fbe971 | |||
6697a24c6d | |||
be1fcf49bc | |||
85e92a397e | |||
708128d7b7 | |||
8dcf3ad973 | |||
2d579757b8 | |||
95ca3ccf1a | |||
4c6b0983dd | |||
edde7d66cc | |||
9689025934 | |||
15547f9926 | |||
dd435734d3 | |||
0bf965e837 | |||
904f90677a | |||
6fa8d06da1 | |||
9a0b503343 | |||
7722f02ecd | |||
7020f69aab | |||
e381f028be |
45
mdsvex.config.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
import math from 'remark-math';
|
||||
import rehype_katex from 'rehype-katex';
|
||||
import katex from 'katex';
|
||||
import visit from 'unist-util-visit';
|
||||
|
||||
const correct_hast_tree = () => (tree) => {
|
||||
visit(tree, 'text', (node) => {
|
||||
if (node.value.trim().startsWith('<')) {
|
||||
node.type = 'raw';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const katex_blocks = () => (tree) => {
|
||||
visit(tree, 'code', (node) => {
|
||||
if (node.lang === 'math') {
|
||||
const str = katex.renderToString(node.value, {
|
||||
displayMode: true,
|
||||
leqno: false,
|
||||
fleqn: false,
|
||||
throwOnError: true,
|
||||
errorColor: '#cc0000',
|
||||
strict: 'warn',
|
||||
output: 'htmlAndMathml',
|
||||
trust: false,
|
||||
macros: { '\\f': '#1f(#2)' }
|
||||
});
|
||||
|
||||
node.type = 'raw';
|
||||
node.value = '{@html `' + str + '`}';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const mdsvex_config = {
|
||||
extensions: ['.md', '.svx'],
|
||||
layout: "./src/routes/articles/Layout.svelte",
|
||||
|
||||
smartypants: {
|
||||
dashes: 'oldschool'
|
||||
},
|
||||
|
||||
remarkPlugins: [math, katex_blocks],
|
||||
rehypePlugins: [correct_hast_tree, rehype_katex]
|
||||
};
|
5668
package-lock.json
generated
Normal file
12
package.json
|
@ -38,6 +38,7 @@
|
|||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-svelte": "^3.3.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"rehype-mermaid": "^3.0.0",
|
||||
"svelte": "^5.28.2",
|
||||
"svelte-check": "^4.1.6",
|
||||
"tailwindcss": "^4.1.4",
|
||||
|
@ -50,5 +51,16 @@
|
|||
"onlyBuiltDependencies": [
|
||||
"esbuild"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@lucide/svelte": "^0.509.0",
|
||||
"katex": "^0.16.22",
|
||||
"lucide": "^0.509.0",
|
||||
"mermaid": "^11.6.0",
|
||||
"playwright": "^1.52.0",
|
||||
"rehype-katex": "^5.0.0",
|
||||
"rehype-katex-svelte": "^1.2.0",
|
||||
"remark-math": "2",
|
||||
"unist-util-visit": "^2.0.3"
|
||||
}
|
||||
}
|
||||
|
|
5249
pnpm-lock.yaml
generated
Normal file
15
src/app.css
|
@ -1,3 +1,12 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
* {
|
||||
color: #ebdbb2;
|
||||
font-family: 'Inter';
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.css"
|
||||
integrity="sha384-MlJdn/WNKDGXveldHDdyRP1R4CTHr3FeuDNfhsLPYrq2t0UBkUdK2jyTnXPEK1NQ"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<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>
|
31
src/routes/articles/Heading.svelte
Normal file
|
@ -0,0 +1,31 @@
|
|||
<script lang="ts">
|
||||
import './article.css';
|
||||
import HorizontalBreak from './HorizontalBreak.svelte';
|
||||
|
||||
export let title;
|
||||
export let date;
|
||||
</script>
|
||||
|
||||
<div class="heading">
|
||||
<h1>{title}</h1>
|
||||
<p>{date}</p>
|
||||
</div>
|
||||
<HorizontalBreak />
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.heading > h1 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.heading > p {
|
||||
float: right;
|
||||
padding-left: auto;
|
||||
padding-right: auto;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
</style>
|
12
src/routes/articles/HorizontalBreak.svelte
Normal file
|
@ -0,0 +1,12 @@
|
|||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<div class="horizontal_break"></div>
|
||||
|
||||
<style>
|
||||
.horizontal_break {
|
||||
margin-top: 1em;
|
||||
background-color: #928374;
|
||||
height: 1px;
|
||||
}
|
||||
</style>
|
21
src/routes/articles/Image.svelte
Normal file
|
@ -0,0 +1,21 @@
|
|||
<script lang="ts">
|
||||
export let paths: string[] = [];
|
||||
export let caption: string = '';
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
{#each paths as path (path)}
|
||||
<img src={path} alt="" />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
width: fit-content;
|
||||
margin-right: auto;
|
||||
padding: 1em;
|
||||
/* Removed flex properties from here */
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
</style>
|
46
src/routes/articles/Layout.svelte
Normal file
|
@ -0,0 +1,46 @@
|
|||
<script lang="ts">
|
||||
import './article.css';
|
||||
import Heading from './Heading.svelte';
|
||||
|
||||
export let title;
|
||||
export let date;
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="padding"></div>
|
||||
|
||||
<div class="body">
|
||||
<Heading {title} {date} />
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<div class="padding"></div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
|
||||
|
||||
.container {
|
||||
background-color: #1d2021;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.body {
|
||||
flex: 3;
|
||||
padding: 1em;
|
||||
background-color: #282828;
|
||||
|
||||
min-width: 80ch;
|
||||
max-width: 80ch;
|
||||
text-wrap-mode: wrap;
|
||||
text-wrap-style: pretty;
|
||||
text-align: justify;
|
||||
|
||||
border-left: 1px solid #92837420;
|
||||
border-right: 1px solid #92837420;
|
||||
}
|
||||
|
||||
.padding {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
130
src/routes/articles/Note.svelte
Normal file
|
@ -0,0 +1,130 @@
|
|||
<script lang="ts">
|
||||
import { Info, BookCopy, Eye, Network, Sigma, Image, Quote } from '@lucide/svelte';
|
||||
let { title = '', type = 'info' } = $props();
|
||||
</script>
|
||||
|
||||
<div class="note">
|
||||
<div class="head">
|
||||
<div class="icon">
|
||||
{#if type == 'info'}
|
||||
<Info />
|
||||
{:else if type == 'image'}
|
||||
<Image />
|
||||
{:else if type == 'diagram'}
|
||||
<Network />
|
||||
{:else if type == 'quote'}
|
||||
<Quote />
|
||||
{:else if type == 'math'}
|
||||
<Sigma />
|
||||
{:else if type == 'review'}
|
||||
<Eye />
|
||||
{:else if type == 'resource'}
|
||||
<BookCopy />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if type == 'info'}
|
||||
<div class="horiz_line" style:background-color="#8ec07c"></div>
|
||||
{:else if type == 'diagram'}
|
||||
<div class="horiz_line" style:background-color="#d3869b"></div>
|
||||
{:else if type == 'quote'}
|
||||
<div class="horiz_line" style:background-color="#d3869b"></div>
|
||||
{:else if type == 'image'}
|
||||
<div class="horiz_line" style:background-color="#d3869b"></div>
|
||||
{:else if type == 'math'}
|
||||
<div class="horiz_line" style:background-color="#fe8019"></div>
|
||||
{:else if type == 'review'}
|
||||
<div class="horiz_line" style:background-color="#cc241d"></div>
|
||||
{:else if type == 'resource'}
|
||||
<div class="horiz_line" style:background-color="#458588"></div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
{#if type == 'info'}
|
||||
<div class="line" style:background-color="#8ec07c"></div>
|
||||
{:else if type == 'diagram'}
|
||||
<div class="line" style:background-color="#d3869b"></div>
|
||||
{:else if type == 'quote'}
|
||||
<div class="line" style:background-color="#d3869b"></div>
|
||||
{:else if type == 'image'}
|
||||
<div class="line" style:background-color="#d3869b"></div>
|
||||
{:else if type == 'math'}
|
||||
<div class="line" style:background-color="#fe8019"></div>
|
||||
{:else if type == 'review'}
|
||||
<div class="line" style:background-color="#cc241d"></div>
|
||||
{:else if type == 'resource'}
|
||||
<div class="line" style:background-color="#458588"></div>
|
||||
{/if}
|
||||
|
||||
<div class="slot">
|
||||
{#if title != ''}
|
||||
<p class="title">{title}</p>
|
||||
{/if}
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap');
|
||||
|
||||
.title {
|
||||
}
|
||||
|
||||
.note {
|
||||
display: block;
|
||||
margin: 1em 0 1em 0;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
margin-bottom: -1em;
|
||||
padding: 0;
|
||||
margin-right: auto;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 0.1em;
|
||||
margin-left: 0.85em;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.horiz_line {
|
||||
height: 0.1em;
|
||||
margin-left: 0.5em;
|
||||
|
||||
margin-top: 0.7em;
|
||||
display: inline-block;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.slot {
|
||||
margin-left: 1em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.slot > p {
|
||||
flex: 1;
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.icon {
|
||||
}
|
||||
|
||||
.icon:first-child {
|
||||
}
|
||||
</style>
|
53
src/routes/articles/Tip.svelte
Normal file
|
@ -0,0 +1,53 @@
|
|||
<script lang="ts">
|
||||
export let text;
|
||||
</script>
|
||||
|
||||
<div class="tooltip">
|
||||
{text}
|
||||
<span class="tooltiptext"><slot /></span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
color: #fabd2f;
|
||||
border-bottom: 1px dotted #fe8019;
|
||||
}
|
||||
|
||||
/* Tooltip text */
|
||||
.tooltip .tooltiptext {
|
||||
visibility: hidden;
|
||||
|
||||
max-width: 60ch;
|
||||
min-width: 60ch;
|
||||
margin-left: -30ch; /* Use half of the width (120/2 = 60), to center the tooltip */
|
||||
margin-top: .5em;
|
||||
|
||||
background-color: #282828ea;
|
||||
text-wrap-mode: wrap;
|
||||
text-align: justify;
|
||||
padding: 1em;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #fe8019;
|
||||
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
|
||||
/* Position the tooltip text - see examples below! */
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Show the tooltip text when you mouse over the tooltip container */
|
||||
.tooltip:hover .tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.tooltip:hover {
|
||||
color: #fe8019;
|
||||
}
|
||||
</style>
|
|
@ -1,47 +1,57 @@
|
|||
@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;
|
||||
color: #ebdbb2;
|
||||
font-family: 'Inter';
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
br {
|
||||
margin-bottom: 1em;
|
||||
strong {
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
color: #fabd2f;
|
||||
}
|
||||
|
||||
strong:hover {
|
||||
color: #fe8019;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin-bottom: .3em;
|
||||
display: block;
|
||||
font-size: 2em;
|
||||
margin-top: 0em;
|
||||
margin-bottom: 0em;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.7em;
|
||||
margin-bottom: .3em;
|
||||
margin-top: .6em;
|
||||
display: block;
|
||||
font-size: 1.5em;
|
||||
margin-top: 0.83em;
|
||||
margin-bottom: 0em;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.body {
|
||||
background-color: #1d2021;
|
||||
display: flex;
|
||||
a {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
color: #83a598;
|
||||
}
|
||||
|
||||
.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;
|
||||
a:hover {
|
||||
color: #458588;
|
||||
}
|
||||
|
||||
.article_padding {
|
||||
flex: 1;
|
||||
.katex {
|
||||
width: max-content;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.katex-display {
|
||||
margin-top: 0;
|
||||
|
||||
}
|
||||
|
|
0
src/routes/articles/cpu-architecture/+page.svx
Normal file
0
src/routes/articles/gpu-architecture/+page.svx
Normal file
0
src/routes/articles/memory-architecture/+page.svx
Normal file
25
src/routes/articles/technical-debt/+page.svx
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
title: C++ Technical Debt
|
||||
date: "April 20 - 2025"
|
||||
---
|
||||
|
||||
<script>
|
||||
import Paragraph from '../Paragraph.svelte';
|
||||
import HorizontalBreak from '../HorizontalBreak.svelte';
|
||||
</script>
|
||||
|
||||
<HorizontalBreak/>
|
||||
|
||||
<Paragraph>
|
||||
|
||||
Have you ever had your project grow too messy that the idea of **total-rewrite** started haunting your
|
||||
dreams? In this article I'll teach you how to avoid that state forever :)
|
||||
</Paragraph>
|
||||
|
||||
|
||||
## Technical Debt
|
||||
|
||||
<Paragraph>
|
||||
|
||||
What causes such a state?
|
||||
</Paragraph>
|
|
@ -1,102 +0,0 @@
|
|||
# The Graphics Pipeline
|
||||
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
|
||||
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.
|
||||
|
||||
<br/>
|
||||
We can coarsely divide the entire pipeline into 4 stages:
|
||||
Application -> [Geometry Processing] -> Rasterization -> Pixel Processing
|
||||
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"
|
||||
stage and have a recap afterwards to demystify our 4-stage division!
|
||||
|
||||
## Vertices (points in space)
|
||||
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.
|
||||
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.
|
||||
|
||||
<br/>
|
||||
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"
|
||||
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.
|
||||
|
||||
<br/>
|
||||
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
|
||||
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
|
||||
"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),
|
||||
which themselves are composed of a series of "vertices" (points in space).
|
||||
|
||||
<br/>
|
||||
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".
|
||||
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".
|
||||
|
||||
<br/>
|
||||
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?
|
||||
|
||||
## Why Triangles?
|
||||
"Always Planar":
|
||||
Triangles can never be __non-planar__(reside in more than 1 plane)! In Euclidean geometry, any
|
||||
|
||||
|
||||
"Normal surface:"
|
||||
|
||||
"Algorithm Simplicity:"
|
||||
|
||||
"Predictable Winding Order:"
|
||||
|
||||
## Primitive Topologies
|
||||
|
||||
## Indices
|
||||
|
||||
## Input Assembler
|
||||
|
||||
## Coordinate System -- Local Space
|
||||
|
||||
## Coordinate System -- World Space
|
||||
|
||||
## Coordinate system -- View Space
|
||||
|
||||
## Coordinate system -- Clip Space
|
||||
|
||||
## Coordinate system -- Screen Space
|
||||
|
||||
## Vertex Shader
|
||||
|
||||
## Tessellation & Geometry Shaders
|
||||
|
||||
## Rasterizer
|
||||
|
||||
## Pixel Shader
|
||||
|
||||
## Output Merger
|
||||
|
||||
## The Future
|
||||
|
||||
## Conclusion
|
||||
|
||||
## Sources
|
||||
[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 - Face Culling](https://learnopengl.com/Advanced-OpenGL/Face-culling)
|
||||
[Wikipedia - Polygonal Modeling](https://en.wikipedia.org/wiki/Polygonal_modeling)
|
||||
[Wikipedia - Non-uniform Rational B-spline Surfaces](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline)
|
||||
[Wikipedia - Computer Aided Design (CAD)](https://en.wikipedia.org/wiki/Computer-aided_design)
|
||||
[Stackoverflow - Why do 3D engines primarily use triangles to draw surfaces?](https://stackoverflow.com/questions/6100528/why-do-3d-engines-primarily-use-triangles-to-draw-surfaces)
|
|
@ -0,0 +1,846 @@
|
|||
---
|
||||
title: The Graphics Pipeline ; Part 1
|
||||
date: "April 20 - 2025"
|
||||
---
|
||||
|
||||
<script>
|
||||
import Image from "../../Image.svelte"
|
||||
import Note from "../../Note.svelte"
|
||||
import Tip from "../../Tip.svelte"
|
||||
</script>
|
||||
|
||||
Ever wondered how games put all that gore on your display? All that beauty is brought into life by
|
||||
a process called **rendering**, and at the heart of it, is the **graphics pipeline**.
|
||||
|
||||
In this article, we'll dive deeply into the intricate details of this powerful beast.
|
||||
Don't worry if things don't click right away---we’ll go over all the key terms and restate the important stuff to help it sink in.
|
||||
And hey, if you still have questions, feel free to reach out :)
|
||||
|
||||
Initially, I tried cramming everything in **one article**, which hurt the **brevity** and the **structure**.
|
||||
The **graphics pipeline** is a beast---incredibly **complex** and constantly **evolving**.
|
||||
So I split it into a **4-part series**, which lets me go into sufficient depth.
|
||||
But why exactly **4-parts**?
|
||||
|
||||
## Overview
|
||||
|
||||
Like any pipeline, the **graphics pipeline** is made up of several **stages**,
|
||||
each of which can be a mini-pipeline in itself or even parallelized.
|
||||
Each stage takes some input (data and configuration) to generate some output data for the next stage.
|
||||
|
||||
<Note title="High level breakdown of the graphics pipeline", type="diagram">
|
||||
|
||||
Application --> **Geometry Processing** --> Rasterization --> Pixel Processing --> Presentation
|
||||
</Note>
|
||||
|
||||
Before the heavy rendering work starts on the <Tip text="GPU">Graphics Processing Unit</Tip>,
|
||||
we simulate and update the world through **systems** such as physics engine, game logic, networking, etc.
|
||||
all in the **application** stage.
|
||||
This stage is mostly ran on the <Tip text="CPU">Central Processing Unit</Tip>,
|
||||
therefore it is extremely efficient on executing <Tip text="sequentially dependent logic">
|
||||
A type of execution flow where the operations depend on the results of previous steps, limiting parallel execution.
|
||||
In other words, **CPUs** are great at executing **branch-heavy** code, and **GPUs** are geared
|
||||
towards executing a TON of **branch-less** or **branch-light** code in parallel---Like executing some
|
||||
code for each pixel on your screen, there are a ton of pixels but they mostly do their own independent logic. </Tip>.
|
||||
|
||||
The updated scene data is then prepped and fed to the **GPU** for **geometry processing**. Here
|
||||
we figure out where everything ends up on our screen by doing lots of fancy linear algebra.
|
||||
We'll cover this stage in depth very soon so don't panic (yet).
|
||||
|
||||
Afterwards, the final geometric data are converted into <Tip text="pixels"> Pixel is the shorthand for **picture-element**, Voxel is the shorthand for **volumetric-element**. </Tip>
|
||||
and prepped for the **pixel processing** stage via a process called **rasterization**.
|
||||
In other words, this stage converts a rather abstract and internal presentation (geometry)
|
||||
into something more concrete (pixels). It's called rasterization because end the product is a <Tip text="raster">Noun. A rectangular pattern of parallel scanning lines followed by the electron beam on a television screen or computer monitor. -- 1930s: from German Raster, literally ‘screen’, from Latin rastrum ‘rake’, from ras- ‘scraped’, from the verb radere. ---Oxford Languages</Tip>
|
||||
(a grid) of pixels.
|
||||
|
||||
The **pixel processing** stage then uses the rasterized geometry data (pixel data) to do
|
||||
**lighting**, **texturing**, **shadow-mapping**, and all the sweet gory details of a scene (like a murder scene).
|
||||
In short, this stage is responsible for calculating the **final output color** of each pixel.
|
||||
|
||||
The pipeline will then serve (present) the output of the **pixel processing** stage, which is a **rendered image**,
|
||||
to your pretty eyes using your <Tip text="display">Usually a monitor but the technical term for it is
|
||||
the target **surface**. Which can be anything like a VR headset or some other crazy surface used for displaying purposes.</Tip>.
|
||||
|
||||
<Note type="info", title="Chapters of The Graphics Pipeline">
|
||||
|
||||
**Geometry Processing**: How geometry is **represented**, **interpreted**, **transformed** and **expanded**.
|
||||
|
||||
**Rasterization**: How the final geometric data is converted into **pixels** and what data they hold.
|
||||
|
||||
**Pixel Processing**: How we figure out the **final output color** of each pixel.
|
||||
|
||||
**Optimizations**: How modern game-engines like Unreal Engine 5 optimize the pipeline.
|
||||
|
||||
</Note>
|
||||
|
||||
I hope it is now evident why I chose to split the concepts in 4-parts. So... let's jump right into the gory details of the **geometry processing**
|
||||
stage!
|
||||
|
||||
|
||||
|
||||
|
||||
## Surfaces
|
||||
|
||||
Ever been jump-scared by this sight in an <Tip text="FPS">First person (shooter) perspective</Tip>? Why are (the inside of) things rendered like that?
|
||||
|
||||
<Note title="Boo!", type="image">
|
||||
|
||||
<Image
|
||||
paths={["/images/boo.png"]}
|
||||
/>
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
In order to display a (murder) scene,
|
||||
we need to have a way of **representing** the **surface** of its composing objects (like corpses) in computer memory.
|
||||
We only care about the **surface** since we won't be seeing the insides anyway---Not that we want to.
|
||||
At this stage, we only care about the **shape** or the **geometry** of the **surface**.
|
||||
Texturing, lighting, and all the sweet gory details come at a much later stage once all the **geometry** has been processed.
|
||||
|
||||
But how do we represent surfaces in computer memory?
|
||||
|
||||
## Vertices
|
||||
|
||||
There are several ways to **represent** the surfaces of 3d objects for a computer to understand.
|
||||
For instance, <Tip text="NURBS">
|
||||
**Non-uniform rational basis spline** is a mathematical model using **basis splines** (B-splines) that is commonly used in computer graphics for representing curves and surfaces. It offers great flexibility and precision for handling both analytic (defined by common mathematical formulae) and modeled shapes. ---Wikipedia</Tip> surfaces are great for representing **curves**, and it's all about the
|
||||
**high precision** needed to do <Tip text="CAD">Computer Assisted Design</Tip>. We could also do **ray-tracing** using fancy equations for
|
||||
rendering **photo-realistic** images.
|
||||
|
||||
These are all great---ignoring the fact that they would take an eternity to process...
|
||||
But what we need is a **performant** approach that can do this for an entire scene with
|
||||
hundreds of thousands of objects (like a lot of corpses) in under a small fraction of a second. What we need is **polygonal modeling**.
|
||||
|
||||
**Polygonal modeling** enables us to do an exciting thing called **real-time rendering**. The idea is that we only need an
|
||||
**approximation** of a surface to render it **realistically enough** for us to have some fun killing time!
|
||||
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).
|
||||
|
||||
<Note title="A sphere made out of triangles", type="image">
|
||||
|
||||
<Image
|
||||
paths={["/images/polygon_sphere.webp"]}
|
||||
/>
|
||||
|
||||
</Note>
|
||||
|
||||
A **vertex** is simply a point in space.
|
||||
Once we get enough of these **points**, we can connect them to form **primitives** such as **triangles**, **lines**, and **dots**.
|
||||
And once we connect enough of these **primitives** together, they form a **model** or a **mesh** (that we need for our corpse).
|
||||
With some interesting models put together, we can compose a **scene** (like a murder scene :D).
|
||||
|
||||
<Note title="Stanford bunny model in increasing level of detail (LoD)", type="image">
|
||||
|
||||
<Image
|
||||
paths={["/images/bunny.jpg"]}
|
||||
/>
|
||||
|
||||
</Note>
|
||||
|
||||
But let's not get ahead of ourselves. The primary type of **primitive** that we care about during **polygonal modeling**
|
||||
is a **triangle**. But why not squares or polygons with a variable number of edges?
|
||||
|
||||
## Why Triangles?
|
||||
|
||||
In <Tip text="Euclidean geometry"> Developed by **Euclid** around 300 BCE, is based on five axioms. It describes properties of shapes, angles, and space using deductive reasoning. It remained the standard model of geometry for centuries until non-Euclidean geometries and general relativity showed its limits. It's still widely used in education, engineering, and **computer graphics**. ---Wikipedia </Tip>, triangles are always **planar** (they exist only in one plane),
|
||||
any polygon composed of more than 3 points may break this rule, but why does polygons residing in one plane so important
|
||||
to us?
|
||||
|
||||
<Note title="Planar vs Non-Planar polygons" type="image">
|
||||
|
||||
<Image
|
||||
paths={["/images/planar.jpg", "/images/non_planar_1.jpg", "/images/non_planar_2.png"]}
|
||||
/>
|
||||
|
||||
</Note>
|
||||
|
||||
When a polygon exists only in one plane, we can safely imply that **only one face** of it can be visible
|
||||
at any one time; this enables us to utilize a huge optimization technique called **back-face culling**.
|
||||
Which means we avoid wasting a ton of **precious processing time** on the polygons that
|
||||
we know won't be visible to us. We can safely **cull** the **back-faces** since we won't
|
||||
be seeing the **back** of a polygon when it's in the context of a closed-off model.
|
||||
We figure this out by simply using the **winding order** of the triangle to determine whether we're looking at the
|
||||
back of the triangle or the front of it---I'll go in depth about **culling** in part 4.
|
||||
|
||||
Triangles also have a very small **memory footprint**; for instance, when using the **triangle-strip** topology (more on this very soon), for each additional triangle after the first one, only **one extra vertex** is needed.
|
||||
|
||||
The most important attribute, in my opinion, is the **algorithmic simplicity**.
|
||||
Any polygon or shape can be composed from a **set of triangles**; for instance, a rectangle is simply **two coplanar triangles**.
|
||||
Also, it is a common practice in computer science to break down hard problems into simpler, smaller problems.
|
||||
Trust me, this will be a lot more convincing when we cover the **rasterization** stage in part 2 :)
|
||||
|
||||
<Note title="Evolution", type="info">
|
||||
|
||||
As a bonus point to consider; present-day **hardware** and **algorithms** have become **extremely efficient** at processing
|
||||
triangles by doing operations such as sorting, rasterizing, etc, after eons of evolving around them.
|
||||
|
||||
We literary have a **fixed function** (unprogrammable) stage in the pipeline dedicated for rasterizing
|
||||
triangles.
|
||||
|
||||
</Note>
|
||||
|
||||
## Primitive Topology
|
||||
So, we got our set of vertices, but having a bunch of points floating around wouldn't make a scene very lively
|
||||
(or gory), we need to form **triangles** out of them to compose **models** (like our beautiful corpse).
|
||||
|
||||
The **input assembler** is first the mini-stage in the **geometry processing** stage. And it's responsible for **concatenating** our vertices (the input) to assemble **primitives**.
|
||||
It is a **fixed function** stage so we can only configure it (it's not programmable).
|
||||
We can tell the assembler how it should interpret the vertex data by configuring its **primitive** <Tip text="toplogy"> The way in which constituent parts are interrelated or arranged.--mid 19th century: via German from Greek topos ‘place’ + -logy.---Oxford Languages </Tip>.
|
||||
|
||||
Instead of explaining with words, I'm going to show you how each type of topology works with pictures. So buckle up!
|
||||
|
||||
When the topology is **point list**, each **consecutive vertex** (v) defines a **single point** primitive (p)
|
||||
and the number of primitives (n of p) is equals to the number of vertices (n of v).
|
||||
|
||||
<Note title="", type="image">
|
||||
|
||||
<Image
|
||||
paths={["/images/primitive_topology_point_list.svg"]}
|
||||
/>
|
||||
|
||||
</Note>
|
||||
|
||||
<Note type="math">
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
&p_i = \{ v_{i} \} \\ &n_p = n_v
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
When the topology is **line list**, each **consecutive pair of vertices** defines a **single line**:
|
||||
|
||||
<Note title="", type="image">
|
||||
|
||||
<Image
|
||||
paths={["/images/primitive_topology_line_list.svg"]}
|
||||
/>
|
||||
|
||||
</Note>
|
||||
|
||||
<Note type="math">
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
&p_i = \{ v_{2i},\ v_{2i+1} \} \\ &n_p = ⌊ n_v / 2 ⌋
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
When the primitive topology is **line strip**, **one line** is defined by each **vertex and the following vertex**:
|
||||
|
||||
<Note title="", type="image">
|
||||
|
||||
<Image
|
||||
paths={["/images/primitive_topology_line_strip.svg"]}
|
||||
/>
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
<Note type="math">
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
&p_i = \{ v_i, v_{i+1} \} \\ &n_p = \text{max}(0, n_v - 1)
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
When the primitive topology is **triangle list**, each **consecutive set of three vertices** defines a **single triangle**:
|
||||
|
||||
<Note title="", type="image">
|
||||
|
||||
<Image
|
||||
paths={["/images/primitive_topology_triangle_list.svg"]}
|
||||
/>
|
||||
|
||||
</Note>
|
||||
|
||||
<Note type="math">
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
&p_i = \{ v_{3i}, v_{3i+1}, v_{3i+2} \} \\ &n_p = ⌊n_v / 3⌋
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
When the primitive topology is **triangle strip**, **one triangle** is defined by each **vertex and the two vertices that follow it**:
|
||||
|
||||
<Note title="", type="image">
|
||||
|
||||
<Image
|
||||
paths={["/images/primitive_topology_triangle_strip.svg"]}
|
||||
/>
|
||||
|
||||
</Note>
|
||||
|
||||
<Note type="math">
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
&p_i = \{ v_i,\ v_{i + (1 + i \bmod 2)},\ v_{i + (2 - i \bmod 2)} \} \\ &n_p = \text{max}(0, n_v- 2)
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
When the primitive topology is **triangle fan**, **triangles** are defined **around a shared common vertex**:
|
||||
|
||||
<Note title="", type="image">
|
||||
|
||||
<Image
|
||||
paths={["/images/primitive_topology_triangle_fan.svg"]}
|
||||
/>
|
||||
|
||||
</Note>
|
||||
|
||||
<Note type="math">
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
&p_i = \{ v_{i+1}, v_{i+2}, v_0 \} \\ &n_p = \text{max}(0, n_v - 2)
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
## Indices
|
||||
|
||||
|
||||
**Indices** are an array of integers that reference the **vertices** in a vertex buffer.
|
||||
They define the **order** in which vertices should be read (and re-read) by the **input assembler**.
|
||||
Which allows **vertex reuse** and reduces memory usage by preventing duplicate vertices.
|
||||
|
||||
Imagine the following scenario:
|
||||
```cc
|
||||
float triangle_vertices[] = {
|
||||
// x__, y__
|
||||
0.0, 0.5, // center top
|
||||
-0.5, -0.5, // bottom left
|
||||
0.5, -0.5, // bottom right
|
||||
};
|
||||
```
|
||||
|
||||
Here we have one triangle primitive, cool! Now let's create a rectangle:
|
||||
```cc
|
||||
float vertices[] = {
|
||||
// first triangle
|
||||
// x__ y__
|
||||
0.5, 0.5, // top right
|
||||
0.5, -0.5, // bottom right << DUPLICATE
|
||||
-0.5, 0.5, // top left << DUPLICATE
|
||||
|
||||
// second triangle
|
||||
// x__ y__
|
||||
0.5, -0.5, // bottom right << DUPLICATE
|
||||
-0.5, -0.5, // bottom left
|
||||
-0.5, 0.5, // top left << DUPLICATE
|
||||
};
|
||||
```
|
||||
|
||||
As indicated by the comments, we have two **identical** vertices. This situation only gets worse
|
||||
for each additional **attribute** per vertex (vertices pack a lot more information than positions, we'll get to it later).
|
||||
And in a large model with hundreds of thousands of triangles, it becomes unacceptable. To remedy this problem, we do
|
||||
**indexed rendering**:
|
||||
|
||||
```cc
|
||||
float vertices[] = {
|
||||
// first triangle
|
||||
// x__ y__
|
||||
0.5, 0.5, // top right [0]
|
||||
0.5, -0.5, // bottom right [1]
|
||||
-0.5, -0.5, // bottom left [2]
|
||||
-0.5, 0.5, // top left [3]
|
||||
};
|
||||
|
||||
unsigned int indices[] = {
|
||||
0, 1, 3, // first triangle
|
||||
1, 2, 3 // second triangle
|
||||
};
|
||||
```
|
||||
|
||||
And you might be asking, what about **triangle strips** we just talked about? Well, if you try to visualize it,
|
||||
a **large model** cannot possibly be made from a **single strip** of triangles, but from **many**. And we might not even use
|
||||
triangle **strips**---we might use triangle **lists**.
|
||||
|
||||
Either way, using indices is optional but almost always a good idea to use them!
|
||||
|
||||
|
||||
<Note title="Post-Transform Vertex Cache", type="info">
|
||||
|
||||
Indexed rendering also allows the GPU to use a neat optimization trick called **post-transform vertex cache** where
|
||||
if the same index is used after **transformations** happened, it'll fetch the result that's recently cached and
|
||||
won't re-run the transformation logic again.
|
||||
|
||||
I'll explain how vertices are transformed soon, don't worry (yet).
|
||||
|
||||
</Note>
|
||||
|
||||
## **Input Assembler**
|
||||
Alrighty! Do we have everything we need?
|
||||
|
||||
We got our surface representation---**vertices**. We set the **primitive topology** to determine
|
||||
how to concatenate them. And we optionally (but most certainly) provided some **indices** to avoid
|
||||
duplication.
|
||||
|
||||
All this data (and configuration) is then fed to the very first mini-stage of the **graphics pipeline** called
|
||||
the **input assembler**. Which as stated before, is responsible for **assembling** primitives from our **input** (vertices and indices).
|
||||
|
||||
<Note type="diagram", title="Geometry Processing">
|
||||
|
||||
[Vertex/Index Data] --> Input Assembler --> ...
|
||||
|
||||
</Note>
|
||||
|
||||
So what comes next?
|
||||
|
||||
## Coordinate System -- Overview
|
||||
**Assembling primitives** is the **first** essential task in the **geometry processing** stage, and
|
||||
everything you read so far only went over that part.
|
||||
Its **second** vital responsibility is the **transformation** of the said primitives. Let me explain.
|
||||
|
||||
So far, our examples show the geometry in **normalized device coordinates**; or **NDC** for short.
|
||||
This is a small space where the x, y and z values are in range of [-1.0 -> 1.0].
|
||||
Anything outside this range will be **clipped** and won't be visible on screen.
|
||||
Below is our old triangle again which was specified within **NDC**---ignoring the z for now:
|
||||
|
||||
```cc
|
||||
float triangle_vertices[] = {
|
||||
// x__, y__
|
||||
0.0, 0.5, // center top
|
||||
-0.5, -0.5, // bottom left
|
||||
0.5, -0.5, // bottom right
|
||||
};
|
||||
```
|
||||
|
||||
This is because the **rasterizer** expects the **final vertex coordinates** to be in the **NDC** range.
|
||||
Anything outside of this range is, again, **clipped** and not visible.
|
||||
|
||||
Yet, as you might imagine, doing everything in the **NDC** is inconvenient and very limiting.
|
||||
We'd like to **compose** a scene by <Tip text="transforming">Scale, Rotate, Translate. </Tip> some objects around, **interact**
|
||||
with the scene by moving and looking around, and express coordinates in arbitrary
|
||||
units---such as meters.
|
||||
|
||||
This is done by transforming these vertices through **5 coordinate systems** before ending up in NDC
|
||||
(or outside of if they're meant to be clipped). Here's a high-level overview:
|
||||
|
||||
**Local Space**: This is where your model begins in, think of it as the data exported from a model
|
||||
using Blender. If we were to modify a model (the model's vertices itself, not its transformation) it would make most sense to do it here.
|
||||
|
||||
**World Space**: All objects will be stuck into each other at coordinates 0, 0, 0 if we don't move them
|
||||
around the world. This is the transformation that puts your object in the context of the **world**.
|
||||
|
||||
**View Space**: Then we transform everything that was relative to the world in such a way that each
|
||||
vertex is seen from the viewer's point of view.
|
||||
|
||||
**Clip Space**: Then we project everything to the clip coordinates, which is in the range of -1.0 and 1.0.
|
||||
This projection is what makes **perspective** possible (distant objects appearing smaller).
|
||||
|
||||
**Screen Space**: This one is out of our control, it simply puts our now normalized coordinates
|
||||
unto the screen.
|
||||
|
||||
As you can see each of these coordinates systems serve a specific purpose and allows **composition** and **interaction** with a scene.
|
||||
However, doing these **transformations** require a lot of **linear algebra**, specially a ton of **matrix operations**.
|
||||
So, before we get into more depth about these coordinate systems, let's learn how to do **linear transformations** using **linear algebra**!
|
||||
|
||||
|
||||
<Note title="Mathematics Ahead!">
|
||||
|
||||
The concepts in the following sections may be difficult to grasp at first. And **that's okay**, you don't
|
||||
need to pickup everything the first time you read them (I didn't). If you feel passionate about these topics
|
||||
and want to have a better grasp, refer to the references at the bottom of this article and **take
|
||||
your time** :)
|
||||
|
||||
</Note>
|
||||
|
||||
## Linear Algebra --- Vectors
|
||||
|
||||
**Vectors** are the **fundamental** building blocks of the linear algebra. And we're going to get
|
||||
really familiar with them :) But what is a **vector** anyways? As all things in life, it depends.
|
||||
|
||||
For a **physicist**, vectors are **arrows pointing in space**, and what defines them is their **length** (or **magnitude**)
|
||||
and **direction**---that is, any two vectors moved to different **origins** (starting points) are the **same vectors**,
|
||||
as long as their **length** and **direction** remain the same:
|
||||
|
||||
<Note type="image", title="Physicist">
|
||||
|
||||
**Insert Image Here**
|
||||
|
||||
</Note>
|
||||
|
||||
For a **computer scientist**, vectors are a fancy word for **ordered lists of numbers**. Yep, that's it, it feels good
|
||||
to be in the simple world of a computer scientist:
|
||||
|
||||
<Note type="image", title="Computer Scientist">
|
||||
|
||||
**Insert Image Here**
|
||||
|
||||
</Note>
|
||||
|
||||
But **mathematically** speaking, vectors are a lot more **abstract**.
|
||||
Virtually **any** representation of **vectors** (which is called a **vector-space**) is valid as long as they follow a set of **axioms**.
|
||||
It doesn't matter if you think of them as **arrows in space** that happen to have a **numeric representation**,
|
||||
or as a **list of numbers** that happen to have a cute **geometric interpretation** (or even certain mathmatical **functions**).
|
||||
As long the [aximos of vector spaces](https://www.math.ucla.edu/~tao/resource/general/121.1.00s/vector_axioms.html) apply to them, they're vectors.
|
||||
|
||||
However, we won't go into such axioms as we're not interested in **abstract** thinking here.
|
||||
We're aiming to do something **concrete** called **linear transformations** of a set of vertices (models).
|
||||
So it would be ideal for us to think of them like this:
|
||||
|
||||
- A vector describes a series of steps to perform a **transformation** in space.
|
||||
- A vector has the properties: **direction** and **magntitude**.
|
||||
- If its **magntitude** is exactly **1**, then it describes a **direction** in space and is called a **unit vector**.
|
||||
|
||||
Let's go over these points one by one.
|
||||
|
||||
**Basis Vector**
|
||||
|
||||
**Additions**
|
||||
|
||||
**Multiplication**
|
||||
|
||||
**Scalar Operations**
|
||||
|
||||
**Cross Product**
|
||||
|
||||
**Dot Product**
|
||||
|
||||
**Length**
|
||||
|
||||
**Normalization and the normal vector**
|
||||
|
||||
<Note title="The Essence of Linear Algebra">
|
||||
|
||||
If you're interested in **mathematics** (bet you are) and **visualization**, then I highly recommend watching the [Essence of Linear Algebra](https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab)
|
||||
by **3Blue1Brown**. His math series has great intuitive explanations using smooth visuals.
|
||||
And much of my own understanding comes from this series---and the other sources references at the end.
|
||||
|
||||
</Note>
|
||||
|
||||
## Linear Algebra --- Matrices
|
||||
|
||||
** What is a matrix**
|
||||
|
||||
**Addition and Subtraction**
|
||||
|
||||
**Scalar Operations**
|
||||
|
||||
**Multiplication**
|
||||
|
||||
**Division (or lack there of)**
|
||||
|
||||
**Identity Matrix**
|
||||
|
||||
## Linear Algebra --- Transformations
|
||||
|
||||
**Scale**
|
||||
|
||||
**Rotation**
|
||||
|
||||
<Note type="info", title="Gimbal Lock">
|
||||
|
||||
Representing rotations like this makes us prone to a phenomenon called **gimbal lock** where we lose
|
||||
an axis of control. A way of avoiding this is to rotate around an arbitary axis (makes it a lot harder
|
||||
to happen but still possible).
|
||||
|
||||
The ideal way is to use <Tip text="quaternions" >A quaternion is a four-part hyper-complex number used in three-dimensional rotations and orientations.
|
||||
A quaternion number is represented in the form a+bi+cj+dk, where a, b, c, and d parts are real numbers, and i, j, and k are the basis elements, satisfying the equation: i2 = j2 = k2 = ijk = −1.</Tip>,
|
||||
which not only make gimbal lock impossible but are also more computationally friendly.
|
||||
|
||||
A full discussion about quaternions is beyond the scope of this article. However, if you're so interested,
|
||||
I've left links at the end of this article for further study.
|
||||
|
||||
</Note>
|
||||
|
||||
**Why Translation is not a linear transformation**
|
||||
|
||||
**Translation**
|
||||
|
||||
<Note type="info", title="Homogeneous coordinates">
|
||||
|
||||
Why are we using 4D matrixes for vertices that are three dimensional?
|
||||
|
||||
</Note>
|
||||
|
||||
**Embedding it all in one matrix**
|
||||
|
||||
Great! You've refreshed on lots of cool mathematics today, let's get back to the original discussion.
|
||||
**Transforming** the freshly generated **primitives** through this **five** mysterious coordinates systems (or spaces),
|
||||
starting with the **local space**!
|
||||
|
||||
## Coordinate System -- Local Space
|
||||
Alternatively called the **object space**, is the space **relative** to your object's **origin**.
|
||||
All objects have an origin, and it's probably at coordinates [0, 0, 0] (not guaranteed).
|
||||
|
||||
Think of a modelling application like **Blender**. If you create a cube in it and export it, the
|
||||
**vertices** it outputs is probably something like this:
|
||||
|
||||
**insert outputted vertices**.
|
||||
|
||||
And the cube looks plain like this:
|
||||
|
||||
<Note title="Unit cube", type="image">
|
||||
|
||||
</Note>
|
||||
|
||||
I hope this one is easy to grasp since **technically** been using it in our initial triangle
|
||||
and square examples already, the local space just happened to be in NDC though that is not necessary.
|
||||
|
||||
Say if we arbitrarily consider each 1 unit is 1cm, then a 10m x 10m cube would have the following
|
||||
vertices whilst in the local space.
|
||||
|
||||
Basically the vertices that are read from a model file is initially in local space.
|
||||
|
||||
## Coordinate System -- World Space
|
||||
This is the where our first transormation happens. If we were constructing a crime scene
|
||||
without world space transformations then all our corpses would reside somewhere in [0, 0, 0] and
|
||||
would be inside each other (horrid, or lovely?).
|
||||
|
||||
This transformation allows us to **compose** a (game) world, by transforming all the models from
|
||||
their local space and scattering them around the world. We can **translate** (move) the model to the desired
|
||||
spot, **rotate** it because why not, and **scale** it if the model needs scaling (capitan obvious here).
|
||||
|
||||
This transformation is stored in a matrix called the **model matrix**. This is the first of three primary
|
||||
**transformation** matrices which gets multiplied by our vertices.
|
||||
|
||||
<Note tye="math", title="Model transformation">
|
||||
|
||||
```math
|
||||
\text{model}_M * \text{local}_V
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
So one down, two more to go!
|
||||
|
||||
## Coordinate system -- View Space
|
||||
Alternatively names include: **eye space** or the **camera space**.
|
||||
|
||||
This is where the crucial element of **interactivity**
|
||||
comes to life (well depends if you can move the view in your game or not).
|
||||
|
||||
Currently, we're looking at the world
|
||||
through a fixed lens. Since everything that's rendered will be in the [-1.0, 1.0] range, that means
|
||||
**moving** our selves or our **eyes** or the game's **camera** doesn't have a real meaning.
|
||||
|
||||
Now it's you that's stuck! (haha). But don't worry your layz-ass, instead of moving yourself
|
||||
(which again would not make sense since everything visible ends up in the NDC), you can move the world! (how entitled).
|
||||
|
||||
We can achieve this illusion of moving around the world by **reverse transforming** everything based
|
||||
on our own **location** and **orientation**. So imagine we're in the [+10.0, 0.0, 0.0] coordinates. How we simulate this
|
||||
movement is to apply this translation matrix:
|
||||
|
||||
<Note type="math", title="Simplified movement to the right">
|
||||
|
||||
</Note>
|
||||
|
||||
** Position **
|
||||
|
||||
** Orientation **
|
||||
|
||||
We can **rotate** the camera, or more accurately **reverse-rotate** the world, via 3 unit vectors snuggled
|
||||
inside a matrix, the **up** vector (U), the **target** or **direction** vector (D) and the **right**
|
||||
vector (R)
|
||||
|
||||
|
||||
<Note type="math", title="LookAt matrix">
|
||||
|
||||
```math
|
||||
\begin{bmatrix} \color{red}{R_x} & \color{red}{R_y} & \color{red}{R_z} & 0 \\ \color{green}{U_x} & \color{green}{U_y} & \color{green}{U_z} & 0 \\ \color{blue}{D_x} & \color{blue}{D_y} & \color{blue}{D_z} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} * \begin{bmatrix} 1 & 0 & 0 & -\color{purple}{P_x} \\ 0 & 1 & 0 & -\color{purple}{P_y} \\ 0 & 0 & 1 & -\color{purple}{P_z} \\ 0 & 0 & 0 & 1 \end{bmatrix}
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
">>>>>" explain in depth why such operation makes the view rotate.
|
||||
|
||||
Just like the **world space** transformation which is stored in the **model matrix**.
|
||||
This transformation is stored in anoher matrix called the **view matrix**.
|
||||
|
||||
So far we got this equation to apply the **world space** and **view space** transformations
|
||||
to the **local space** vertices of our model:
|
||||
|
||||
<Note tye="math", title="Model_View transformation">
|
||||
|
||||
```math
|
||||
\text{model}_M * \text{view}_M * \text{local}_V
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
That's two down, one left to slay!
|
||||
|
||||
## Coordinate system -- Clip Space
|
||||
|
||||
**Overview***
|
||||
|
||||
**Aspect Ratio***
|
||||
|
||||
**Field of view***
|
||||
|
||||
**Normalization***
|
||||
|
||||
**Putting it all together**
|
||||
|
||||
<Note tye="math", title="Model_View transformation">
|
||||
|
||||
```math
|
||||
\text{model}_M * \text{view}_M * \text{projection}_M * \text{local}_V
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
## Coordinate system -- Screen Space
|
||||
|
||||
** Viewport transform **
|
||||
|
||||
## Coordinate system -- Putting it All Together
|
||||
|
||||
<Note title="Coordinate System", type="diagram">
|
||||
|
||||
</Note>
|
||||
|
||||
## Vertex Shader
|
||||
|
||||
<Note title="Shaders", type="info">
|
||||
|
||||
**Why is it called a "shader" when it's not "shading" anything?**
|
||||
|
||||
</Note>
|
||||
|
||||
## Geometry Shader (optional stage)
|
||||
**We can generate more geometry here since some geometric details are expressed more efficiently through mathmatical expressions than raw vertex data**
|
||||
|
||||
**Different levels of parallelism (why do we still need the vertex shader)**
|
||||
|
||||
**Takes as input "a" primitive, outputs any type of (but only one of) primitive(s)**
|
||||
|
||||
**Adjecency primitive types**
|
||||
|
||||
**Primitive type only indicates number of input vertices since the primitive itself will get cconsumed**
|
||||
|
||||
**Geometry shader instancing**
|
||||
|
||||
**Geometry shader examples**
|
||||
|
||||
**Tessellation/Subdivision**
|
||||
|
||||
**Geometry shaders are out of fashion**
|
||||
|
||||
**Subdivision**
|
||||
|
||||
**Why do we subdivide?**
|
||||
|
||||
**Mathmatical presentation more compressed than actual vertex data**
|
||||
|
||||
**Geometry shaders are versatile, not performant**
|
||||
|
||||
**Data movement bottleneck**
|
||||
|
||||
**LoD**
|
||||
|
||||
## Tessellation Shader (optional stage)
|
||||
**Tessellation Control Shader** (or Hull Shader in DirectX terminology)
|
||||
|
||||
**Tessllator**
|
||||
|
||||
**Quad Primitives**
|
||||
|
||||
**Isolines**
|
||||
|
||||
**Outer tessellation / Inner tessellation**
|
||||
|
||||
**Tessellation Evaluation Shader** (or Domain Shader in DirectX terminology)
|
||||
|
||||
**Tessellation examples**
|
||||
|
||||
## Geometry Processing --- Conclusion
|
||||
Let's wrap up!
|
||||
|
||||
<Note type="diagram", title="Geometry Processing">
|
||||
|
||||
Prepared Vertex Data ->
|
||||
|
||||
Input Assembly turns Vertex Data into digestable structures for the Vertex Shader ->
|
||||
|
||||
Vertex Shader is invoked per vertex for applying transformations via some clever linear algebra ->
|
||||
|
||||
Geometry & Tessellation Shaders expand the geometry on-the-fly and may apply more transformations ->
|
||||
|
||||
... Rasterizer
|
||||
|
||||
</Note>
|
||||
|
||||
The geometric detail that we now have is not **real**. Perfect triangle do not exist in the real world.
|
||||
Our next challenge in this journey is to turn these mathmatical representations into something
|
||||
concrete and significant. We're gonna take these primitives and turn them into **pixels** through
|
||||
a fancy process called **rasterization**.
|
||||
|
||||
You can continue on to [part 2](/articles/the-graphics-pipeline/rasterization) of this article series and learn all about how rasterization
|
||||
works.
|
||||
|
||||
## Sources
|
||||
|
||||
<Note title="Reviewers", type="review">
|
||||
|
||||
MMZ ❤️
|
||||
|
||||
Grammarly
|
||||
|
||||
Some LLMs
|
||||
|
||||
</Note>
|
||||
|
||||
<Note title="Books", type="resource">
|
||||
|
||||
[Joey De Vriez --- LearnOpenGL](https://learnopengl.com/) <br/>
|
||||
[Tomas Akenine Moller --- Real-Time Rendering (4th ed)](https://www.realtimerendering.com/intro.html) <br/>
|
||||
[Gabriel Gambetta --- Computer Graphics from Scratch](https://gabrielgambetta.com/computer-graphics-from-scratch/) <br/>
|
||||
</Note>
|
||||
|
||||
<Note title="Wikipedia", type="resource">
|
||||
|
||||
[Polygonal Modeling](https://en.wikipedia.org/wiki/Polygonal_modeling) <br/>
|
||||
[Non-uniform Rational B-spline Surfaces](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline) <br/>
|
||||
[Computer Aided Design (CAD)](https://en.wikipedia.org/wiki/Computer-aided_design) <br/>
|
||||
[Rasterization](https://en.wikipedia.org/wiki/Rasterisation) <br/>
|
||||
[Euclidean geometry](https://en.wikipedia.org/wiki/Euclidean_geometry) <br/>
|
||||
[Vector space](https://en.wikipedia.org/wiki/Vector_space) <br/>
|
||||
|
||||
</Note>
|
||||
|
||||
<Note title="Youtube", type="resource">
|
||||
|
||||
[Miolith --- Quick Understanding of Homogeneous Coordinates for Computer Graphics](https://www.youtube.com/watch?v=o-xwmTODTUI) <br/>
|
||||
[Leios Labs --- What are affine transformations?](https://www.youtube.com/watch?v=E3Phj6J287o) <br/>
|
||||
[3Blue1Brown --- Essence of linear algebra (highly recommended playlist)](https://www.youtube.com/watch?v=fNk_zzaMoSs&list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab) <br/>
|
||||
[3Blue1Brown --- Quaternions and 3d rotation, explained interactively](https://www.youtube.com/watch?v=zjMuIxRvygQ) <br/>
|
||||
[pikuma --- Math for Game Developers (playlist)](https://www.youtube.com/watch?v=Do_vEjd6gF0&list=PLYnrabpSIM-93QtJmGnQcJRdiqMBEwZ7_) <br/>
|
||||
[pikuma --- 3D Graphics (playlist)](https://www.youtube.com/watch?v=Do_vEjd6gF0&list=PLYnrabpSIM-97qGEeOWnxZBqvR_zwjWoo) <br/>
|
||||
[Cem Yuksel --- Introduction to Computer Graphics (playlist)](https://www.youtube.com/watch?v=vLSphLtKQ0o&list=PLplnkTzzqsZTfYh4UbhLGpI5kGd5oW_Hh) <br/>
|
||||
[Cem Yuksel --- Interactive Computer Graphics (playlist)](https://www.youtube.com/watch?v=UVCuWQV_-Es&list=PLplnkTzzqsZS3R5DjmCQsqupu43oS9CFN&pp=0gcJCV8EOCosWNin) <br/>
|
||||
[javidx9 --- Essential Mathematics For Aspiring Game Developers](https://www.youtube.com/watch?v=DPfxjQ6sqrc) <br/>
|
||||
</Note>
|
||||
|
||||
<Note title="Articles", type="resource">
|
||||
|
||||
[Stackoverflow --- Why do 3D engines primarily use triangles to draw surfaces?](https://stackoverflow.com/questions/6100528/why-do-3d-engines-primarily-use-triangles-to-draw-surfaces) <br/>
|
||||
[The ryg blog --- The barycentric conspiracy](https://fgiesen.wordpress.com/2013/02/06/the-barycentric-conspirac/) <br/>
|
||||
[Juan Pineda --- A Parallel Algorithm for Polygon Rasterization](https://www.cs.drexel.edu/~deb39/Classes/Papers/comp175-06-pineda.pdf) <br/>
|
||||
[Kristoffer Dyrkorn --- A fast and precise triangle rasterizer](https://kristoffer-dyrkorn.github.io/triangle-rasterizer/) <br/>
|
||||
[Microsoft --- Rasterization Rules](https://learn.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-rasterizer-stage-rules) <br/>
|
||||
[Axioms of vector spaces](https://www.math.ucla.edu/~tao/resource/general/121.1.00s/vector_axioms.html)
|
||||
</Note>
|
||||
|
||||
<Note title="Documentations", type="resource">
|
||||
|
||||
[Vulkan Docs --- Drawing](https://docs.vulkan.org/spec/latest/chapters/drawing.html) <br/>
|
||||
[Vulkan Docs --- Pipeline Diagram](https://docs.vulkan.org/spec/latest/_images/pipelinemesh.svg) <br/>
|
||||
</Note>
|
|
@ -0,0 +1,144 @@
|
|||
---
|
||||
title: The Graphics Pipeline --- Optimizations
|
||||
date: "April 20 - 2025"
|
||||
---
|
||||
|
||||
<script>
|
||||
import Image from "../../Image.svelte"
|
||||
import Note from "../../Note.svelte"
|
||||
import Tip from "../../Tip.svelte"
|
||||
</script>
|
||||
|
||||
## Optimizing the Pipeline
|
||||
<Note type="quote" title="An idiot admires complexity, a genius admires simplicity.">
|
||||
|
||||
--- Terry A. Davis
|
||||
</Note>
|
||||
|
||||
Let's get our heads out of the abstract and dizzying mathmatical world now and think like an engineer.
|
||||
|
||||
**Out of the mathmatical world, into the engineering world!**
|
||||
|
||||
## Deferred Shading
|
||||
**Deferred Shading**
|
||||
|
||||
**Bottleneck in pixel shading**
|
||||
|
||||
**The G Buffer**
|
||||
|
||||
**Forward pass** or the **Geometry Pass**
|
||||
|
||||
**Deferred pass** or the **Lighting pass**
|
||||
|
||||
**Anti Aliasing**
|
||||
|
||||
## Beyond G-Buffers --- Visibility Buffers
|
||||
**Pros and Cons of G-Buffers**
|
||||
|
||||
**High memory consumption**
|
||||
|
||||
**May be slower for simple scenes**
|
||||
|
||||
**How we did thing in the traditional graphics pipeline**
|
||||
|
||||
**Intro to Visbility Buffers!**
|
||||
|
||||
## Meshlet-based Rendering
|
||||
**Intro to Mesh shaders**
|
||||
|
||||
**Issue with Low resolution -> High resolution**
|
||||
|
||||
**[Task Shader -> Mesh Generation -> Mesh Shader] -> Rasterization -> Pixel Shader -> Merger**
|
||||
** ^^^ GEOMETRY PROCESSING -> ^^^ -> Pixel Processing
|
||||
|
||||
## Conclusion
|
||||
Let's---for the final time, have a quick recap and go everything at the speed of **light** :)
|
||||
|
||||
**Application** <br/>
|
||||
The pipeline starts simulating the world on the **CPU** and updates, changes, destroys things
|
||||
through systems like physics, ecs, events, etc, etc. Here we have full autonomy.
|
||||
|
||||
**Geometry Processing** <br/>
|
||||
The **graphics pipeline** then provides the **scene data** as a set of **vertices** that form
|
||||
**primitives** to the **input assembler**. We use **triangles** because they're the best! Then this
|
||||
**input assembler** does what it says and **assembles** some input for the **vertex shader**.
|
||||
This **vertex shader** transforms the vertices through different **coordinate systems** and figure out where
|
||||
everything should end up on the screen. Here we can optionally do some work with the **geomtry** and **tessellation**
|
||||
steps to generate more geometry on the fly---since expressing some geometric detail mathmatically is more efficient than providing the concrete geometry.
|
||||
This would help us lighten the load on the DRAM -> GPU data lines which are often a bottleneck.
|
||||
|
||||
**Rasterization** <br/>
|
||||
After all that **geometry processing** we pass the final geometry data to the hardcoded hardware **rasterizer**
|
||||
to do **rasterization** and **interpolation** for us and convert the **abstract geometry** into concrete **pixels**.
|
||||
All by using triangles because they're the best.
|
||||
|
||||
**Pixel Processing** <br/>
|
||||
The **rasterizer** then hands off the work to the **pixel/fragment shader** and our world will end up
|
||||
being so sexy and colorful! After processing all the fragments the **output merger** will squeeze these
|
||||
together and compose the final image.
|
||||
|
||||
**Presentation** <br/>
|
||||
The **presentation engine** will then feed the output of the pipeline to the target display **surface**
|
||||
for your pretty eyes to digest and enjoy.
|
||||
|
||||
You've done it! You read through all this garbage just to learn how the **graphics pipeline** works.
|
||||
Give yourself a pat on the back and a well deserved reward.
|
||||
|
||||
Thanks for reading all the way through! Any feedback, criticism, or question is welcome so contact
|
||||
me if you'd like. Good luck on your journey, wherever it may take you :)
|
||||
|
||||
## Sources
|
||||
|
||||
<Note title="Reviewers", type="review">
|
||||
|
||||
MMZ ❤️
|
||||
|
||||
Grammarly
|
||||
|
||||
Some LLMs
|
||||
|
||||
</Note>
|
||||
|
||||
<Note title="Books", type="resource">
|
||||
|
||||
[Joey De Vriez --- LearnOpenGL](https://learnopengl.com/)
|
||||
[Tomas Akenine Moller --- Real-Time Rendering (4th ed)](https://www.realtimerendering.com/intro.html)
|
||||
[Gabriel Gambetta --- Computer Graphics from Scratch](https://gabrielgambetta.com/computer-graphics-from-scratch/)
|
||||
</Note>
|
||||
|
||||
<Note title="Wikipedia", type="resource">
|
||||
|
||||
[Polygonal Modeling](https://en.wikipedia.org/wiki/Polygonal_modeling)
|
||||
[Non-uniform Rational B-spline Surfaces](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline)
|
||||
[Computer Aided Design (CAD)](https://en.wikipedia.org/wiki/Computer-aided_design)
|
||||
[Rasterization](https://en.wikipedia.org/wiki/Rasterisation)
|
||||
[Euclidean geometry](https://en.wikipedia.org/wiki/Euclidean_geometry)
|
||||
</Note>
|
||||
|
||||
<Note title="Youtube", type="resource">
|
||||
|
||||
[Miolith --- Quick Understanding of Homogeneous Coordinates for Computer Graphics](https://www.youtube.com/watch?v=o-xwmTODTUI)
|
||||
[Leios Labs --- What are affine transformations?](https://www.youtube.com/watch?v=E3Phj6J287o)
|
||||
[3Blue1Brown --- Essence of linear algebra (highly recommended playlist)](https://www.youtube.com/watch?v=fNk_zzaMoSs&list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab)
|
||||
[3Blue1Brown --- Quaternions and 3d rotation, explained interactively](https://www.youtube.com/watch?v=zjMuIxRvygQ)
|
||||
[pikuma --- Math for Game Developers (playlist)](https://www.youtube.com/watch?v=Do_vEjd6gF0&list=PLYnrabpSIM-93QtJmGnQcJRdiqMBEwZ7_)
|
||||
[pikuma --- 3D Graphics (playlist)](https://www.youtube.com/watch?v=Do_vEjd6gF0&list=PLYnrabpSIM-97qGEeOWnxZBqvR_zwjWoo)
|
||||
[Cem Yuksel --- Introduction to Computer Graphics (playlist)](https://www.youtube.com/watch?v=vLSphLtKQ0o&list=PLplnkTzzqsZTfYh4UbhLGpI5kGd5oW_Hh)
|
||||
[Cem Yuksel --- Interactive Computer Graphics (playlist)](https://www.youtube.com/watch?v=UVCuWQV_-Es&list=PLplnkTzzqsZS3R5DjmCQsqupu43oS9CFN&pp=0gcJCV8EOCosWNin)
|
||||
[javidx9 --- Essential Mathematics For Aspiring Game Developers](https://www.youtube.com/watch?v=DPfxjQ6sqrc)
|
||||
</Note>
|
||||
|
||||
<Note title="Articles", type="resource">
|
||||
|
||||
[Stackoverflow --- Why do 3D engines primarily use triangles to draw surfaces?](https://stackoverflow.com/questions/6100528/why-do-3d-engines-primarily-use-triangles-to-draw-surfaces)
|
||||
[The ryg blog --- The barycentric conspiracy](https://fgiesen.wordpress.com/2013/02/06/the-barycentric-conspirac/)
|
||||
[Juan Pineda --- A Parallel Algorithm for Polygon Rasterization](https://www.cs.drexel.edu/~deb39/Classes/Papers/comp175-06-pineda.pdf)
|
||||
[Kristoffer Dyrkorn --- A fast and precise triangle rasterizer](https://kristoffer-dyrkorn.github.io/triangle-rasterizer/)
|
||||
[Microsoft --- Rasterization Rules](https://learn.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-rasterizer-stage-rules)
|
||||
</Note>
|
||||
|
||||
<Note title="Documentations", type="resource">
|
||||
|
||||
[Vulkan Docs --- Drawing](https://docs.vulkan.org/spec/latest/chapters/drawing.html)
|
||||
[Vulkan Docs --- Pipeline Diagram](https://docs.vulkan.org/spec/latest/_images/pipelinemesh.svg)
|
||||
</Note>
|
|
@ -0,0 +1,115 @@
|
|||
---
|
||||
title: The Graphics Pipeline --- Pixel Processing
|
||||
date: "April 20 - 2025"
|
||||
---
|
||||
|
||||
<script>
|
||||
import Image from "../../Image.svelte"
|
||||
import Note from "../../Note.svelte"
|
||||
import Tip from "../../Tip.svelte"
|
||||
</script>
|
||||
|
||||
## Pixel Processing
|
||||
**Overview**
|
||||
|
||||
## Texturing
|
||||
**Vertex Data Extension**
|
||||
|
||||
**Texture Coordinates**
|
||||
|
||||
**Texture Sampling**
|
||||
|
||||
**Mipmaps**
|
||||
|
||||
**Non-color Data**
|
||||
|
||||
## Lighting
|
||||
**Phong Shading**
|
||||
|
||||
// The model was named after its developer B`ui Tóng Phong
|
||||
|
||||
**Ambient**
|
||||
|
||||
**Diffuse**
|
||||
|
||||
**Specular**
|
||||
|
||||
**Combined (Phong)**
|
||||
|
||||
## Shadows
|
||||
|
||||
## Anti-Aliasing
|
||||
**SSAA**
|
||||
|
||||
**MSAA**
|
||||
|
||||
## Post-Processing & Screen-Space Effects
|
||||
|
||||
## Pixel Shaders
|
||||
|
||||
## Presentation
|
||||
|
||||
## Depth Testing
|
||||
|
||||
## Stencil Testing
|
||||
|
||||
## Output Merger
|
||||
** Transparency**
|
||||
|
||||
**Blending**
|
||||
|
||||
## Sources
|
||||
|
||||
<Note title="Reviewers", type="review">
|
||||
|
||||
MMZ ❤️
|
||||
|
||||
Grammarly
|
||||
|
||||
Some LLMs
|
||||
|
||||
</Note>
|
||||
|
||||
<Note title="Books", type="resource">
|
||||
|
||||
[Joey De Vriez --- LearnOpenGL](https://learnopengl.com/)
|
||||
[Tomas Akenine Moller --- Real-Time Rendering (4th ed)](https://www.realtimerendering.com/intro.html)
|
||||
[Gabriel Gambetta --- Computer Graphics from Scratch](https://gabrielgambetta.com/computer-graphics-from-scratch/)
|
||||
</Note>
|
||||
|
||||
<Note title="Wikipedia", type="resource">
|
||||
|
||||
[Polygonal Modeling](https://en.wikipedia.org/wiki/Polygonal_modeling)
|
||||
[Non-uniform Rational B-spline Surfaces](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline)
|
||||
[Computer Aided Design (CAD)](https://en.wikipedia.org/wiki/Computer-aided_design)
|
||||
[Rasterization](https://en.wikipedia.org/wiki/Rasterisation)
|
||||
[Euclidean geometry](https://en.wikipedia.org/wiki/Euclidean_geometry)
|
||||
</Note>
|
||||
|
||||
<Note title="Youtube", type="resource">
|
||||
|
||||
[Miolith --- Quick Understanding of Homogeneous Coordinates for Computer Graphics](https://www.youtube.com/watch?v=o-xwmTODTUI)
|
||||
[Leios Labs --- What are affine transformations?](https://www.youtube.com/watch?v=E3Phj6J287o)
|
||||
[3Blue1Brown --- Essence of linear algebra (highly recommended playlist)](https://www.youtube.com/watch?v=fNk_zzaMoSs&list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab)
|
||||
[3Blue1Brown --- Quaternions and 3d rotation, explained interactively](https://www.youtube.com/watch?v=zjMuIxRvygQ)
|
||||
[pikuma --- Math for Game Developers (playlist)](https://www.youtube.com/watch?v=Do_vEjd6gF0&list=PLYnrabpSIM-93QtJmGnQcJRdiqMBEwZ7_)
|
||||
[pikuma --- 3D Graphics (playlist)](https://www.youtube.com/watch?v=Do_vEjd6gF0&list=PLYnrabpSIM-97qGEeOWnxZBqvR_zwjWoo)
|
||||
[Cem Yuksel --- Introduction to Computer Graphics (playlist)](https://www.youtube.com/watch?v=vLSphLtKQ0o&list=PLplnkTzzqsZTfYh4UbhLGpI5kGd5oW_Hh)
|
||||
[Cem Yuksel --- Interactive Computer Graphics (playlist)](https://www.youtube.com/watch?v=UVCuWQV_-Es&list=PLplnkTzzqsZS3R5DjmCQsqupu43oS9CFN&pp=0gcJCV8EOCosWNin)
|
||||
[javidx9 --- Essential Mathematics For Aspiring Game Developers](https://www.youtube.com/watch?v=DPfxjQ6sqrc)
|
||||
</Note>
|
||||
|
||||
<Note title="Articles", type="resource">
|
||||
|
||||
[Stackoverflow --- Why do 3D engines primarily use triangles to draw surfaces?](https://stackoverflow.com/questions/6100528/why-do-3d-engines-primarily-use-triangles-to-draw-surfaces)
|
||||
[The ryg blog --- The barycentric conspiracy](https://fgiesen.wordpress.com/2013/02/06/the-barycentric-conspirac/)
|
||||
[Juan Pineda --- A Parallel Algorithm for Polygon Rasterization](https://www.cs.drexel.edu/~deb39/Classes/Papers/comp175-06-pineda.pdf)
|
||||
[Kristoffer Dyrkorn --- A fast and precise triangle rasterizer](https://kristoffer-dyrkorn.github.io/triangle-rasterizer/)
|
||||
[Microsoft --- Rasterization Rules](https://learn.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-rasterizer-stage-rules)
|
||||
</Note>
|
||||
|
||||
<Note title="Documentations", type="resource">
|
||||
|
||||
[Vulkan Docs --- Drawing](https://docs.vulkan.org/spec/latest/chapters/drawing.html)
|
||||
[Vulkan Docs --- Pipeline Diagram](https://docs.vulkan.org/spec/latest/_images/pipelinemesh.svg)
|
||||
</Note>
|
|
@ -0,0 +1,99 @@
|
|||
---
|
||||
title: The Graphics Pipeline --- Rasterization
|
||||
date: "April 20 - 2025"
|
||||
---
|
||||
|
||||
<script>
|
||||
import Image from "../../Image.svelte"
|
||||
import Note from "../../Note.svelte"
|
||||
import Tip from "../../Tip.svelte"
|
||||
</script>
|
||||
|
||||
## Rasterization
|
||||
|
||||
**Bounding Box**
|
||||
|
||||
**Winding order**
|
||||
|
||||
**P needs to be on the "RIGHT" side of a->b**
|
||||
|
||||
**Cross Product**
|
||||
|
||||
**Interpolation**
|
||||
|
||||
Remember the god forsaken **input assembler**? Let's expand our understanding of it
|
||||
since-- for simplicity's sake, we skipped over the fact that **vertices** can hold much, much more data
|
||||
than only positions.
|
||||
|
||||
**Barycentric Interpolation** NOTE NOT linear interpolation
|
||||
|
||||
**Some Optimizations**
|
||||
|
||||
<Note title="Software Rasterization">
|
||||
|
||||
What we've implemented is a simple toy rasterizer written to be run on the CPU for educational
|
||||
purposes only. It is inefficient, has shit precision (integer precision) thus it is choppy when moving things around, and has many problems.
|
||||
However, GPUs have dedicated hardwares that run incredibly optimized algorithms to do this
|
||||
sort of thing; hence what we made is called a **software** rasterizer ---as opposed to the usual
|
||||
**hardware** rasterizer.
|
||||
|
||||
It's nice to be aware of and appreciate the simplicity of triangles. If our polygons had variable
|
||||
number of edges then it would be really difficult to come up with efficient algorithms for doing this.
|
||||
|
||||
</Note>
|
||||
|
||||
## Sources
|
||||
|
||||
<Note title="Reviewers", type="review">
|
||||
|
||||
MMZ ❤️
|
||||
|
||||
Grammarly
|
||||
|
||||
Some LLMs
|
||||
|
||||
</Note>
|
||||
|
||||
<Note title="Books", type="resource">
|
||||
|
||||
[Joey De Vriez --- LearnOpenGL](https://learnopengl.com/)
|
||||
[Tomas Akenine Moller --- Real-Time Rendering (4th ed)](https://www.realtimerendering.com/intro.html)
|
||||
[Gabriel Gambetta --- Computer Graphics from Scratch](https://gabrielgambetta.com/computer-graphics-from-scratch/)
|
||||
</Note>
|
||||
|
||||
<Note title="Wikipedia", type="resource">
|
||||
|
||||
[Polygonal Modeling](https://en.wikipedia.org/wiki/Polygonal_modeling)
|
||||
[Non-uniform Rational B-spline Surfaces](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline)
|
||||
[Computer Aided Design (CAD)](https://en.wikipedia.org/wiki/Computer-aided_design)
|
||||
[Rasterization](https://en.wikipedia.org/wiki/Rasterisation)
|
||||
[Euclidean geometry](https://en.wikipedia.org/wiki/Euclidean_geometry)
|
||||
</Note>
|
||||
|
||||
<Note title="Youtube", type="resource">
|
||||
|
||||
[Miolith --- Quick Understanding of Homogeneous Coordinates for Computer Graphics](https://www.youtube.com/watch?v=o-xwmTODTUI)
|
||||
[Leios Labs --- What are affine transformations?](https://www.youtube.com/watch?v=E3Phj6J287o)
|
||||
[3Blue1Brown --- Essence of linear algebra (highly recommended playlist)](https://www.youtube.com/watch?v=fNk_zzaMoSs&list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab)
|
||||
[3Blue1Brown --- Quaternions and 3d rotation, explained interactively](https://www.youtube.com/watch?v=zjMuIxRvygQ)
|
||||
[pikuma --- Math for Game Developers (playlist)](https://www.youtube.com/watch?v=Do_vEjd6gF0&list=PLYnrabpSIM-93QtJmGnQcJRdiqMBEwZ7_)
|
||||
[pikuma --- 3D Graphics (playlist)](https://www.youtube.com/watch?v=Do_vEjd6gF0&list=PLYnrabpSIM-97qGEeOWnxZBqvR_zwjWoo)
|
||||
[Cem Yuksel --- Introduction to Computer Graphics (playlist)](https://www.youtube.com/watch?v=vLSphLtKQ0o&list=PLplnkTzzqsZTfYh4UbhLGpI5kGd5oW_Hh)
|
||||
[Cem Yuksel --- Interactive Computer Graphics (playlist)](https://www.youtube.com/watch?v=UVCuWQV_-Es&list=PLplnkTzzqsZS3R5DjmCQsqupu43oS9CFN&pp=0gcJCV8EOCosWNin)
|
||||
[javidx9 --- Essential Mathematics For Aspiring Game Developers](https://www.youtube.com/watch?v=DPfxjQ6sqrc)
|
||||
</Note>
|
||||
|
||||
<Note title="Articles", type="resource">
|
||||
|
||||
[Stackoverflow --- Why do 3D engines primarily use triangles to draw surfaces?](https://stackoverflow.com/questions/6100528/why-do-3d-engines-primarily-use-triangles-to-draw-surfaces)
|
||||
[The ryg blog --- The barycentric conspiracy](https://fgiesen.wordpress.com/2013/02/06/the-barycentric-conspirac/)
|
||||
[Juan Pineda --- A Parallel Algorithm for Polygon Rasterization](https://www.cs.drexel.edu/~deb39/Classes/Papers/comp175-06-pineda.pdf)
|
||||
[Kristoffer Dyrkorn --- A fast and precise triangle rasterizer](https://kristoffer-dyrkorn.github.io/triangle-rasterizer/)
|
||||
[Microsoft --- Rasterization Rules](https://learn.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-rasterizer-stage-rules)
|
||||
</Note>
|
||||
|
||||
<Note title="Documentations", type="resource">
|
||||
|
||||
[Vulkan Docs --- Drawing](https://docs.vulkan.org/spec/latest/chapters/drawing.html)
|
||||
[Vulkan Docs --- Pipeline Diagram](https://docs.vulkan.org/spec/latest/_images/pipelinemesh.svg)
|
||||
</Note>
|
BIN
static/images/boo.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
static/images/bunny.jpg
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
static/images/bunny.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
static/images/non_planar_1.jpg
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
static/images/non_planar_2.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
static/images/planar.jpg
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
static/images/polygon_sphere.webp
Normal file
After Width: | Height: | Size: 18 KiB |
126
static/images/primitive_topology_line_list.svg
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="89.898438"
|
||||
height="107.35807"
|
||||
viewBox="0 0 89.898439 107.35807"
|
||||
version="1.1"
|
||||
id="svg8653"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs8647">
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="DartArrow"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto-start-reverse"
|
||||
markerWidth="1"
|
||||
markerHeight="1"
|
||||
viewBox="0 0 1 1"
|
||||
preserveAspectRatio="xMidYMid">
|
||||
<path
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
transform="scale(-0.5)"
|
||||
id="path6" />
|
||||
</marker>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata8650">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="5.0234375"
|
||||
y="12.867185"
|
||||
id="text5070-2-2-9-9"><tspan
|
||||
id="tspan5068-0-3-36-9"
|
||||
x="5.0234375"
|
||||
y="12.867185"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="5.0234375"
|
||||
y="92.86718"
|
||||
id="text5070-2-2-9-9-7"><tspan
|
||||
id="tspan5068-0-3-36-9-6"
|
||||
x="5.0234375"
|
||||
y="92.86718"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="85.023438"
|
||||
y="12.867185"
|
||||
id="text5070-2-2-9-9-6"><tspan
|
||||
id="tspan5068-0-3-36-9-4"
|
||||
x="85.023438"
|
||||
y="12.867185"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="85.023438"
|
||||
y="92.86718"
|
||||
id="text5070-2-2-9-9-77"><tspan
|
||||
id="tspan5068-0-3-36-9-5"
|
||||
x="85.023438"
|
||||
y="92.86718"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">3</tspan></text>
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-2"
|
||||
cx="85.023438"
|
||||
cy="22.86717"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-2-4"
|
||||
cx="85.023438"
|
||||
cy="102.86718"
|
||||
r="3.4908931" />
|
||||
<path
|
||||
style="fill:#f9f9f9;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 5.023437,22.86718 H 85.023434"
|
||||
id="path2033" />
|
||||
<path
|
||||
style="fill:#f9f9f9;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 5.023437,102.86718 H 85.023434"
|
||||
id="path2033-5" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-3"
|
||||
cx="5.0234375"
|
||||
cy="102.86718"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-3-8"
|
||||
cx="5.0234375"
|
||||
cy="22.867186"
|
||||
r="3.4908931" />
|
||||
<path
|
||||
style="fill:#f9f9f9;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)"
|
||||
d="m 20.023434,17.86718 c 16.66767,0 33.33433,0 50,0"
|
||||
id="path5581" />
|
||||
<path
|
||||
id="path5885"
|
||||
d="m 20.023434,97.86718 c 16.66767,0 33.33433,0 50,0"
|
||||
style="fill:#f9f9f9;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)" />
|
||||
</svg>
|
After Width: | Height: | Size: 7.1 KiB |
126
static/images/primitive_topology_line_strip.svg
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="249.89841"
|
||||
height="27.365885"
|
||||
viewBox="0 0 249.89841 27.365885"
|
||||
version="1.1"
|
||||
id="svg8653"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs8647">
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="DartArrow"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto-start-reverse"
|
||||
markerWidth="1"
|
||||
markerHeight="1"
|
||||
viewBox="0 0 1 1"
|
||||
preserveAspectRatio="xMidYMid">
|
||||
<path
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
transform="scale(-0.5)"
|
||||
id="path6" />
|
||||
</marker>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata8650">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="5.0234332"
|
||||
y="12.875005"
|
||||
id="text5070-2-2-9-9-8"><tspan
|
||||
id="tspan5068-0-3-36-9-9"
|
||||
x="5.0234332"
|
||||
y="12.875005"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="165.02344"
|
||||
y="12.875005"
|
||||
id="text5070-2-2-9-9-7-7"><tspan
|
||||
id="tspan5068-0-3-36-9-6-6"
|
||||
x="165.02344"
|
||||
y="12.875005"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="85.02343"
|
||||
y="12.875005"
|
||||
id="text5070-2-2-9-9-6-2"><tspan
|
||||
id="tspan5068-0-3-36-9-4-8"
|
||||
x="85.02343"
|
||||
y="12.875005"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="245.02341"
|
||||
y="12.875005"
|
||||
id="text5070-2-2-9-9-77-5"><tspan
|
||||
id="tspan5068-0-3-36-9-5-1"
|
||||
x="245.02341"
|
||||
y="12.875005"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">3</tspan></text>
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-5-0-7"
|
||||
cx="245.02341"
|
||||
cy="22.874998"
|
||||
r="3.4908931" />
|
||||
<path
|
||||
style="fill:#f9f9f9;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 5.02343,22.875 240,-5e-6"
|
||||
id="path2085" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-3"
|
||||
cx="5.0234332"
|
||||
cy="22.874998"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-3-9"
|
||||
cx="85.02343"
|
||||
cy="22.874998"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-3-1"
|
||||
cx="165.02344"
|
||||
cy="22.874998"
|
||||
r="3.4908931" />
|
||||
<path
|
||||
style="fill:#f9f9f9;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)"
|
||||
d="m 20.02343,17.874995 c 16.66767,0 33.33433,0 50,0"
|
||||
id="path16307" />
|
||||
<path
|
||||
id="path16954"
|
||||
d="m 100.02343,17.874995 c 16.66767,0 33.33433,0 50,0"
|
||||
style="fill:#f9f9f9;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)" />
|
||||
<path
|
||||
style="fill:#f9f9f9;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)"
|
||||
d="m 180.02343,17.874995 c 16.66767,0 33.33433,0 50,0"
|
||||
id="path17316" />
|
||||
</svg>
|
After Width: | Height: | Size: 7.2 KiB |
334
static/images/primitive_topology_point_list.svg
Normal file
|
@ -0,0 +1,334 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="200.14062"
|
||||
height="147.16275"
|
||||
viewBox="0 0 200.14063 147.16275"
|
||||
version="1.1"
|
||||
id="svg8653"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs8647">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter2"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="fbSourceGraphic"
|
||||
id="feColorMatrix2" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix14" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix15"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="color2"
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter3"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="fbSourceGraphic"
|
||||
id="feColorMatrix3" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix16" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix17"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="color2"
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter4"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="fbSourceGraphic"
|
||||
id="feColorMatrix4" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix18" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix19"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="color2"
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter5"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="fbSourceGraphic"
|
||||
id="feColorMatrix5" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix20" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix21"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="color2"
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter6"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="fbSourceGraphic"
|
||||
id="feColorMatrix6" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix22" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix23"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="color2"
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter7"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="fbSourceGraphic"
|
||||
id="feColorMatrix7" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix24" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix25"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="color2"
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter8"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="fbSourceGraphic"
|
||||
id="feColorMatrix8" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix26" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix27"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="color2"
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter9"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="fbSourceGraphic"
|
||||
id="feColorMatrix9" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix28" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix29"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="color2"
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter10"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="fbSourceGraphic"
|
||||
id="feColorMatrix10" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix30" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix31"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="color2"
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter11"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1"
|
||||
height="1">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="fbSourceGraphic"
|
||||
id="feColorMatrix11" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix32" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix33"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.21 -0.72 -0.07 2 0 "
|
||||
result="color2"
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata8650">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(52.301544,180.70697)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427;filter:url(#filter11)"
|
||||
x="12.534395"
|
||||
y="-108.03511"
|
||||
id="text5070-2-2-9-9"><tspan
|
||||
id="tspan5068-0-3-36-9"
|
||||
x="12.534395"
|
||||
y="-108.03511"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke-width:1.16427">0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427;filter:url(#filter10)"
|
||||
x="142.53439"
|
||||
y="-118.03511"
|
||||
id="text5070-2-2-9-9-1"><tspan
|
||||
id="tspan5068-0-3-36-9-3"
|
||||
x="142.53439"
|
||||
y="-118.03511"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke-width:1.16427">4</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427;filter:url(#filter9)"
|
||||
x="-47.465607"
|
||||
y="-148.03511"
|
||||
id="text5070-2-2-9-9-7"><tspan
|
||||
id="tspan5068-0-3-36-9-6"
|
||||
x="-47.465607"
|
||||
y="-148.03511"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke-width:1.16427">2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427;filter:url(#filter8)"
|
||||
x="52.534393"
|
||||
y="-168.0351"
|
||||
id="text5070-2-2-9-9-6"><tspan
|
||||
id="tspan5068-0-3-36-9-4"
|
||||
x="52.534393"
|
||||
y="-168.0351"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke-width:1.16427">1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427;filter:url(#filter7)"
|
||||
x="92.534393"
|
||||
y="-48.03511"
|
||||
id="text5070-2-2-9-9-77"><tspan
|
||||
id="tspan5068-0-3-36-9-5"
|
||||
x="92.534393"
|
||||
y="-48.03511"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke-width:1.16427">3</tspan></text>
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter6)"
|
||||
id="path4517-0-8-5-8"
|
||||
cx="142.53439"
|
||||
cy="-108.03511"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5)"
|
||||
id="path4517-0-8-5-91"
|
||||
cx="52.534393"
|
||||
cy="-158.03511"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4)"
|
||||
id="path4517-0-8-5-2"
|
||||
cx="92.534393"
|
||||
cy="-38.03511"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3)"
|
||||
id="path4517-0-8-5-25"
|
||||
cx="-47.465607"
|
||||
cy="-138.03511"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter2)"
|
||||
id="path4517-0-8-5-5"
|
||||
cx="12.534393"
|
||||
cy="-98.03511"
|
||||
r="3.4908931" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 14 KiB |
171
static/images/primitive_topology_triangle_fan.svg
Normal file
|
@ -0,0 +1,171 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="169.79558"
|
||||
height="104.11718"
|
||||
viewBox="0 0 169.79558 104.11718"
|
||||
version="1.1"
|
||||
id="svg8653"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs8647">
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="DartArrow"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto-start-reverse"
|
||||
markerWidth="1"
|
||||
markerHeight="1"
|
||||
viewBox="0 0 1 1"
|
||||
preserveAspectRatio="xMidYMid">
|
||||
<path
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
transform="scale(-0.5)"
|
||||
id="path6" />
|
||||
</marker>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata8650">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(-248.0435,180.9101)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="332.53439"
|
||||
y="-78.035103"
|
||||
id="text5070-2-2-9-9-75"><tspan
|
||||
id="tspan5068-0-3-36-9-68"
|
||||
x="332.53439"
|
||||
y="-78.035103"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke-width:1.16427">0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="412.53439"
|
||||
y="-78.035103"
|
||||
id="text5070-2-2-9-9-1-4"><tspan
|
||||
id="tspan5068-0-3-36-9-3-6"
|
||||
x="412.53439"
|
||||
y="-78.035103"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke-width:1.16427">4</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="292.53439"
|
||||
y="-168.0351"
|
||||
id="text5070-2-2-9-9-7-4"><tspan
|
||||
id="tspan5068-0-3-36-9-6-3"
|
||||
x="292.53439"
|
||||
y="-168.0351"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke-width:1.16427">2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="252.53439"
|
||||
y="-78.035103"
|
||||
id="text5070-2-2-9-9-6-2"><tspan
|
||||
id="tspan5068-0-3-36-9-4-4"
|
||||
x="252.53439"
|
||||
y="-78.035103"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke-width:1.16427">1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="372.53439"
|
||||
y="-168.0351"
|
||||
id="text5070-2-2-9-9-77-2"><tspan
|
||||
id="tspan5068-0-3-36-9-5-2"
|
||||
x="372.53439"
|
||||
y="-168.0351"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke-width:1.16427">3</tspan></text>
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-8-0"
|
||||
cx="412.53439"
|
||||
cy="-98.035095"
|
||||
r="3.4908931" />
|
||||
<path
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 252.53439,-98.0351 40,-59.99999 h 80 l 40,59.99999 z m 40,-59.99999 40,59.99999 40,-59.99999"
|
||||
id="path875-4" />
|
||||
<path
|
||||
id="path1868-1"
|
||||
d="m 267.53439,-113.0351 20,-30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)" />
|
||||
<path
|
||||
id="path1870-2"
|
||||
d="m 297.53439,-143.0351 20,30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)" />
|
||||
<path
|
||||
id="path1872-1"
|
||||
d="m 317.53439,-103.0351 h -50"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)" />
|
||||
<path
|
||||
id="path1868-6-6"
|
||||
d="m 347.19583,-112.35392 20,-30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)" />
|
||||
<path
|
||||
id="path1870-4-3"
|
||||
d="m 377.19583,-142.35392 20,30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)" />
|
||||
<path
|
||||
id="path1872-0-9"
|
||||
d="m 397.19583,-102.35392 h -50"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#DartArrow)" />
|
||||
<path
|
||||
id="path1868-08-3"
|
||||
d="m 307.53439,-143.03509 20,30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#DartArrow)" />
|
||||
<path
|
||||
id="path1870-9-9"
|
||||
d="m 337.53439,-113.03509 20,-30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#DartArrow)" />
|
||||
<path
|
||||
id="path1872-2-3"
|
||||
d="m 357.53439,-153.03509 h -50"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#DartArrow)" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-3"
|
||||
cx="292.53439"
|
||||
cy="-158.03511"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-2-9"
|
||||
cx="252.53439"
|
||||
cy="-98.03511"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-2-9-7"
|
||||
cx="332.53439"
|
||||
cy="-98.03511"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-2-9-6"
|
||||
cx="372.53439"
|
||||
cy="158.03511"
|
||||
r="3.4908931"
|
||||
transform="scale(1,-1)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 10 KiB |
BIN
static/images/primitive_topology_triangle_list.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
190
static/images/primitive_topology_triangle_list.svg
Normal file
|
@ -0,0 +1,190 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="210.32816"
|
||||
height="104.11718"
|
||||
viewBox="0 0 210.32816 104.11718"
|
||||
version="1.1"
|
||||
id="svg8653"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs8647">
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker3"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto-start-reverse"
|
||||
markerWidth="1"
|
||||
markerHeight="1"
|
||||
viewBox="0 0 1 1"
|
||||
preserveAspectRatio="xMidYMid">
|
||||
<path
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
transform="scale(-0.5)"
|
||||
id="path3" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker1"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto-start-reverse"
|
||||
markerWidth="1"
|
||||
markerHeight="1"
|
||||
viewBox="0 0 1 1"
|
||||
preserveAspectRatio="xMidYMid">
|
||||
<path
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
transform="scale(-0.5)"
|
||||
id="path1" />
|
||||
</marker>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata8650">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 125.02343,22.875 40,59.999997 40,-59.999997 z"
|
||||
id="path11344" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="85.02346"
|
||||
y="102.875"
|
||||
id="text5070-2-2-9-9-75-8"><tspan
|
||||
id="tspan5068-0-3-36-9-68-4"
|
||||
x="85.02346"
|
||||
y="102.875"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="45.023403"
|
||||
y="12.87502"
|
||||
id="text5070-2-2-9-9-7-4-5"><tspan
|
||||
id="tspan5068-0-3-36-9-6-3-1"
|
||||
x="45.023403"
|
||||
y="12.87502"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="5.0234332"
|
||||
y="102.875"
|
||||
id="text5070-2-2-9-9-6-2-2"><tspan
|
||||
id="tspan5068-0-3-36-9-4-4-0"
|
||||
x="5.0234332"
|
||||
y="102.875"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">0</tspan></text>
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-9-3"
|
||||
cx="45.023403"
|
||||
cy="22.875021"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-25-0-0"
|
||||
cx="85.02346"
|
||||
cy="82.875"
|
||||
r="3.4908931" />
|
||||
<path
|
||||
id="path1868-1-8"
|
||||
d="m 20.02343,67.87502 20,-30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker3)" />
|
||||
<path
|
||||
id="path1870-2-7"
|
||||
d="m 50.02343,37.87502 20,30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker3)" />
|
||||
<path
|
||||
id="path1872-1-0"
|
||||
d="m 70.02343,77.87502 h -50"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker3)" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="125.02346"
|
||||
y="12.875005"
|
||||
id="text5070-2-2-9-9-75-8-3"><tspan
|
||||
id="tspan5068-0-3-36-9-68-4-4"
|
||||
x="125.02346"
|
||||
y="12.875005"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">3</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="165.02347"
|
||||
y="102.875"
|
||||
id="text5070-2-2-9-9-1-4-2"><tspan
|
||||
id="tspan5068-0-3-36-9-3-6-1"
|
||||
x="165.02347"
|
||||
y="102.875"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">5</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="205.02347"
|
||||
y="12.875005"
|
||||
id="text5070-2-2-9-9-77-2-4"><tspan
|
||||
id="tspan5068-0-3-36-9-5-2-0"
|
||||
x="205.02347"
|
||||
y="12.875005"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:1.16427">4</tspan></text>
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-8-0-3"
|
||||
cx="165.02347"
|
||||
cy="82.875"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-25-0-0-6"
|
||||
cx="205.02347"
|
||||
cy="22.875006"
|
||||
r="3.4908931" />
|
||||
<path
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 5.02343,82.875005 40,-59.999995 40,59.999995 z"
|
||||
id="path11342" />
|
||||
<path
|
||||
id="path1868-08-3"
|
||||
d="m 140.02344,37.875 20,30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker1)" />
|
||||
<path
|
||||
id="path1870-9-9"
|
||||
d="m 170.02344,67.875 20,-30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker1)" />
|
||||
<path
|
||||
id="path1872-2-3"
|
||||
d="m 190.02344,27.875 h -50"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker1)" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-97"
|
||||
cx="5.0234332"
|
||||
cy="82.875"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:#f9f9f9;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-3"
|
||||
cx="125.02346"
|
||||
cy="22.875006"
|
||||
r="3.4908931" />
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
202
static/images/primitive_topology_triangle_strip.svg
Normal file
|
@ -0,0 +1,202 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="170.32812"
|
||||
height="104.11719"
|
||||
viewBox="0 0 170.32813 104.11719"
|
||||
version="1.1"
|
||||
id="svg8653"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs8647">
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker2"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto-start-reverse"
|
||||
markerWidth="1"
|
||||
markerHeight="1"
|
||||
viewBox="0 0 1 1"
|
||||
preserveAspectRatio="xMidYMid">
|
||||
<path
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
transform="scale(-0.5)"
|
||||
id="path2" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker1"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto-start-reverse"
|
||||
markerWidth="1"
|
||||
markerHeight="1"
|
||||
viewBox="0 0 1 1"
|
||||
preserveAspectRatio="xMidYMid">
|
||||
<path
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
transform="scale(-0.5)"
|
||||
id="path1" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="DartArrow"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto-start-reverse"
|
||||
markerWidth="1"
|
||||
markerHeight="1"
|
||||
viewBox="0 0 1 1"
|
||||
preserveAspectRatio="xMidYMid">
|
||||
<path
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
transform="scale(-0.5)"
|
||||
id="path6" />
|
||||
</marker>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata8650">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(-7.5109558,180.91011)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="12.534393"
|
||||
y="-78.03511"
|
||||
id="text5070-2-2-9-9"><tspan
|
||||
id="tspan5068-0-3-36-9"
|
||||
x="12.534393"
|
||||
y="-78.03511"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke-width:1.16427">0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="172.53439"
|
||||
y="-78.035103"
|
||||
id="text5070-2-2-9-9-1"><tspan
|
||||
id="tspan5068-0-3-36-9-3"
|
||||
x="172.53439"
|
||||
y="-78.035103"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke-width:1.16427">4</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="92.534393"
|
||||
y="-78.035103"
|
||||
id="text5070-2-2-9-9-7"><tspan
|
||||
id="tspan5068-0-3-36-9-6"
|
||||
x="92.534393"
|
||||
y="-78.035103"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke-width:1.16427">2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="52.534393"
|
||||
y="-168.0351"
|
||||
id="text5070-2-2-9-9-6"><tspan
|
||||
id="tspan5068-0-3-36-9-4"
|
||||
x="52.534393"
|
||||
y="-168.0351"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke-width:1.16427">1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.16427"
|
||||
x="132.53439"
|
||||
y="-168.03511"
|
||||
id="text5070-2-2-9-9-77"><tspan
|
||||
id="tspan5068-0-3-36-9-5"
|
||||
x="132.53439"
|
||||
y="-168.03511"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke-width:1.16427">3</tspan></text>
|
||||
<circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-8"
|
||||
cx="172.53439"
|
||||
cy="-98.035103"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-2"
|
||||
cx="132.53439"
|
||||
cy="-158.03511"
|
||||
r="3.4908931" />
|
||||
<path
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 12.534393,-98.035106 40,-59.999994 h 79.999997 l 40,59.999994 z m 40,-59.999994 39.999997,59.999994 40,-59.999994"
|
||||
id="path875" />
|
||||
<path
|
||||
id="path1868"
|
||||
d="m 27.534393,-113.0351 20,-30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker2)" />
|
||||
<path
|
||||
id="path1870"
|
||||
d="m 57.534393,-143.0351 19.999997,30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker2)" />
|
||||
<path
|
||||
id="path1872"
|
||||
d="M 77.53439,-103.0351 H 27.534393"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker2)" />
|
||||
<path
|
||||
id="path1868-6"
|
||||
d="m 107.19584,-112.35393 20,-30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker2)" />
|
||||
<path
|
||||
id="path1870-4"
|
||||
d="m 137.19584,-142.35393 19.99999,30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker2)" />
|
||||
<path
|
||||
id="path1872-0"
|
||||
d="M 157.19583,-102.35393 H 107.19584"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker2)" />
|
||||
<path
|
||||
id="path1868-08-3-3"
|
||||
d="m 67.53439,-143.0351 20,30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker1)" />
|
||||
<path
|
||||
id="path1870-9-9-3"
|
||||
d="m 97.53439,-113.0351 20,-30"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker1)" />
|
||||
<path
|
||||
id="path1872-2-3-1"
|
||||
d="M 111.73438,-153.0351 H 67.53439"
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:0.940213px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#DartArrow)" />
|
||||
<circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-97"
|
||||
cx="12.872943"
|
||||
cy="-98.716286"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-97-3"
|
||||
cx="92.534393"
|
||||
cy="-98.035103"
|
||||
r="3.4908931" />
|
||||
<circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4517-0-8-5-91-0-3"
|
||||
cx="52.534393"
|
||||
cy="-158.0351"
|
||||
r="3.4908931" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
|
@ -1,18 +1,11 @@
|
|||
import { mdsvex } from 'mdsvex';
|
||||
import { mdsvex_config } from './mdsvex.config.js';
|
||||
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://svelte.dev/docs/kit/integrations
|
||||
// for more information about preprocessors
|
||||
preprocess: [
|
||||
vitePreprocess(),
|
||||
mdsvex({
|
||||
extensions: ['.md', '.svx'],
|
||||
})
|
||||
],
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
||||
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
||||
|
@ -20,7 +13,14 @@ const config = {
|
|||
adapter: adapter()
|
||||
},
|
||||
|
||||
extensions: ['.svelte', '.svx', '.md']
|
||||
extensions: ['.svelte', '.svx', '.md'],
|
||||
|
||||
// Consult https://svelte.dev/docs/kit/integrations
|
||||
// for more information about preprocessors
|
||||
preprocess: [
|
||||
vitePreprocess(),
|
||||
mdsvex(mdsvex_config)
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|