javascript - 自定义 3D 引擎中的不稳定投影
问题描述
今天我一直在尝试使用 JavaScript 组装一个 3D 线框渲染引擎;请注意,我的目标是最终创建一个 Rails 射击游戏,因此相机转换对我来说还不是很重要。但是,我似乎无法让透视投影正常工作:
这是我的渲染代码,请注意我对 glMatrix 的依赖:
export default (() =>
{
const { mat4, vec3 } = glMatrix;
function line(pixels, a_x = 0, a_y = 0, b_x = 0, b_y = 0, color = 0xFF0000)
{
// Bresenham's algorithm
};
function translate(point, pos)
{
vec3.add(point, point, pos);
}
function rotate(point, pos, rot)
{
vec3.rotateX(point, point, pos, rot[0]);
vec3.rotateY(point, point, pos, rot[1]);
vec3.rotateZ(point, point, pos, rot[2]);
};
function transform(point, pos, rot)
{
translate(point, pos);
rotate(point, pos, rot);
};
return {
Camera: class
{
constructor(pos, fudge)
{
/* Unused
this.pos = pos;
this.rot = [0, 0, 0]; */
this.fudge = fudge;
}
fudged(p)
{
return this.fudge / (p[2] + this.fudge);
}
},
Model: class
{
constructor(verts, edges, faces)
{
this.faces = faces;
this.edges = edges;
this.verts = verts;
this.pos = [0, 0, 0];
this.rot = [0, 0, 0];
this.scale = [1, 1, 1];
}
render(camera, pixels)
{
for (const face of this.faces)
{
for (const index of face.edges)
{
const edge = this.edges[index];
const a = [...this.verts[edge.verts[0]]];
const b = [...this.verts[edge.verts[1]]];
transform(a, this.pos, this.rot);
transform(b, this.pos, this.rot);
const a_p = camera.fudged(a);
const b_p = camera.fudged(b);
line(pixels, a[0] * a_p, a[1] * a_p, b[0] * b_p, b[1] * b_p, edge.color);
}
}
}
},
};
})();
这是设置场景的代码:
import Wireframe from './wireframe.js';
export default function main()
{
const canvas = document.querySelector `canvas`;
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
const ctx = canvas.getContext('2d');
const camera = new Wireframe.Camera([canvas.width / 2, canvas.height / 2, 200], canvas.width);
const model = new Wireframe.Model(
[ // Verts
[-50, -50, 50], [50, -50, 50],
[50, 50, 50], [-50, 50, 50],
[50, 50, -50], [-50, 50, -50],
[-50, -50, -50], [50, -50, -50]],
[ // Edges
{ color: 0xFFC800, verts: [0, 1] },
{ color: 0x20C8FF, verts: [1, 2] },
{ color: 0x00C800, verts: [2, 3] },
{ color: 0xC82020, verts: [3, 0] },
{ color: 0xFFC800, verts: [3, 5] },
{ color: 0x20C8FF, verts: [5, 6] },
{ color: 0x00C800, verts: [6, 0] },
{ color: 0xC82020, verts: [0, 3] },
{ color: 0xFFC800, verts: [4, 5] },
{ color: 0x20C8FF, verts: [5, 6] },
{ color: 0x00C800, verts: [6, 7] },
{ color: 0xC82020, verts: [7, 4] }],
[ // Faces
{ edges: [0, 1, 2, 3] },
{ edges: [4, 5, 6, 7] },
{ edges: [8, 9, 10, 11] }]);
model.pos = [canvas.width / 2, canvas.height / 2, 0];
const draw = (() =>
{
return mil =>
{
window.requestAnimationFrame(draw);
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
const pixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
model.render(camera, pixels);
model.rot[1] += 0.01;
ctx.putImageData(pixels, 0, 0);
};
})();
window.requestAnimationFrame(draw);
};
感谢您提供任何帮助,谢谢。
解决方案
推荐阅读
- javascript - How can I collect data on all BrowserWindows synchronuously in Electron?
- python - Annotate point on axes with automatic tick formatting in matplotlib?
- android - 在 Google 地图中使用 dragListener 可编辑多个多边形
- linux - 无法运行编译的 go 文件
- php - POST 请求中的 Symfony 正文表单数据为空
- nginx - 无法通过子域上的反向代理访问父目录
- powershell - PowerShell - 测试 TXT/CSV 文件中的多个 URL 并将 HTTP 代码记录到 CSV 文件中以进行报告
- pandas - 如何根据每行中的列值数量删除异常值
- mysql - 字段列表中的未知表?
- javascript - Wordpress:如何在 html 正文中使用 javascript 变量