# Thread: Gradients on perspective projected Images..

1. ## Gradients on perspective projected Images..

There's something I stumbled over while testing some gradients:

The gradients inherit the transform of the objects they are applied to. That makes perfect sense for me. In the spec this is only defined for the pathes, but ok - it makes sense to do the same for images as well.

However, the spec clearly states that paint transforms are affine only, and image transforms might be projective.

Now if I apply a gradient paint on a image drawn with perspective projection I don't know what results to expect. The reference implementation draws something, but it's hard to find out/guess how exactly the gradient should be drawn.

Question:

• Do we have to mimic the behaviour of the reference implementation for this special case? After all it's not defined in the spec.
[/*:meh44fix]
• If so - how exactly should the gradient sampling work? Do we really have to sample the gradient projective?
[/*:meh44fix]
• If we have to sample the gradient affine, how should we get rid of the projective transform?[/*:meh44fix]

Hope someone can help me with these issues. After all - there's little to none traffic on this board..

Thanks,
Nils Pipenbrinck

2. Here's a bit of code. draws a test image with radial gradient in perspective and affine mode.

Code :
```void Gradient_WTF (void)
{
VGfloat stops[10] =
{
0, 0.8,0.2,0.1,1,
1, 0.1,0.2,0.8,1,
};

{
128,128,128,128,60,
};

VGfloat ImageMatrix[9] =
{
-0.4477,  0.8941,   0.0015,
-0.8941, -0.4477,  0.0018,
370,      140,      1,
};

// make checkerboard image:
VGImage img = vgCreateImage (VG_sL_8, 256, 256, VG_IMAGE_QUALITY_BETTER);
for (VGint y=0; y<256; y+=32)
for (VGint x=0; x<256; x+=32)
{
VGfloat white[4] = { 1,1,1,1       };
VGfloat gray[4]  = { 0.4,0.4,0.4,1 };
vgSetfv      (VG_CLEAR_COLOR, 4, (x^y)&32 ? white:gray);
vgClearImage (img, x,y,32,32);
}

// make paint:
VGPaint paint = vgCreatePaint();
vgSetPaint        (paint, VG_FILL_PATH);
vgSetParameterfv  (paint, VG_PAINT_COLOR_RAMP_STOPS, 10, stops);

// draw projective image:
vgSeti        (VG_IMAGE_MODE,  VG_DRAW_IMAGE_MULTIPLY);
vgSeti        (VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
vgDrawImage   (img);

// draw affine image:
vgTranslate    (400, 10);
vgDrawImage    (img);

vgDestroyImage (img);
vgDestroyPaint (paint);
}```

3. anyone?

4. Ok - if anyone is ever interested, this is what the reference implementation does:

Projective image matrices become unprojected before multiplication with the paint matrix. The unprojection works like this:

build 3 vectors that form a unit coordinate system in 2d:
vector v[3];
v[0] = vector(0,0);
v[1] = vector(1,0);
v[2] = vector(0,1);

transform these vectors by the image matrix (extend 2d vectors to homogenous 2d vectors by adding an implicit z=1). after transformation divide out the vectors x,y by z.

Then subtract projected origin from projected axis:

v[1] -= v[0];
v[2] -= v[0];

The output matrix directly built from these 3 vectors.

- translational part is equal to v[0],
- first column of upper 2x2 submatrix equals to v[1]
- second column of upper 2x2 submatrix equals to v[2]
- projective part becomes 0, 0, 1 (as usual for affine matrices)

I still scratch my head if this is fine with the standard.

5. Originally Posted by Nils Pipenbrinck
...
I still scratch my head if this is fine with the standard.
OpenVG specifications do not clarify the correct behavior for perspective image matrixes coupled with a paint.
For radial gradient, i think that the correct result should be, in your case, that gradient circles had to "fit" (perspectively) the image outline.

6. Originally Posted by muratmat
Originally Posted by Nils Pipenbrinck
...
I still scratch my head if this is fine with the standard.
OpenVG specifications do not clarify the correct behavior for perspective image matrixes coupled with a paint.
For radial gradient, i think that the correct result should be, in your case, that gradient circles had to "fit" (perspectively) the image outline.
Hm..

I doubt that this is intended.. For pattern images that wouldn't be such a big deal since it simplifies down to just a perspective image mapping, but the radial gradients are already hard enough to calculate.

Making them perspective correct would make almost all good optimizations impossible (e.g precomputed dda-method for scanlines).

7. Originally Posted by Nils Pipenbrinck
Hm..

I doubt that this is intended.. For pattern images that wouldn't be such a big deal since it simplifies down to just a perspective image mapping, but the radial gradients are already hard enough to calculate.

Making them perspective correct would make almost all good optimizations impossible (e.g precomputed dda-method for scanlines).
I was talking about the correct behaviour that every user could expect, and that i think is the most correct one.
From an implementation point of view, it's normal to accept some compromises to not loose too much speed.
Anyway, i think that guys who wrote OpenVG specifications did not consider a such case, and that's why in my vector graphics framework (Amanith, do you know it?) i left gradient/pattern matrix independent from the "modelview" matrix.

8. When there is a projective transform on an image, the image mode falls back to normal mode.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•