Forums > Jitter

UVcoords in shader?

January 3, 2007 | 5:10 pm

Hi,

I’m a total glsl rookie trying to write a shader that gives you individual control over the four cornerpoints of your UV. Like the "Perspective Transform" image unit. But I can’t get it to work. I realize I need something other then the texture2DRect call, but when I try to use texture2DProj it gives me errors. I guess I need a varying vec4 texcoord somehow, but how?
Any pointers in the right direction would be great.

tia


January 3, 2007 | 5:32 pm

On Jan 3, 2007, at 9:10 AM, Adam Wittsell wrote:

> I’m a total glsl rookie trying to write a shader that gives you
> individual control over the four cornerpoints of your UV. Like the
> "Perspective Transform" image unit. But I can’t get it to work. I
> realize I need something other then the texture2DRect call, but
> when I try to use texture2DProj it gives me errors. I guess I need
> a varying vec4 texcoord somehow, but how?
> Any pointers in the right direction would be great.

Check out any of the texdisplace shaders to see how to manipulate
texture coordinates. td.resample.jxs is probably a good one to start
getting a feel for this. td.rota.jxs is more along the lines of
"Perspective Transform", but the bound mode logic is a little
confusing. Here’s esse ntially what that would look like if you
didn’t care about the bound modes. (*much simpler*).

void main()
{
// where is the point?
vec2 sizea = texdim0;
vec2 point = texcoord0;

//transformation matrices
mat2 sca = mat2 (1./zoom.x,0.,0.,1./zoom.y);//scaling matrix (zoom)
mat2 rot = mat2 (cos(theta),sin(theta),-sin(theta),cos(theta));//
rotation matrix

//perform transform
vec2 tc = ((((point-anchor*sizea)*rot)*sca)+anchor*sizea)+offset;

//sample textures
gl_FragColor = texture2DRect(tex0,tc);
}

For more information regarding shaders, I would recommend checking
out some of the resources listed at the following link, as well as
NVidia’s GPUGems series:

http://www.cycling74.com/twiki/bin/view/ResourceGuide/OpenGLResources

-Joshua


January 3, 2007 | 7:18 pm

Thanks for the tips Joshua.
I have tried to look on the net and the texdisp shaders, but I still don’t get it. Every example I find deals with the transformation of a rectangle and not the individual points. Why can’t it be easy as in Maya ;)?


January 3, 2007 | 7:56 pm

Hi Adam,
It sounds like what you need is a little primer on linear algebra.
Since what you are manipulating (texcoords) are cartesian coordinates,
look for ways to tranform those coordinates into the shape, size, and
location you are looking for. For a start, here’s a page that discusses
some basic transformation matrices:

http://en.wikipedia.org/wiki/Transformation_matrix

Good luck!

Cheers,
Andrew B.


January 3, 2007 | 8:35 pm

Are you tryting to do projective texture mapping like this:
http://developer.nvidia.com/object/Projective_Texture_Mapping.html ?
If so, you don’t want to use a 4-component texcoord but a 3 component
texcoord. The 3 components are the usual U, V but in homogenous
coordinates with the 3rd value used for the perspective divide. For
the 4 component version, the 3rd value holds a depth value. This for
is used for shadow mapping.

wes

Here’s a version of td.lumadisplace.jxs but in GLSL.



Luminance based texture displacement

Amplitude of displacement (x,y)

Offset




< ![CDATA[

uniform vec2 amp;
uniform float offset;

varying vec2 texcoord0;
varying vec2 texdim0;
uniform sampler2DRect tex0;

void main()
{
vec3 color = texture2DRect(tex0, texcoord0).rgb;
float colorSQ = dot(color, color);
float colorInvSQR = inversesqrt(colorSQ);

vec2 recip;
recip.x = 1./colorInvSQR;
recip.y = recip.x;

recip += vec2(offset);
recip *= amp;
recip *= texdim0;

recip += texcoord0;

vec4 final_color = texture2DRect(tex0, recip);

gl_FragColor = final_color;
//gl_FragColor = vec4(color, 1.);
}
]]>


January 3, 2007 | 9:07 pm

