Loading ...
Sorry, an error occurred while loading the content.

Re: [canvas-developers] Re: Image perspective and shape reference

Expand Messages
  • Philip Taylor
    ... My memory of geometry is not entirely clear, but I believe you can t do perspective with setTransform because it only handles 2D affine transformations -
    Message 1 of 4 , Oct 30, 2006
    • 0 Attachment
      On 30/10/06, Matt Westcott <matthew@...> wrote:
      > --- In canvas-developers@yahoogroups.com, "davez1982" <davez82@...> wrote:
      >
      > > 1) Is it possible to manipulate the perspective of an image or to fill
      > > a shape in perspective?
      >
      > It ought to be possible to do that (with a bit of matrix algebra)
      > through the transform / setTransform methods, but they were only added
      > to the Canvas spec a few months back, and as a result no browsers
      > currently implement them (as far as I know).

      My memory of geometry is not entirely clear, but I believe you can't
      do perspective with setTransform because it only handles 2D affine
      transformations - parallel lines will always remain parallel. The
      transform matrix only contains six values (m11, m12, m21, m22, dx,
      dy), so it's limited to six degrees of freedom and you can only
      control the positions of three 2D points - if you're transforming a
      square, you can choose where three of its points will end up, but the
      final point will have to end up making a parallelogram, which is no
      good for distorting squares into arbitrary quadrilaterals. And it's
      not possible to get correct perspective with any kind of matrix
      transformation at all, because you need division too.

      You can cheat and make something that looks quite like perspective -
      my example at http://canvex.lazyilluminati.com/ does walls by drawing
      lots of vertical strips, progressively scaled smaller in the distance.
      (It doesn't need a huge number of strips - I used 8-pixel wide strips
      in the worst case, and fewer when there's less perspective effect, and
      it's not too obvious as long as the wall textures don't have strong
      horizontal lines.)

      That's a relatively easy case since the walls are always vertical - I
      also did some perspective-correct textured floors like
      http://canvex.lazyilluminati.com/misc/floor5.jpg by drawing thin (2
      pixel) horizontal strips, with a rotated/scaled/translated image
      pattern fill (plus some mipmapping because images normally get scaled
      down in an ugly flickery way). It works by setting the transform
      matrix such that the desired line of texture will be transformed onto
      the desired line of screen coordinates (corresponding to the current
      horizontal strip), then drawing a pattern-filled rectangle which ends
      up getting transformed to those screen coordinates; that just involves
      some maths (or experimentation and typing in random equations until it
      works).
      I think that method could support any arbitrary 3D polygon (though my
      code was limited to the requirements of my floors) - but the biggest
      problem is that it's really quite slow, because it needs lots of
      textured-rectangle-fills for each polygon, which makes it unusable in
      most practical cases.

      --
      Philip Taylor
      excors@...
    • Mathieu HENRI
      ... davez1982 ... to fill ... added ... Correct. The setTransform() method is an affine transformation in 2D space. The result would be as good (
      Message 2 of 4 , Nov 3, 2006
      • 0 Attachment
        --- In canvas-developers@yahoogroups.com, "Philip
        Taylor" <excors+yahoo@...> wrote:
        >
        > On 30/10/06, Matt Westcott <matthew@...> wrote:
        > > --- In canvas-developers@yahoogroups.com,
        "davez1982" <davez82@>
        wrote:
        > >
        > > > 1) Is it possible to manipulate the perspective of an image or
        to fill
        > > > a shape in perspective?
        > >
        > > It ought to be possible to do that (with a bit of matrix algebra)
        > > through the transform / setTransform methods, but they were only
        added
        > > to the Canvas spec a few months back, and as a result no browsers
        > > currently implement them (as far as I know).
        >
        > My memory of geometry is not entirely clear, but I believe you can't
        > do perspective with setTransform because it only handles 2D affine
        > transformations - parallel lines will always remain parallel. The
        > transform matrix only contains six values (m11, m12, m21, m22, dx,
        > dy)



        Correct.
        The setTransform() method is an affine transformation in 2D space.

        The result would be as good ( or bad ) as the texture mapping on
        PlayStation 1. It could be acceptable if you subdivide the polygons
        into small triangles but it's tough to balance between speed and
        quality.

        Back in the days of Quake 1, the perspective correction was done
        every 8 ( or 16 ) pixels and the mapping was affine in between. It
        was mostly visible when you walked along a wall because of the big
        difference of perspective from one edge to the other. But this
        technique is still too heavy for JavaScript and Canvas.



        > That's a relatively easy case since the walls are always vertical -
        I
        > also did some perspective-correct textured floors like
        > http://canvex.lazyilluminati.com/misc/floor5.jpg by drawing thin (2
        > pixel) horizontal strips, with a rotated/scaled/translated image
        > pattern fill (plus some mipmapping because images normally get
        scaled
        > down in an ugly flickery way). It works by setting the transform
        > matrix such that the desired line of texture will be transformed
        onto
        > the desired line of screen coordinates (corresponding to the current
        > horizontal strip), then drawing a pattern-filled rectangle which
        ends
        > up getting transformed to those screen coordinates; that just
        involves
        > some maths (or experimentation and typing in random equations until
        it works).
        > I think that method could support any arbitrary 3D polygon (though
        my
        > code was limited to the requirements of my floors) - but the biggest
        > problem is that it's really quite slow, because it needs lots of
        > textured-rectangle-fills for each polygon, which makes it unusable
        in most practical cases.



        It can work for arbitrary 3D polygons but it would be really CPU
        intensive and most likely not suitable for more than ~20-30
        triangles. :|
      Your message has been successfully submitted and would be delivered to recipients shortly.