Thursday, June 7, 2012

Projecting Complex Faces with Gladius / CubicVR.js

‹prev | My Chain | next›

Last night I found another aspect of UV mapping in Gladius that managed to confuse me. This time around, it was projecting a square image:



I had expected a projection onto a triangle to somehow squish the entire image into the triangle. Instead, I just got three corners projected onto the triangle. I can certainly understand why it works that way, but it begs the question: what happens when I try to project a square image onto a shape with more than four sides?

I am still working a pyramid shape, so I will add another point to the base:
    points: [
      [ point, 0,      0],
      [ point, point,  0],
      [ 0,     point,  0],
      [-point, 0,      0],
      [ 0,    -point,  0],
      [ 0,     0,      1.5*point]
    ],
Adding a point does nothing unless the faces built from points include them, so I have to add a fifth point to the bottom face (I also have to add a fifth triangle to the top):
    faces: [
      [4, 3, 2, 1, 0],
      [0, 1, 5],
      [1, 2, 5],
      [2, 3, 5],
      [3, 4, 5],
      [4, 0, 5]
    ],
As for the UV mapping, the bottom square had been easy enough. Just like points around an X-Y Cartesian system, I move from the origin at (0,0) around the positive ones: [ [0, 1], [1, 1], [1, 0], [0, 0] ]. For the triangles, I simply picked three coordinates: [ [1, 0], [0, 0], [0, 1] ]. But what to pick for a pentagon?

I try different variations of five points: [ [0, 0.5], [0, 1], [1, 1], [1, 0], [0, 0] ], [ [0, 0], [0, 1], [1, 1], [1, 0], [0, 0] ], etc. But the five point projection mappings all result no bottom face:



Even if I try just four project points, I still get no base on my five-sided pyramid. In the end, I can find no other recourse than to define two faces on the bottom: a triangle and a square:
    faces: [
      [4, 3, 2, 1],
      [1, 0, 4],
      [0, 1, 5],
      [1, 2, 5],
      [2, 3, 5],
      [3, 4, 5],
      [4, 0, 5]
    ],
The UV mapping for those first two points then become a four-pointer and a three-pointer:
    uv: [
      [ [1, 0], [0, 0], [0, 1], [1, 1] ],
      [ [1, 0], [0, 0], [0, 1] ],
      [ [1, 0], [0, 0], [0, 1] ],
      [ [1, 0], [0, 0], [0, 1] ],
      [ [1, 0], [0, 0], [0, 1] ],
      [ [1, 0], [0, 0], [0, 1] ],
      [ [1, 0], [0, 0], [0, 1] ]
    ],
And, with that, I have a solid face on the bottom of my five-sided "pyramid":



For reference, all of this is in the "procedural mesh", which looks like:
function proc( options ) {

  options = options || {};
  options.size = options.size || 1.0;
  var point = options.size / 2.0;

  var mesh =
  {
    points: [ /* ... */ ],
    faces: [ /* ... */ ],
    uv: [ /* ... */ ],
    // wireframe: true,
    uvmapper: {
      projectionMode: "cubic",
      scale: [1, 1, 1]
    }
  };

  return mesh;
}
And my "procedural material":
function proc( options ) {
  return {
    textures: {
      color: '/images/rygb.png'
    },
    opacity: 1.0
  };
}
In the end, I cannot project onto a shape more complex than a square. In other words, anything more complex than a square has to be assembled from a combination of squares and triangles. That is definitely useful information to know.

I will call it a night here. Up tomorrow, I think I will examine the projectionMode setting in uvmapper. None of this is feeling very "cubic" and initial experiments suggest that I am, in fact, doing "planar" projection instead. But I'll figure that out tomorrow.


Day #410

No comments:

Post a Comment