What I’m trying to achieve is a way to do perspective transformation in the texture space itself. The point being that I then could have several texture layers composited together with slabs ending up on one videoplane, but still have 3D-control over each layer individually.
So far I managed to get around my lack of math by using the Jash 3Dmatrix objects and feed the result into the "Perspective Transform" image unit. The problem is that the effect forbids pointA to have a larger x-value then PointB. So I can only rotate the object +-90 degrees in y (patch below).
I guess the best approach would be to have a vertex shader manipulate the slab geometry itself, so I just have to grit my teeth and get down with the matrices.
Any other suggestions from you pros are very welcome.

#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P newex 589 293 27 196617 90;
#P newex 524 298 40 196617 10000;
#P newex 465 289 27 196617 216;
#P newex 325 753 89 196617 pak param 3 0. 0.;
#P newex 235 753 89 196617 pak param 2 0. 0.;
#P newex 145 753 89 196617 pak param 1 0. 0.;
#P newex 522 256 143 196617 jit.window 3d @size 384 216;
#P newex 354 113 20 196617 t b;
#N vpatcher 442 381 1065 792;
#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P newex 171 74 27 196617 + 1.;
#P newex 133 74 27 196617 f;
#P newex 82 74 40 196617 + 1.77;
#P newex 50 74 27 196617 f;
#P newex 50 148 174 196617 pack 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.;
#P newex 50 175 47 196617 zl iter 3;
#P inlet 50 30 15 0;
#P inlet 243 38 14 0;
#P inlet 133 32 15 0;
#P outlet 50 200 15 0;
#P window linecount 0;
#P newex 100 49 14 196617 .;
#P connect 4 0 7 0;
#P connect 0 0 7 0;
#P connect 7 0 6 0;
#P connect 6 0 5 0;
#P connect 5 0 1 0;
#P connect 9 0 6 1;
#P fasten 3 0 6 2 248 127 83 127;
#P fasten 4 0 8 0 55 58 87 58;
#P connect 8 0 6 3;
#P connect 3 0 0 0;
#P connect 2 0 0 0;
#P connect 9 0 6 4;
#P fasten 3 0 6 5 248 129 125 129;
#P connect 2 0 9 0;
#P connect 8 0 6 6;
#P connect 10 0 6 7;
#P connect 3 0 6 8;
#P fasten 2 0 10 0 138 59 176 59;
#P connect 7 0 6 9;
#P connect 10 0 6 10;
#P connect 3 0 6 11;
#P pop;
#P newobj 196 203 118 196617 p defaultPlane;
#P flonum 302 104 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 250 102 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 196 103 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P message 30 192 58 196617 order t s r;
#P newex 109 594 51 196617 zl slice 2;
#P comment 466 485 100 196617 point of interest;
#B frgb 127 127 127;
#P comment 332 485 53 196617 eye-point;
#B frgb 127 127 127;
#P comment 648 370 31 196617 mode;
#B frgb 127 127 127;
#P comment 495 354 71 196617 clipping range;
#B frgb 127 127 127;
#P comment 327 297 42 196617 rotation;
#B frgb 127 127 127;
#P flonum 539 431 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 503 499 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 467 499 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 467 519 77 196617 pak poi 0. 0. 0.;
#P flonum 404 499 50 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 368 499 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 332 499 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 333 519 80 196617 pak eye 0. 0. 0.;
#P comment 418 354 70 196617 viewport size;
#B frgb 127 127 127;
#P number 454 368 36 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P number 418 368 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 418 386 46 196617 pak;
#P number 531 368 44 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P number 495 368 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 496 386 46 196617 pak;
#P newex 496 406 71 196617 prepend range;
#P message 581 385 38 196617 fov $1;
#P flonum 581 368 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 418 405 64 196617 prepend size;
#P toggle 631 368 15 0;
#P message 631 385 45 196617 mode $1;
#P message 344 396 39 196617 roll $1;
#P flonum 344 379 60 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P message 335 362 42 196617 yaw $1;
#P flonum 335 345 60 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P message 326 328 45 196617 pitch $1;
#P flonum 326 311 60 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 126 551 28 196617 gaze;
#P comment 581 354 25 196617 fov;
#B frgb 127 127 127;
#P flonum 452 95 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 418 95 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 384 95 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 452 58 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 418 58 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 384 58 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 452 22 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 418 22 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 384 38 20 196617 t b;
#P newex 384 74 20 196617 t b;
#P flonum 384 22 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 373 131 109 196617 pack translate 0. 0. 0.;
#P newex 403 74 95 196617 pack rotate 0. 0. 0.;
#P newex 403 38 91 196617 pack scale 0. 0. 0.;
#P newex 87 287 52 196617 3Dmatrix;
#P newex 280 547 14 196617 .;
#P newex 109 640 39 196617 thresh;
#P newex 788 270 226 196617 jit.gl.imageunit 3d @fx "Perspective Transform";
#P newex 590 199 123 196617 jit.gl.render 3d @ortho 2;
#P newex 590 111 57 196617 qmetro 40;
#P toggle 590 82 15 0;
#P newex 590 152 50 196617 t b erase;
#P newex 788 358 178 196617 jit.gl.videoplane 3d @scale 1.77 1. 1.;
#P newex 788 155 105 196617 jit.qt.movie 320 240;
#P message 843 86 30 196617 read;
#P newex 54 753 89 196617 pak param 0 0. 0.;
#P newex 109 687 136 196617 unpack 0. 0. 0. 0. 0. 0. 0. 0.;
#P comment 197 80 116 196617 Initial object transform;
#P newex 435 224 48 196617 loadbang;
#P newex 427 288 27 196617 384;
#P newex 386 289 36 196617 -2.29;
#P connect 70 0 16 0;
#P connect 66 0 16 0;
#P fasten 19 0 16 0 378 158 92 158;
#P fasten 18 0 16 0 408 157 92 157;
#P fasten 17 0 16 0 408 157 92 157;
#P connect 4 0 5 2;
#P connect 32 0 65 0;
#P connect 65 0 14 0;
#P connect 14 0 4 0;
#P fasten 56 0 32 0 472 544 131 544;
#P fasten 44 0 32 0 501 473 131 473;
#P fasten 41 0 32 0 423 473 131 473;
#P fasten 38 0 32 0 349 473 131 473;
#P fasten 34 0 32 0 331 473 131 473;
#P fasten 52 0 32 0 338 544 131 544;
#P fasten 43 0 32 0 586 473 131 473;
#P fasten 39 0 32 0 636 473 131 473;
#P fasten 36 0 32 0 340 473 131 473;
#P connect 16 0 32 0;
#P connect 4 1 5 3;
#P fasten 22 0 70 0 389 149 201 149;
#P connect 71 0 70 0;
#P connect 67 0 70 0;
#P fasten 15 0 70 0 285 574 188 574 188 181 201 181;
#P fasten 21 0 70 0 389 150 201 150;
#P connect 4 2 73 2;
#P connect 4 3 73 3;
#P connect 68 0 70 1;
#P connect 56 0 15 0;
#P connect 52 0 15 0;
#P connect 44 0 15 0;
#P fasten 43 0 15 0 586 465 285 465;
#P connect 41 0 15 0;
#P fasten 39 0 15 0 636 463 285 463;
#P connect 38 0 15 0;
#P connect 36 0 15 0;
#P connect 34 0 15 0;
#P connect 4 4 74 2;
#P connect 69 0 70 2;
#P connect 4 5 74 3;
#P connect 33 0 34 0;
#P connect 35 0 36 0;
#P connect 37 0 38 0;
#P connect 30 0 71 0;
#P connect 29 0 71 0;
#P connect 28 0 71 0;
#P connect 53 0 52 1;
#P connect 71 0 19 0;
#P connect 4 6 75 2;
#P connect 54 0 52 2;
#P connect 24 0 22 0;
#P connect 23 0 22 0;
#P connect 20 0 22 0;
#P connect 27 0 21 0;
#P connect 26 0 21 0;
#P connect 25 0 21 0;
#P connect 2 0 0 0;
#P connect 55 0 52 3;
#P connect 22 0 17 0;
#P connect 21 0 18 0;
#P connect 4 7 75 3;
#P connect 0 0 55 0;
#P connect 28 0 19 1;
#P connect 1 0 49 0;
#P connect 49 0 48 0;
#P fasten 48 0 41 0 423 407 423 407;
#P connect 2 0 1 0;
#P connect 20 0 17 1;
#P connect 25 0 18 1;
#P connect 29 0 19 2;
#P connect 76 0 50 0;
#P connect 50 0 48 1;
#P connect 23 0 17 2;
#P connect 26 0 18 2;
#P connect 2 0 76 0;
#P connect 30 0 19 3;
#P connect 24 0 17 3;
#P connect 27 0 18 3;
#P connect 57 0 56 1;
#P connect 46 0 45 0;
#P fasten 45 0 44 0 501 407 501 407;
#P connect 58 0 56 2;
#P connect 2 0 77 0;
#P connect 77 0 47 0;
#P connect 47 0 45 1;
#P connect 59 0 56 3;
#P connect 78 0 42 0;
#P connect 42 0 43 0;
#P connect 2 0 78 0;
#P connect 10 0 11 0;
#P connect 11 0 9 0;
#P connect 9 0 12 0;
#P connect 9 1 12 0;
#P fasten 40 0 39 0 636 384 636 384;
#P connect 6 0 7 0;
#P fasten 11 0 7 0 595 137 793 137;
#P fasten 75 0 13 0 330 781 704 781 704 233 793 233;
#P fasten 5 0 13 0 59 779 681 779 681 228 793 228;
#P fasten 74 0 13 0 240 782 706 782 706 237 793 237;
#P fasten 73 0 13 0 150 779 700 779 694 241 793 241;
#P connect 7 0 13 0;
#P connect 13 0 8 0;
#P window clipboard copycount 79;


