POV-Ray : Newsgroups : povray.beta-test : Suggested bicubic patch uv mapping changes : Suggested bicubic patch uv mapping changes Server Time
31 Jul 2024 04:28:05 EDT (-0400)
  Suggested bicubic patch uv mapping changes  
From: Mike Hough
Date: 10 Sep 2001 00:03:41
Message: <3b9c3b9d@news.povray.org>
Sometime in June of last year, I submitted for MegaPOV an alternate method
for calculating the parametric mapping for patches.  The intention was to
have the option of providing an arbitrary quadrilateral represent the
texture coordinates of the patch but at the time a seemingly minor problem
was present.  Basically any time the texture coordinates deviated from a
rectangle a perspective distortion was introduced.  Recently I noticed that
the paper I adapted the code from was interested in inferred perspective
mapping for raster projection.  The net result is that in many cases,
texture coordinates that should stitch smoothly at the edge of two patches
do not do so and this problem is still present in the 3.5 beta.

I've spent the entire weekend working on a fix because this is close to
being official and think I have found a good solution.  Only 3 files need to
be changed.  The following is using the original code from MegaPOV.

Starting with matrices.c, we can get rid of the function MSquareQuad()
altogether since it's no longer necessary to compute the 3x3 homogenous
matrix when a patch is parsed.  A little further up in the file, the
function MTransUVPoint needs to be changed to the following:

void MTransUVPoint(p, st, t)
UV_VECT st[4];
double p[2], t[2];
{ 
 UV_VECT u1, u2;
 
    u1[0] = st[0][0] + p[0] * (st[1][0] - st[0][0]);
    u1[1] = st[0][1] + p[0] * (st[1][1] - st[0][1]);

    u2[0] = st[3][0] + p[0] * (st[2][0] - st[3][0]);
    u2[1] = st[3][1] + p[0] * (st[2][1] - st[3][1]);

    t[0] = u1[0] + p[1] * (u2[0] - u1[0]);
    t[1] = u1[1] + p[1] * (u2[1] - u1[1]);
 
}

Notice that this function is no longer using the tranformation matrix - instead we get
the mapping directly using the texture coordinates ST.  Therefore we need to change
every use of this function in bezier.c to take object->ST instead of object->mapping. 
There's a few of these.  In other words,

This:

MTransUVPoint(uv_point, Shape->Mapping, tpoint);

Becomes this:

MTransUVPoint(uv_point, Shape->ST,
 tpoint);

Since we have switched from using the mapping matrix to using texture
coordinates, we must copy the texture coordinates when we copy a patch.
Near the bottom of bezier.c change:

for (m = 0; m < 3; m++)
  {
    for (h = 0; h < 3; h++)
    {
      New->Mapping[m][h] = ((BICUBIC_PATCH *)Object)->Mapping[m][h];
    }
  }

Into this:

for (m = 0; m < 4; m++)
  {
    for (h = 0; h < 2; h++)
    {
      New->ST[m][h] = ((BICUBIC_PATCH *)Object)->ST[m][h];
    }
  }

Lastly, since MSquareQuad function was removed, it should be removed from
Parse_Bicubic_Patch in parse.c since it appears there at least once.  At
this point everything should work correctly.

I will be posting an example render of what the mapping looked like in 3.5
beta and how it looks with these changes in p.b-t.b.  Here is a code example
for testing.  The texture along the top edge of the bottom patch and the
bottom edge of the top patch should blend smoothly.

#include "colors.inc"
camera {location <0, 0, -2> angle 40}
light_source {<10, 10, -20> color White}

#declare test_pigment =
pigment {
average
pigment_map {
[1
gradient x
sine_wave
frequency 12
color_map {
[0 color White transmit 0]
[1 color Black transmit 0]
}

]
[1 gradient y
frequency 12
sine_wave
color_map {
[0 color Blue]
[1 color White]
}
scale 1
]
}

}
/*
#declare test_pigment =
pigment {
image_map {
tga "gradient.tga"
interpolate 4
}
}
*/

#declare test = union {
bicubic_patch {
type 1
u_steps 4
v_steps 4
uv_vectors <0, 0>, <1, .25>, <1, .5>, <0, .5>
<-3, -3, 0>, <-1, -3, 0>, <1, -3, 0>, <3, -3, 0>,
<-3, -1, 0>, <-1, -1, -3>, <1, -1, -3>, <3, -1, 0>,
<-3, 1, 0>, <-1, 1, -3>, <1, 1, -3>, <3, 1, 0>,
<-3, 3, 0>, <-1, 3, -3>, <1, 3, -3>, <3, 3, 0>
uv_mapping
scale 1/6
pigment {test_pigment}
finish {ambient 1}
}

bicubic_patch {
type 1
u_steps 4
v_steps 4
uv_vectors <0, .5>, <1, .5>, <1, 1>, <0, 1>
<-3, -3, 0>, <-1, -3, -3>, <1, -3, -3>, <3, -3, 0>,
<-3, -1, 0>, <-1, -1, -3>, <1, -1, -3>, <3, -1, 0>,
<-3, 1, 0>, <-1, 1, -3>, <1, 1, -3>, <3, 1, 0>,
<-3, 3, 0>, <-1, 3, 0>, <1, 3, 0>, <3, 3, 0>
uv_mapping
scale 1/6
pigment {test_pigment}
finish {ambient 1}
translate 1*y
}

}


object {test translate -.5*y scale <1, .5, 1>} /* test that patch data is
being copied correctly */


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.