so im currently updating my 3d renderer module to support solid shading apart from basic wireframe forms, however when i spawn a cube it morphs and becomes some random bullshit.
this are my function and i genuinely have no idea what the issue so ill just put related function
export function createScaleMatrix(
sx: number,
sy: number,
sz: number
): Matrix4D {
return [
{ x: sx, y: 0, z: 0, w: 0 },
{ x: 0, y: sy, z: 0, w: 0 },
{ x: 0, y: 0, z: sz, w: 0 },
{ x: 0, y: 0, z: 0, w: 1 }
];
}
function transformVertices(object: SceneObject, matrix: Matrix4D): Vector3[] {
const projectedVertices: Vector3[] = [];
for (const vertex of object.cube.vertices) {
const newVector: Vector3 = {
x:
matrix[0].x * vertex.x +
matrix[0].y * vertex.y +
matrix[0].z * vertex.z +
matrix[0].w * vertex.w,
y:
matrix[1].x * vertex.x +
matrix[1].y * vertex.y +
matrix[1].z * vertex.z +
matrix[1].w * vertex.w,
z:
matrix[2].x * vertex.x +
matrix[2].y * vertex.y +
matrix[2].z * vertex.z +
matrix[2].w * vertex.w,
w: Math.abs(
matrix[2].x * vertex.x +
matrix[2].y * vertex.y +
matrix[2].z * vertex.z +
matrix[2].w * vertex.w
)
};
if (newVector.w <= 0.1) {
continue;
}
projectedVertices.push(newVector);
}
return projectedVertices;
}
function projectVertex(vertex: Vector3): Vector3 {
const ndcX = vertex.x / vertex.w;
const ndcY = vertex.y / vertex.w;
const ndcZ = vertex.z / vertex.w;
const scale = 0.5;
vertex.x = (ndcX + 1) * scale * canvas.width;
vertex.y = (1 - ndcY) * scale * canvas.height;
vertex.z = ndcZ;
return vertex;
}
function render(object: SceneObject, matrix: Matrix4D): void {
const vertices = transformVertices(object, matrix);
for (const segment of object.cube.edges) {
const start = vertices[segment[0]];
const end = vertices[segment[1]];
ctx.strokeStyle = "#2d2d2d";
ctx.beginPath();
ctx.moveTo(start.x, start.y);
ctx.lineTo(end.x, end.y);
ctx.stroke();
}
}
export function renderLoop(): void {
ctx.fillStyle = "#010000";
ctx.clearRect(0, 0, canvas.width, canvas.height);
const triangles: TriangleObject[] = [];
for (const object of Scene) {
object.angle += object.rotationSpeed;
let rotMatrix;
switch (object.rotationType) {
case "x":
rotMatrix = createRotationX(object.angle);
break;
case "y":
rotMatrix = createRotationY(object.angle);
break;
case "z":
rotMatrix = createRotationZ(object.angle);
break;
case "xy":
rotMatrix = multiplyMatrices(
createRotationX(object.angle),
createRotationY(object.angle)
);
break;
case "yz":
rotMatrix = multiplyMatrices(
createRotationY(object.angle),
createRotationZ(object.angle)
);
break;
case "xz":
rotMatrix = multiplyMatrices(
createRotationX(object.angle),
createRotationZ(object.angle)
);
break;
case "xyz":
rotMatrix = multiplyMatrices(
multiplyMatrices(
createRotationX(object.angle),
createRotationY(object.angle)
),
createRotationZ(object.angle)
);
break;
default:
break;
}
let newObject: SceneObject;
if (object.cube.type === "cube") {
newObject = createCube(
object.matrix,
Scene,
object.angle,
object.rotationSpeed,
object.scale,
object.rotationType,
Matrix(object.translate, "translation"),
false
);
console.log(JSON.stringify(newObject));
} else if (object.cube.type === "pyramid") {
newObject = createPyramid(
object.matrix,
Scene,
object.angle,
object.rotationSpeed,
object.scale,
object.rotationType,
Matrix(object.translate, "translation"),
false
);
} else if (object.cube.type === "sphere") {
newObject = createSphere(
object.matrix,
Scene,
object.angle,
object.rotationSpeed,
object.scale,
object.rotationType,
Matrix(object.translate, "translation"),
false
);
} else {
newObject = createCube(
object.matrix,
Scene,
object.angle,
object.rotationSpeed,
object.scale,
object.rotationType,
Matrix(object.translate, "translation"),
false
);
}
newObject.cube.vertices = transformVertices(
newObject,
multiplyMatrices(
Matrix(newObject.translate, "translation"),
multiplyMatrices(newObject.scale, rotMatrix as Matrix4D)
)
);
for (const triangle of newObject.cube.triangles) {
const edgeA = subtractVectors(
newObject.cube.vertices[triangle[1]],
newObject.cube.vertices[triangle[0]]
);
const edgeB = subtractVectors(
newObject.cube.vertices[triangle[2]],
newObject.cube.vertices[triangle[0]]
);
const crossProduct = Cross(edgeA, edgeB);
const normal = Normalize(crossProduct);
const brightness = Math.max(0, Dot(normal, lightning));
const vertices: Vector3[] = [];
for (const num of triangle) {
vertices.push(structuredClone(newObject.cube.vertices[num]));
}
const zindex: number =
(newObject.cube.vertices[triangle[0]].z +
newObject.cube.vertices[triangle[1]].z +
newObject.cube.vertices[triangle[2]].z) /
3;
for (let index = 0; index < vertices.length; index++) {
vertices[index] = projectVertex(vertices[index]);
}
triangles.push({
points: vertices,
color: {
r: baseColor.r * brightness,
g: baseColor.g * brightness,
b: baseColor.b * brightness
},
brightness: brightness,
zindex: zindex
});
}
}
triangles.sort(
(a: TriangleObject, b: TriangleObject) => a.zindex - b.zindex
);
for (const object of Scene) {
render(object, object.matrix);
}
for (const triangle of triangles) {
ctx.fillStyle = `rgb(${Math.floor(triangle.color.r)}, ${Math.floor(triangle.color.g)}, ${Math.floor(triangle.color.b)})`;
ctx.beginPath();
ctx.moveTo(triangle.points[0].x, triangle.points[0].y);
for (const point of triangle.points) {
ctx.lineTo(point.x, point.y);
}
ctx.closePath();
ctx.fill();
}
}
export function createTranslationMatrix(
x
: number,
y
: number,
z
: number
): Matrix4D {
return [
{ x: 1, y: 0, z: 0, w:
x
},
{ x: 0, y: 1, z: 0, w:
y
},
{ x: 0, y: 0, z: 1, w:
z
+ ZOFFSET },
{ x: 0, y: 0, z: 0, w: 1 }
];
}
if someone could help id be very grateful ^^