Skip to content

Commit 06e157a

Browse files
committed
Finished Scene logic
1 parent eaaa1ea commit 06e157a

8 files changed

Lines changed: 46 additions & 41 deletions

File tree

src/main.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { mat4, vec3 } from "./math/types";
22
import { perspective, identity, look_at, rotate, translate } from "./math/transformations";
33
import { create_sphere } from "./rendering/primitives";
4-
import { build_mesh, build_meshes } from "./rendering/render";
4+
import { build_mesh, render_scene } from "./rendering/render";
55
import { StringBuffer } from "./utils/string_buffer";
6+
import { Mesh } from "./rendering/mesh";
7+
import { Scene } from "./rendering/scene";
8+
import { mul_mat4 } from "./math/matrix_operators";
69

710

811
export function main_3d() {
@@ -12,23 +15,33 @@ export function main_3d() {
1215
const do_wireframe:boolean = wireframe_el?.checked;
1316
const sun_mesh = create_sphere(1.5, 16, 16);
1417
const planet_mesh = create_sphere(0.5, 12, 12);
18+
19+
const scene:Scene = new Scene([sun_mesh.vertices,planet_mesh.vertices],[sun_mesh.indices,planet_mesh.indices]);
20+
21+
22+
1523
const y = vec3(0,1,0);
1624
const view:mat4 = look_at(vec3(0,2,6.5),vec3(0,0,0),y);
1725
const projection = perspective(60 * Math.PI / 180, 400/300, 0.1, 100);
1826
let time = 0;
1927
const string_buffer = new StringBuffer(1024*1024);
28+
const vp = mul_mat4(projection,view);
2029
const loop = () => {
2130
time += 0.01;
2231

2332
let frame_html = "";
2433
let sun_model = identity();
2534
sun_model = rotate(sun_model, time * 0.5, y);
26-
frame_html += build_mesh(sun_mesh, sun_model,view,projection,string_buffer,do_wireframe,true);
2735
let planet_model = identity();
2836
planet_model = rotate(planet_model, time, vec3(0, 1, 0));
2937
planet_model = translate(planet_model, vec3(3.5, 0, 0));
3038
planet_model = rotate(planet_model, time * 3, vec3(1, 0, 1));
31-
frame_html += build_meshes([sun_mesh,planet_mesh],[sun_model,planet_model],[view,view],[projection,projection],string_buffer,do_wireframe,true);
39+
40+
const planet_mvp = mul_mat4(planet_model,vp);
41+
const sun_mvp = mul_mat4(sun_model,vp);
42+
43+
render_scene(scene,[sun_mvp,planet_mvp],true);
44+
3245
target!.innerHTML = frame_html;
3346
requestAnimationFrame(loop);
3447
}

src/rendering/depth_sorting.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +0,0 @@
1-
import type { Mesh } from "./mesh";
2-
3-
4-
export function depth_sort(mesh: Mesh, stride: number = 4): number {
5-
const projected = mesh.projected_buffer;
6-
const raster = mesh.raster_buffer;
7-
const indices = mesh.indices;
8-
const num_triangles = indices.length / 3;
9-
let visible_count = 0;
10-
11-
for (let i = 0; i < num_triangles; i++) {
12-
const i0 = indices[i * 3] * stride;
13-
const i1 = indices[i * 3 + 1] * stride;
14-
const i2 = indices[i * 3 + 2] * stride;
15-
16-
const z_avg = (projected[i0 + 2] + projected[i1 + 2] + projected[i2 + 2]) / 3;
17-
18-
raster[i] = z_avg;
19-
mesh.draw_order[visible_count] = i;
20-
visible_count++;
21-
}
22-
23-
return visible_count;
24-
}

src/rendering/mesh.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export class Mesh{
66
indices: IndexingType
77
projected_buffer: ArrayType
88
raster_buffer: ArrayType
9-
draw_order:IndexingType
109
raster_end:number
1110
visible_triangles_count:number
1211

@@ -18,7 +17,6 @@ export class Mesh{
1817
this.raster_buffer = new ArrayType(indices.length * 4);
1918
else
2019
this.raster_buffer = raster_buffer;
21-
this.draw_order = new IndexingType(indices.length);
2220
this.raster_end = indices.length * 4;
2321
this.visible_triangles_count = 0;
2422
}

src/rendering/primitive_assembler.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { depth_sort } from "./depth_sorting";
21
import type { Mesh } from "./mesh";
32

43
/**
@@ -7,16 +6,13 @@ import type { Mesh } from "./mesh";
76
* @param stride
87
*/
98
export function assemble_primitives(mesh:Mesh):void{
10-
const visible_count = depth_sort(mesh);
119
const projected = mesh.projected_buffer;
1210
const indices = mesh.indices;
13-
const order = mesh.draw_order;
1411

1512
const out = mesh.raster_buffer
1613
let out_index = 0;
17-
for(let i = 0; i < visible_count; ++i){
18-
const index = order[i];
19-
14+
for(let i = 0; i < indices.length; ++i){
15+
const index = indices[i];
2016
const v1 = indices[index * 3] * 4;
2117
const v2 = indices[index * 3 + 1] * 4;
2218
const v3 = indices[index * 3 + 2] * 4;
@@ -36,5 +32,4 @@ export function assemble_primitives(mesh:Mesh):void{
3632
out[out_index++] = projected[v3 + 2];
3733
out[out_index++] = projected[v3 + 3];
3834
}
39-
mesh.visible_triangles_count = visible_count;
4035
}

src/rendering/primitives.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ArrayType, IndexingType } from "../math/types";
22
import { Mesh } from "./mesh";
33

4-
export function create_sphere(radius: number, rings: number, slices: number):Mesh {
4+
export function create_sphere(radius: number, rings: number, slices: number):{vertices:ArrayType, indices: IndexingType} {
55
const vertice_count = (rings + 1) * (slices + 1) * 3;
66
const vertices = new ArrayType(vertice_count);
77
const indices = new IndexingType(rings * slices * 6);
@@ -40,5 +40,5 @@ export function create_sphere(radius: number, rings: number, slices: number):Mes
4040
indices[ind_i++] = first + 1
4141
}
4242
}
43-
return new Mesh(vertices,indices);
43+
return {vertices:vertices, indices: indices};
4444
}

src/rendering/rasterizer.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,15 @@ export function rasterize(mesh:Mesh, invert_y:boolean = true, stride:number = 4)
3535

3636
const x1 = n1[0];
3737
const y1 = n1[1] * sign;
38+
const z1 = n1[2];
3839

3940
const x2 = n2[0];
4041
const y2 = n2[1] * sign;
42+
const z2 = n2[2];
4143

4244
const x3 = n3[0];
4345
const y3 = n3[1] * sign;
46+
const z3 = n3[2];
4447

4548
const area = (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1);
4649

@@ -54,12 +57,15 @@ export function rasterize(mesh:Mesh, invert_y:boolean = true, stride:number = 4)
5457

5558
out[out_index++] = x1;
5659
out[out_index++] = y1;
57-
60+
out[out_index++] = z1;
61+
5862
out[out_index++] = x2;
5963
out[out_index++] = y2;
64+
out[out_index++] = z2;
6065

6166
out[out_index++] = x3;
6267
out[out_index++] = y3;
68+
out[out_index++] = z3;
6369
}
6470
mesh.raster_end = out_index;
6571
}

src/rendering/render.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,27 @@ export function render(mesh: Mesh, model:mat4, view:mat4, projection:mat4, inver
1515
rasterize(mesh, invert_y, stride);
1616
}
1717

18+
function get_z_value(array:ArrayType, offset:number, z_offset:number = 2, stride:number = 3){
19+
return (array[offset + z_offset] + array[offset + z_offset + stride] + array[offset + z_offset + stride*2]);
20+
}
21+
1822
export function render_scene(scene:Scene, mvp:mat4[], invert_y:boolean = true){
1923
for(let i = 0; i < scene.meshes.length; ++i){
2024
const mesh = scene.meshes[i];
2125
transform_vertices(mesh,mvp[i]);
2226
assemble_primitives(mesh);
2327
rasterize(mesh,invert_y);
2428
}
29+
let index = 0;
30+
let offset = 0;
31+
for(const mesh of scene.meshes){
32+
for(let i = 0; i < mesh.raster_end; i+=9){
33+
scene.draw_order[index] = i + offset;
34+
index++;
35+
}
36+
offset += mesh.raster_buffer.length;
37+
}
38+
scene.draw_order.subarray(0,index).sort((a,b)=>get_z_value(scene.scene_buffer,a) - get_z_value(scene.scene_buffer,b));
2539
}
2640

2741

src/rendering/scene.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { ArrayType, type IndexingType } from "../math/types";
1+
import { ArrayType, IndexingType } from "../math/types";
22
import { Mesh } from "./mesh";
33

44
export class Scene{
55
scene_buffer:ArrayType;
6+
draw_order: IndexingType;
67
meshes:Mesh[];
78

89
constructor(vertices:ArrayType[], indices:IndexingType[]){
@@ -16,10 +17,12 @@ export class Scene{
1617
index_size += indices[i].length;
1718
}
1819
this.scene_buffer = new ArrayType(index_size * 4);
20+
this.draw_order = new IndexingType(vert_size/3);
1921
this.meshes = new Array(vertices.length);
2022
let prev_length = 0;
2123
for(let i = 0; i < vertices.length; ++i){
22-
this.meshes[i] = new Mesh(vertices[i],indices[i],this.scene_buffer.subarray(prev_length,indices[i].length*4));
24+
this.meshes[i] = new Mesh(vertices[i],indices[i],this.scene_buffer.subarray(prev_length,prev_length + indices[i].length*4));
25+
prev_length += indices[i].length * 4;
2326
}
2427
}
2528
resize(size:number){

0 commit comments

Comments
 (0)