January 3, 2007 | 9:20 pm

If you’re just looking to do 4 point interpolation, where the four
corners of the rectangle can be tied to new coords, this math is very
simple and doesn’t require learning about matrix transformations.
Otherwise, you’ll need to learn a bit of matrix math (or just use
textured geometry with jit.gl.sketch or jit.gl.mesh instead of using
slab)

Here’s a rough example of how you’d accomplish the four point
interpolation in a jitter shader. Warning email client coded, so
there might be mistakes.

uniform vec2 bottomleft;
uniform vec2 bottomright;
uniform vec2 topleft;
uniform vec2 topright;

varying vec2 texcoord0;
varying vec2 texdim0;
uniform sampler2DRect tex0;

void main()
{
// normalize our texture coordinate to range 0-1 based on texture
dimensions
vec2 normpoint = texcoord0/texdim0;

// four point interpolation:

// interpolate across X axis for top two points
vec2 toptemp = xfade(topleft,topright,vec2(texcoord0.x));

// interpolate across X axis for bottom two points
vec2 bottomtemp = xfade(bottomleft,bottomright,vec2(texcoord0.x));

// interpolate across Y axis with top/bottom temporaries
vec2 tc = xfade(bottomtemp,toptemp,vec2(texcoord0.y));

// if the four corners are specified with normalized texture
coordinates, need to scale again
tc = tc*texdim0;

//sample texture
gl_FragColor = texture2DRect(tex0,tc);
}

