Skip to content

Commit 626dfa9

Browse files
committed
Added geometry normalization for imported vertices
1 parent e91435b commit 626dfa9

4 files changed

Lines changed: 40 additions & 26 deletions

File tree

devlog.md

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
And let there be light!
1+
Our graphics engine is done!
22

3-
Simulating light is the single thing that graphics programming (and hardware!) has been developing towards in the past few decades or so. This is because, in the real world, light behaves in a very complicated manner, of which only the great GPU that runs the universe can render, so we can only ever approximate how it truly behaves. You may have heard the terms _raytracing_ or _raymarching_ before, and those are just that: approximations of how light behaves.
3+
Or as done as it can be, really. A true graphics engine would have many other things: textures, multicolored meshes, fragment shaders, interpolation and many other things that are a consequence of the literal decades put into developing this area. It is, however, _good enough_, when you take into account the limitations that svg imposes upon us.
44

5-
For our (very limited) graphics engine though, we have to do just the basics: get the color of vertex after being under the effect of multiple punctual lights. This is a task with many steps:
5+
First things first, a careful eye might have noticed that the last rendering scene missed a certain 'reflection' you get from illuminating most objects. Think of the litte white spot you see in a billiard ball when it's put against a light source - this is something that emerges naturally whenever you have a reflective surface, because it's just a result of light reflecting on it and going directly to your eyes.
6+
To make our rendered meshes have the same effect, we implement something called the Phong reflection model, which is the "algorithm" (or, to better put it, formulas) to calculate the light that'll go to our eyes. This is a relatively expensive operation (involves exponentiating by 64), so I left it as an optinal feature, per object.
67

7-
First, we have to figure out where each one of our vertices are pointing. This is called a _normal_, and we use to find what the intensity of the light shining on a face will have. Logically this is a factor: if you hold your phone against the sun, the side facing it will be bright, and the one facing _you_ won't.
8-
Then, we have to figure out the resulting light on a vertex. This is **additive**: we just have to sum all the incoming lights and intensities into one. Then, we have to take into account the object's original color for the resulting color: this is **multiplicative**
9-
The final step is drawing these colors into the screen. Usually, we'd take the colored vertices for each triangle and interpolate them, but this is impossible in svg: we have to assign each face a single color. We do this by taking the average of each vertex.
10-
11-
This implies more memory usage to store everything needed: meshes, colors, lights, etc. So, as usual, a complete refactor of `Scene` to make it easier to use.
12-
Attached: the lights!
8+
Second, and the reason that I'm saying that the engine is "complete", is that we can now just read data from an `.obj` file and it will be rendered to the screen (after I wrote the parser for it, of course).
9+
We can render meshes with a surprisingly high number of triangles with this method. I could, (running at around ~3 fps), render a model of the Eiffel Tower with over 400k triangles!
10+
Attached, renders of some more complex 3D models!
1311

1412
**Commits**
15-
[795addc](https://url.jam06452.uk/1dmb9jx): Added lighting
16-
[b7ce605](https://url.jam06452.uk/1dsik8b): Added normals
17-
[1c48364](https://url.jam06452.uk/i83mp3): Lighting almost finished
18-
[0324cd9](https://url.jam06452.uk/rstls4): Lighting working!
13+
[Commit 9b2fdb3](https://github.com/Sekqies/native-html-images/commit/9b2fdb380168e8b45290ce3911ab5e9e0c30f234): Added specular lighting
14+
[Commit e91435b](https://github.com/Sekqies/native-html-images/commit/e91435b7ee373333b1a42de204adcc528b3571d7): Adedd obj parsing

index.html

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@
3434
<p>Want to import your own data? Do it through here (obj file type accepted)</p>
3535
<input type="file" id="file-picker"/>
3636

37-
<svg
38-
width="400px"
39-
height="300px"
40-
viewBox="-1 -1 2 2"
41-
preserveAspectRatio="none"
42-
stroke-width ="0.01"
43-
id="model-preview-container"
44-
shape-rendering ="optimizeSpeed"
45-
>
46-
</svg>
37+
<svg
38+
width="400px"
39+
height="300px"
40+
viewBox="-1 -1 2 2"
41+
preserveAspectRatio="none"
42+
stroke-width ="0.01"
43+
id="model-preview-container"
44+
shape-rendering ="optimizeSpeed"
45+
>
46+
</svg>
4747

4848

4949
</body>

src/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export function main_3d() {
137137
scene.meshes[i].update_normals(models[i]);
138138
}
139139

140-
process_world_coordinates(scene, models);
140+
process_world_coordinates(scene, models, camera_pos);
141141
render_scene(scene, mvps, true);
142142

143143
const frame_html = build_scene(scene, do_wireframe, string_buffer);
@@ -170,7 +170,7 @@ function render_preview(geo: Geometry) {
170170
if (preview_animation_id !== null) {
171171
cancelAnimationFrame(preview_animation_id);
172172
}
173-
173+
console.log(geo.vertices);
174174
const target = document.getElementById('model-preview-container');
175175
if (!target) return;
176176

src/utils/parser.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ArrayType, IndexingType } from "../math/types";
1+
import { ArrayType, IndexingType, vec3 } from "../math/types";
22
import { Geometry } from "../rendering/types/geometry";
33

44
function center_geometry(geo: Geometry): void {
@@ -29,6 +29,23 @@ function center_geometry(geo: Geometry): void {
2929
}
3030
}
3131

32+
function normalize_geometry(geo:Geometry): void {
33+
let max = -Infinity;
34+
for(let i = 0; i < geo.vertices.length; i+=3){
35+
max = Math.max(max,geo.vertices[i])
36+
max = Math.max(max,geo.vertices[i+1])
37+
max = Math.max(max,geo.vertices[i+2])
38+
}
39+
if(max===0){
40+
max = 1;
41+
}
42+
for(let i = 0; i < geo.vertices.length; i+=3){
43+
geo.vertices[i] /= max;
44+
geo.vertices[i+1] /= max;
45+
geo.vertices[i+2] /= max;
46+
}
47+
}
48+
3249

3350

3451
export function parse_obj(file:string):Geometry{
@@ -79,5 +96,6 @@ export function parse_obj(file:string):Geometry{
7996
}
8097
const geo = new Geometry(vertices,indices);
8198
center_geometry(geo);
99+
normalize_geometry(geo);
82100
return geo;
83101
}

0 commit comments

Comments
 (0)