perspective interpolation

Started by
12 comments, last by bwhiting 13 years, 3 months ago
have been scratching my noodle with this one for a wee while so i though i would put it out there, am sure there is a pretty simple solution and if you could share it with a small explanation that would be awesome!!


basically, given 2 points in screen space A and B

suppose there is an intersection point C...

how the fudge to I work out the w value for C.

I know the projected values of A B and C (screen x and screen y)
I also know the original/local x y and z for A and B
as well as knowing the w value for A and B

but unlike the screen coords for C, which are linear, the w value is not... i think.

I kind of understand the perspective divide and stuff but not well enough to reverse it/interpolate it.

Is this possible with the information I have about A and B?

thanks very much for your time :)

let me know if i make < perfect sense and I will try and work it better or maybe post a picture or something.

(the context is me trying to interpolate uvt data for the purpose of clipping in screen space without it going nuts like it is at the moment)
Advertisement
Just interpolate linearly 1/w and x/w (where x can be any vertex attribute) and recalculate x per pixel from interpolated values. The theory behind this - classic articles by Chris Hecker about perspective texture mapping.
1st thanks for replying, its much appreciated!

I think my variable interpolation is ok, its just getting hold of the new w value.


i.e.
intersect1.sx = in1.sx + ((out1.sx - in1.sx) * dwa);
intersect1.x = (in1.sx*in1.w) + (((out1.sx*out1.w) - (in1.sx*in1.w)) * dwa);

dwa is the ratio... intersect is the intersecting point between in1 and out1, each has the properties x,y,z,w,sx,sy and sz

the above code correctly interpolates the sx and x values, but i need to work out the w value for the intersection.

i.e.
intersect1.w = in1.w + ((out1.w - in1.w) * dwa);


but it wont work will it?

are you saying i need to put 1/w into that formula instead?


sorry if im not quite getting it.
hmm i think i got some fundamentals wrong here...


var x:Number = (verticy.x * a) + (verticy.y * e) + (verticy.z * i) + m;
var y:Number = (verticy.x * B) + (verticy.y * f) + (verticy.z * j) + n;
var z:Number = (verticy.x * c) + (verticy.y * g) + (verticy.z * k) + o;
var w:Number = (verticy.x * d) + (verticy.y * h) + (verticy.z * l) + p;

verticy.sx = x/w;
verticy.sy = y/w;
verticy.sz = z/w;

var t:Number = focalLength/w;

basically a..m are the final transform matrix values including viewport transformation.

t is the value used for perspective correct texturing.

so in screen space when I create new vertices for the purpose of clipping I need to get that new t value.
the t value requires the correct w value and thats where I seem to be unable to succeed.

event though the screen coords are linear the w is not ( i think) so i canny figure out a formula to work it out.


if anyone can fill me in here that would be jolly smashing, as its doing my nut in and so far is the only thing that has had me stumped for a while!!!
triangle.jpg

^^ the original triangle

correct.jpg



^^ un-clipped

fail.jpg


fail w interpolation :(

fail2.jpg


^^ texture is clipped correctly but screen coords are buggared



oh why cant I work this one out, I feel like I have tried every combo of multiplies and divides i can think of...

I think my variable interpolation is ok, its just getting hold of the new w value.

i.e.
intersect1.sx = in1.sx + ((out1.sx - in1.sx) * dwa);
intersect1.x = (in1.sx*in1.w) + (((out1.sx*out1.w) - (in1.sx*in1.w)) * dwa);

dwa is the ratio... intersect is the intersecting point between in1 and out1, each has the properties x,y,z,w,sx,sy and sz

the above code correctly interpolates the sx and x values, but i need to work out the w value for the intersection.

i.e.
intersect1.w = in1.w + ((out1.w - in1.w) * dwa);


but it wont work will it?

are you saying i need to put 1/w into that formula instead?



I'll try to explain it in a greater detail. Let's try to calculate perspective correct u:

1. For every vertex: calculate u' = u' / w and w' = 1 / w'
2. For every pixel: linearly interpolate u' _and_ w' and calculate perspective correct u ( interpolated u' / interpolated w' ).

As for the clipping - looks like You are using linear interpolation to calculate values for new vertices created by clipping. You should use perspective correct interpolation there.
cheers again for the update and you patience for my incompetence :)
Flash is the platform I am using and it does the texturing for you, you just supply it UVT data and the T value I have been getting by this formula:


[size=2]var t:Number = focalLength/w;<br /> <br /> <br /> <h3>this works fine but when I create a new verticy for clipping purposes I need to also calculate its w value some how. I could get it if I could work out the new local coordintes of the vert but i dont seem to be able to work those out given that my interpolation is in screen space and i just can&#39;t get a formula that works.<br /> <h3><br /> <br /> <h3>p.s. not to sure what the difference between [size=2]w and [size=2]w&#39;?<br /> [size=2]<br /> <br /> [size=2]am self taught you see and im a pretty crap teacher too.<br /> <br /> <br /> code:<br /> //d1 is the linear interpolation ratio <br /> <br /> var d1:Number = out1.sx - in1.sx; //in and out verts form the edges of the triangles to be clipped<br /> d1 = (xMin - in1.sx)/d1; //xMin is the left clipping value, i.e. 0<br /> <br /> var intersect1:VectorB3D = new VectorB3D(); //the new vertex <br /> <br /> intersect1.sx = in1.sx + ((out1.sx - in1.sx) * d1); //will be equal to xMin<br /> <span style="font-weight:bold;">intersect1.sy = in1.sy + ((out1.sy - in1.sy) * d1); //the new screen y value</span><br /> <br /> <span style="font-weight:bold;">intersect1.w = ? //how the fudge can I get these puppies given all I know is the sx sy sz and w for the in and out verts</span><br /> <span style="font-weight:bold;">intersect1.x = ?</span><br /> [size=2]<span style="font-weight:bold;">intersect1.y = ?</span><br /> [size=2]<span style="font-weight:bold;">intersect1.z = ?</span><br /> [size=2]<span style="font-weight:bold;"><br /> </span><br /> if you could fill in any of the blanks for me I would be sorted&#33;&#33;<br /> <br /> <br /> p.s. i am not even sure if my w values are correctly generated (see my code a few replies back about how i arrived at it) from debugging they seem to go from -1 to about -800 in this demo<br /> <br /> <br /> ben
One approach is to clip in world space, by using the plane equations for the six faces of the view frustum. Then your clip test reduces to finding a line-vs-planeintersection.

A second approach is to invert the projective matrix. The inverse of the projective matrix transforms from screen space back to world space. So you would intersect your line against the clip boundary in screenspace, then append a w of 1 and transform the intersection point back to world space.






One approach is to clip in world space, by using the plane equations for the six faces of the view frustum. Then your clip test reduces to finding a line-vs-planeintersection.

A second approach is to invert the projective matrix. The inverse of the projective matrix transforms from screen space back to world space. So you would intersect your line against the clip boundary in screenspace, then append a w of 1 and transform the intersection point back to world space.


As I am running this in flash, I chose to avoid frustum at that stage because all the implementations I had seen before were slow, and my pipeline goes straight from local to screen space avoiding any additional matrix multiplications for speed gain. so I never see the verts in world space :( they go direct to screen.

might try the inverse matrix approach if that is the only way it can be done but it might end up being slower... curse flash and her in ability to do stuff fast!



var t:Number = focalLength/w;<br /> this works fine but when I create a new verticy for clipping purposes I need to also calculate its w value some how. I could get it if I could work out the new local coordintes of the vert but i dont seem to be able to work those out given that my interpolation is in screen space and i just can&#39;t get a formula that works.<br /> </blockquote><br /> <br /> vert1 and vert2 - original vertices<br /> newVert - new vertex created by clipper<br /> <br /> newVert.w = 1 / lerp( 1 / vert1.w, 1 / vert2.w, ratio )<br /> newVert.x = lerp( vert1.x / vert1.w, vert2.x / vert2.w, ratio ) * newVert.w<br /> newVert.y = lerp( vert1.y / vert1.w, vert2.y / vert2.w, ratio ) * newVert.w<br /> newVert.z = lerp( vert1.z / vert1.w, vert2.z / vert2.w, ratio ) * newVert.w<br /> <br /> lerp is linear interpolation - lerp(a,b,ratio) = ( a + (b - a) * ratio )<br /> ratio is Yours d1 variable<br /> <br /> Basic idea is that w isn&#39;t linear in screen space, but 1/w is.<br /> <br /> <blockquote class="ipsQuote" data-ipsquote data-ipsquote-contentapp="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contenttype="forums" data-ipsquote-username="bwhiting"><br /> p.s. not to sure what the difference between w and w&#39;?<br /> </blockquote><br /> <br /> It was my mistake, it should be w&#39; = 1 / w in my previous post.[font=&quot;arial, verdana, tahoma, sans-serif&quot;]<br /> <br /> <blockquote class="ipsQuote" data-ipsquote data-ipsquote-contentapp="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contenttype="forums" data-ipsquote-username="davidleonardcook"><br /> One approach is to clip in world space, by using the plane equations for the six faces of the view frustum. Then your clip test reduces to finding a line-vs-planeintersection. <br /> </blockquote><br /> <br /> I don&#39;t think clipping in world space is a good idea. First - clip test isn&#39;t efficient and second - there will be precision errors (a vertex may fall outside the viewport).

This topic is closed to new replies.

Advertisement