-Joshua


January 3, 2007 | 9:50 pm

Thank’s Joshua! This looks exactly like what I’m after. It refuses to compile though. It says "ERROR: 0:19: ‘xfade’ : no matching overloaded function found". I think the code came through all right.


January 3, 2007 | 9:57 pm

That’s because xfade() is not a valid built-in GLSL function. I think
JKC meant to use mix() here.

AB


January 3, 2007 | 10:45 pm

On Jan 3, 2007, at 1:57 PM, Andrew Benson wrote:

> That’s because xfade() is not a valid built-in GLSL function. I think
> JKC meant to use mix() here.

Ja. Sorry about that. Was just typing real quick in email client, and
spaced out on the GLSL mix call.

-Joshua


January 3, 2007 | 10:53 pm

I got it up and running now, but it seems that the transformation is nonlinear. I modified your code to include the normpoint you declared, but didn’t use, but it made no difference. It’s a very cool effect, but not quite what I was after ;).

{
vec2 normpoint = texcoord0/texdim0;
vec2 toptemp = mix(topleft,topright,vec2(normpoint.x));
vec2 bottomtemp = mix(bottomleft,bottomright,vec2(normpoint.x));
vec2 tc = mix(bottomtemp,toptemp,vec2(normpoint.y));
tc = tc*texdim0;
gl_FragColor = texture2DRect(tex0,tc);
}

