projection - 倾斜透视 - 处理中的投影矩阵

标签 projection perspective processing projection-matrix

我想扩展处理,以便能够使用倾斜投影(内阁或骑士)渲染 3D 内容。在查看了camera()、perspective()和ortho()方法的源代码之后,我能够设置正交透视,然后将PGraphics3D#camera矩阵调整为适当的值,并取得了部分成功。

void setup() {
   camera(30, 30, 30, 0, 0, 0, 1, 1, 0);
   ortho(-100, 100, -100, 100, -500, 500);
   p3d.camera.set(1, 0, -0.433f, 0, 0, 1, 0.25f, 0, 0, 0, 0, 0, 0, 0, 0, 1);
}

void draw() {
   box(20);
}

这会产生正确的视角,但没有表面填充。当删除相机和正交方法调用或两者时,屏幕是空的,尽管我希望相机(...)在稍后被覆盖的同一矩阵上进行操作。

此外,我对 PGraphics3D 中的矩阵有点困惑:相机、模型 View 和投影。虽然 OpenGL 保留两个矩阵堆栈 - modelView 和投影,但这里有第三个矩阵堆栈 - 相机。谁能阐明这些矩阵之间的区别和关系?

这对于了解何时使用/设置哪个很有帮助。

最佳答案

好问题!

我按照您的方式运行了以下代码,它看起来像一个白色立方体的等角 View 。

1: size(300,300,P3D);
2: camera(30, 30, 30, 0, 0, 0, 1, 1, 0);
3: ortho(-100, 100, -100, 100, -500, 500);
4: PGraphics3D p3d = (PGraphics3D)g;
5: p3d.camera.set(1, 0, -0.433f, 0, 0, 1, 0.25f, 0, 0, 0, 0, 0, 0, 0, 0, 1);
6: box(20);

这是发生的事情:

  • 第 2 行:设置相机模型 View 矩阵
  • 第 3 行:设置投影矩阵
  • 第 4 行:仅设置相机矩阵,但实际上这里没有执行任何操作。 (继续阅读)

仅使用模型 View 投影矩阵执行转换。 相机矩阵只是模型 View 通常初始化的一个方便的分离。

如果您使用了draw()函数,则在每次调用之前,modelview矩阵实际上会被初始化为camera矩阵。由于您没有使用draw()函数,因此您的相机矩阵从未使用相机矩阵中的倾斜变换进行更新。


如何创建倾斜投影

作为免责声明,您必须真正理解如何使用矩阵来转换坐标。顺序非常重要。这是一个很好的学习资源: http://glprogramming.com/red/chapter03.html

我能给出的最快解释是,模型 View 矩阵将对象坐标转换为相对眼睛坐标,然后投影 矩阵获取这些眼睛坐标并将它们转换为屏幕坐标。因此,您需要在转换为屏幕坐标之前应用倾斜投影。

这是一个可运行的示例,用于创建显示一些立方体的橱柜投影:

void setup()
{
  strokeWeight(2);
  smooth();
  noLoop();

  size(600,600,P3D);
  oblique(radians(60),0.5);
}

void draw()
{
  background(100);

  // size of the box
  float w = 100;

  // draw box in the middle
  translate(width/2,height/2);
  fill(random(255),random(255),random(255),100);
  box(w);

  // draw box behind
  translate(0,0,-w*4);
  fill(random(255),random(255),random(255),100);
  box(w);

  // draw box in front
  translate(0,0,w*8);
  fill(random(255),random(255),random(255),100);
  box(w);
}

void oblique(float angle, float zscale)
{
  PGraphics3D p3d = (PGraphics3D)g;

  // set orthographic projection
  ortho(-width/2,width/2,-height/2,height/2,-5000,5000);

  // get camera's z translation
  // ... so we can transform from the original z=0
  float z = p3d.camera.m23;

  // apply z translation
  p3d.projection.translate(0,0,z);

  // apply oblique projection 
  p3d.projection.apply(
    1,0,-zscale*cos(angle),0,
    0,1,zscale*sin(angle),0,
    0,0,1,0,
    0,0,0,1);

  // remove z translation
  p3d.projection.translate(0,0,-z);
}

screenshot of oblique projection in processing

关于projection - 倾斜透视 - 处理中的投影矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4660086/

相关文章:

qt - 创建 QTransform 给定 4 个定义变换单位正方形的点

java - 将纬度和经度值转换为自定义大小的网格

.net - 类型投影有相反的,还是仍然是投影(或只是映射)?

php - 使用 3D 透视预览打印 Canvas 包装

java - 从 Eclipse 插件在后台打开 Perspective

java - 找不到类 FileNameExtensionFilter

java - 对形状进行分组,以便我可以通过单击鼠标循环浏览它们 - 处理和 java

audio - 如何访问来自正在播放的电影的音频输出?

ios - 修改相机的透视投影

opencv - 3d 点投影 2d 点错误