Anonymous
Перспективное преобразование прерывается при крайних значениях Z.
Сообщение
Anonymous » 26 ноя 2025, 08:40
Ниже представлен мой 3D-рендерер, написанный на данный момент на HTML и JavaScript. На данный момент я исправил многие недостатки и, наконец, добился рендеринга более-менее нормального куба, но когда значения Z становятся высокими, перспектива нарушается. Кто-нибудь знает, что здесь происходит? Я инвертировал деление из примера из Википедии, но без этого оно вообще не похоже на куб.
Код: Выделить всё
class Point2D {
constructor(x, y) {
this.x = x;
this.y = y;
}
};
class Point3D {
constructor(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
}
class Camera {
constructor() {
this.position = new Point3D(0, 0, -5);
this.rotation = new Point3D(0, 0, 0);
}
}
var pressedKeys = {};
window.onkeyup = function(e) { pressedKeys[e.keyCode] = false; }
window.onkeydown = function(e) { pressedKeys[e.keyCode] = true; }
var camo = new Camera();
var plz = 20;
var c;
var ctx;
function project(p) {
var x0 = (p.x - camo.position.x);
var y0 = (p.y - camo.position.y);
var z0 = (p.z - camo.position.z);
var interm1 = (Math.sin(camo.rotation.z) * y0) + (Math.cos(camo.rotation.z) * x0);
var interm2 = (Math.cos(camo.rotation.z) * y0) - (Math.sin(camo.rotation.z) * x0);
var interm3 = ((Math.cos(camo.rotation.y) * z0) + (Math.sin(camo.rotation.y) * interm1));
var x = (Math.cos(camo.rotation.y) * interm1) - (Math.sin(camo.rotation.y) * z0);
var y = (Math.sin(camo.rotation.x) * interm3) + (Math.cos(camo.rotation.x) * interm2);
var z = (Math.cos(camo.rotation.x) * interm3) - (Math.sin(camo.rotation.x) * interm2);
return new Point3D((z / plz) * x * 120 + 120, (z / plz) * y * 120 + 120, 1 / z);
}
function orient2d(a, b, c) {
return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
};
function triangle(img, depf, a, b, c) {
if (a.z < 0 || b.z < 0 || c.z < 0) {
return;
}
var minx = Math.floor(Math.max(Math.min(a.x, b.x, c.x), 0));
var miny = Math.floor(Math.max(Math.min(a.y, b.y, c.y), 0));
var maxx = Math.floor(Math.min(Math.max(a.x, b.x, c.x), 239));
var maxy = Math.floor(Math.min(Math.max(a.y, b.y, c.y), 239));
var a01 = a.y - b.y;
var b01 = b.x - a.x;
var a12 = b.y - c.y;
var b12 = c.x - b.x;
var a20 = c.y - a.y;
var b20 = a.x - c.x;
var p = new Point2D(minx, miny);
var w0_row = orient2d(b, c, p);
var w1_row = orient2d(c, a, p);
var w2_row = orient2d(a, b, p);
for (p.y = miny; p.y
Подробнее здесь: [url]https://stackoverflow.com/questions/79830361/perspective-transform-breaks-at-extreme-z-values[/url]
1764135643
Anonymous
Ниже представлен мой 3D-рендерер, написанный на данный момент на HTML и JavaScript. На данный момент я исправил многие недостатки и, наконец, добился рендеринга более-менее нормального куба, но когда значения Z становятся высокими, перспектива нарушается. Кто-нибудь знает, что здесь происходит? Я инвертировал деление из примера из Википедии, но без этого оно вообще не похоже на куб. [code]class Point2D { constructor(x, y) { this.x = x; this.y = y; } }; class Point3D { constructor(x, y, z) { this.x = x; this.y = y; this.z = z; } } class Camera { constructor() { this.position = new Point3D(0, 0, -5); this.rotation = new Point3D(0, 0, 0); } } var pressedKeys = {}; window.onkeyup = function(e) { pressedKeys[e.keyCode] = false; } window.onkeydown = function(e) { pressedKeys[e.keyCode] = true; } var camo = new Camera(); var plz = 20; var c; var ctx; function project(p) { var x0 = (p.x - camo.position.x); var y0 = (p.y - camo.position.y); var z0 = (p.z - camo.position.z); var interm1 = (Math.sin(camo.rotation.z) * y0) + (Math.cos(camo.rotation.z) * x0); var interm2 = (Math.cos(camo.rotation.z) * y0) - (Math.sin(camo.rotation.z) * x0); var interm3 = ((Math.cos(camo.rotation.y) * z0) + (Math.sin(camo.rotation.y) * interm1)); var x = (Math.cos(camo.rotation.y) * interm1) - (Math.sin(camo.rotation.y) * z0); var y = (Math.sin(camo.rotation.x) * interm3) + (Math.cos(camo.rotation.x) * interm2); var z = (Math.cos(camo.rotation.x) * interm3) - (Math.sin(camo.rotation.x) * interm2); return new Point3D((z / plz) * x * 120 + 120, (z / plz) * y * 120 + 120, 1 / z); } function orient2d(a, b, c) { return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); }; function triangle(img, depf, a, b, c) { if (a.z < 0 || b.z < 0 || c.z < 0) { return; } var minx = Math.floor(Math.max(Math.min(a.x, b.x, c.x), 0)); var miny = Math.floor(Math.max(Math.min(a.y, b.y, c.y), 0)); var maxx = Math.floor(Math.min(Math.max(a.x, b.x, c.x), 239)); var maxy = Math.floor(Math.min(Math.max(a.y, b.y, c.y), 239)); var a01 = a.y - b.y; var b01 = b.x - a.x; var a12 = b.y - c.y; var b12 = c.x - b.x; var a20 = c.y - a.y; var b20 = a.x - c.x; var p = new Point2D(minx, miny); var w0_row = orient2d(b, c, p); var w1_row = orient2d(c, a, p); var w2_row = orient2d(a, b, p); for (p.y = miny; p.y Подробнее здесь: [url]https://stackoverflow.com/questions/79830361/perspective-transform-breaks-at-extreme-z-values[/url]