[img]index.php?t=getfile&id=406&private=0[/img]


January 4, 2007 | 9:41 pm

Hi Adam,
Could you send us a copy of the complete shader that you are using?
It’s very strange that you are getting these non-linear results.

Cheers,
Andrew B.


January 4, 2007 | 9:48 pm

Here it is.
I probably did something wrong when I tried to change it.



shader for performing srcdim/dstdim operations

topleft

topright

bottomright

bottomleft







< ![CDATA[

// Andrew Benson – andrewb@cycling74.com
//Copyright 2006 – Cycling ’74

//fragment shader for performing texture resampling, using srcdim/dstdim messages

// texcoords
uniform vec2 topleft;
uniform vec2 topright;
uniform vec2 bottomright;
uniform vec2 bottomleft;

varying vec2 texcoord0;
varying vec2 texdim0;
uniform sampler2DRect tex0;

// entry point
void main()
{
vec2 normpoint = texcoord0/texdim0;
vec2 toptemp = mix(topleft,topright,vec2(normpoint.x));
vec2 bottomtemp = mix(bottomleft,bottomright,vec2(normpoint.x));
vec2 tc = mix(bottomtemp,toptemp,vec2(normpoint.y));
tc = tc*texdim0;
gl_FragColor = texture2DRect(tex0,tc);
}

]]>


January 5, 2007 | 2:11 am

On Jan 3, 2007, at 2:53 PM, Adam Wittsell wrote:

> I got it up and running now, but it seems that the transformation
> is nonlinear. I modified your code to include the normpoint you
> declared, but didn’t use, but it made no difference. It’s a very
> cool effect, but not quite what I was after ;).

Technically bilinear interpolation isn’t a linear operation. Sorry
for this false solution to your problem. I thought that this would
give you roughly the results you were looking for, but obviously not.
What you’ll need to do to get the exact same solution as the
"Perspective Transform" image unit is solve for the rectangular plane
in 3d space which projects to the four screen points specified. This
will definitely require some linear algebra.

http://en.wikipedia.org/wiki/3D_projection

If you don’t care about the perspective transform and that the shape
is a rectangle in 3d space (instead of some arbitrary quadrilateral
in 2d space), the problem is a little bit simpler, and you can easily
accomplish with sketch and glvertex/gltexture instead of using
jit.gl.slab, letting OpenGL do the rest for you.

Finally, another thing to mention for people interested in linear
transforms to texture coordinates without using shaders, keep in mind
that you can use the tex_plane_s and tex_plane_t attributes of
jit.gl.* objects in tex_mode 1 and 3 (search archives for some
examples), or use gltranslate/glscale/glrotate with glmatrixmode
texture in sketch. These approaches of course can invalidate
assumptions made by the passthrudim vertex shader that grabs the
diagonal texture matrix values to establish pixel width height for
rectangular textures.

Probably more detail with less usable information than you were
looking for, but hopefully this points you in the right direction if
you want to get your hands dirty.

-Joshua


January 6, 2007 | 2:03 pm

Thank’s for the tips guys. Will try to get down with the matrices.

Cheers


January 6, 2007 | 4:43 pm

A late follow-up…

Here are some great free video lectures for all who missed them in school:

http://ocw.mit.edu/OcwWeb/Mathematics/18-06Spring-2005/VideoLectures/index.htm

They helped me realizing that jit.la object names are not referencing Los
Angeles…

> It sounds like what you need is a little primer on linear algebra.


Viewing 16 posts - 1 through 16 (of 16 total)