开发者

Oblique perspective - projection matrizes in processing

I want to extend processing in order to be able to render 3D stuff with oblique projections (cabinet or cavalier). After looking around source of the camera(), perspective() and ortho() methods I was able to set up an orthographic perspective and then adjust the PGraphics3D#camera matrix to an appropriate value with partial success.

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);
}

This results in the right perspective, but without surface filling. When removing either the camera and ortho method calls or both, the screen is empty, although I'd expect camera(...) to operate on the same matrix that is overwritten later on.

Moreover I'm a little bit confused about the matrizes in PGraphics3D: camera, modelView and projection. While OpenGL keeps two matrix stacks - modelView and projection, here is a third one - camera. Can anybody shed some light on the difference and relation between these matrizes?

This would be helpful in order to know when to use/set 开发者_StackOverflow社区which one.


Great question!

I ran the following code as you had it, and it looked like an isometric view of a white cube.

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);

Here's what's happening:

  • Line 2: sets both the camera and modelview matrices
  • Line 3: sets the projection matrix
  • Line 4: sets the camera matrix only, but this actually did nothing here. (read on)

Transformations are only performed using the modelview and projection matrices. The camera matrix is merely a convenient separation of what the modelview is usually initialized to.

If you used the draw() function, the modelview matrix is actually initialized to the camera matrix before each time it is called. Since you didn't use the draw() function, your camera matrix was never updated with your oblique transform in your camera matrix.


How to create an Oblique Projection

As a disclaimer, you must truly understand how matrices are used to transform coordinates. Order is very important. This is a good resource for learning it: http://glprogramming.com/red/chapter03.html

The quickest explanation I can give is that the modelview matrix turns object coordinates into relative eye coordinates, then the projection matrix takes those eye coordinates and turns them in to screen coordinates. So you want to apply the oblique projection before the transformation into screen coordinates.

Here's a runnable example for creating a cabinet projection that displays some cubes:

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);
}

Oblique perspective - projection matrizes in processing

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