# parallax mapping

I have a trouble with applying parallax mapping shader to a non-square polygons.

For example when I put whole texture (square area) on non-square geometry (e.g. trapezoid) it looks distorted then.

Guys any thoughts on this? Is it possible to apply this technique to meshes that consist of different quads, sphere, for example?

you understand why it looks distorted, surely?

It looks distorted when part from texture has different shape than geometry. All tutorials & docs I read use square (GL_QUADs) and put whole texture on it.

What should I do in case of incomplete shapes? In my case it is square in texture space and trapezoid in world space.

I suspect root of the problem is different āoffsetā vectors in different parts of primitive. In case of square it is constant -

P = -E.xy * scale / E.z; (glsl)

Any thoughts?

I donāt need general solution, but only in case of trapezoidā¦

Simply use trapezoid portion of texture when applying to trapezoid geometry.
Otherwise tangent and binormal vectors may vary across polygons in a way you wonāt be able to control easily - cn be platform dependent since different hardware may split quad into a pair of triangles in different way.

It looks distorted when part from texture has different shape than geometry
At least knackered had some laugh againā¦

Simply use trapezoid portion of texture when applying to trapezoid geometry.
Itās wrong way.

The trick is to map square to trapezoid. Iām applying parallax on a part_of_sphere mesh which consists of set of trapezoids. Whole image is rectangular, and I get square subimages and pass them as textures to this trapezoidal parts.

Imagine what could be in case of trapezoid texture parts %)

Otherwise tangent and binormal vectors may vary across polygons in a way you wonāt be able to control easily
Why do you think so? Actually I compute TBN matrix in vertex shader (itās easy in case of sphere, i need only a normal for it (which are already specified with geometry)). Then all stuff is interpolated and passed to frag shaderā¦

Subdivide or use the 4th texture coordinate homogeneous w to apply the ātrapezoidalā projection.

You cannot simply apply quad texture to trapezoid without some perspective tricks, just as dorbie said.

Also, I donāt know, how parallax would deal with projective texturing.

Here are some links on fourth texture coordinate:
http://www.r3.nu/~cass/qcoord/

Thanks for link, Jackis. Maybe this is itā¦

However, I think GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST does the same, doesnāt it? I tried to use it but with no luckā¦

Perspective correction hints has nothing to do with it. The way the texture coordinates are interpolated over a quad is wrong to begin with. If the texture coordinates are not what you want them to be in the first place, you cannot just hint for them to magically become correct. You need perspective correct texture coordinates in the first place to get a perspective correct interpolation.

No, perspective correction is always enabled on modern chipsets, and this hint actually does nothing. And the main thing is that you canāt simply apply rectangular texture region to trapezoid.

EDIT: Bob was the first one

Otherwise tangent and binormal vectors may vary across polygons in a way you wonāt be able to control easily

Why do you think so?
Thatās why:

Each quad is rendered as 2 triangles and that makes tangent space change suddenly in the middle of GL_QUAD if texture shape is different than polygon.

OK. I implemented āqā coordinate usage but only for āsā coordinate to prevent shrinking in vertical direction. It looks much better, but not excellent. See this
screenshots gallery . Notice hills bending on second image.

Also I rejected to use smoothed normals.
What Iām doing wrong? k_szczech, could you please help with proper TBN handling in this case? Is there any applicable solution?

One little questionā¦
You said - you did perspective division only for āsā component - so, as I understand, you had to do it manually, leaving ātā as is, wasnāt it?
I ask it, because OpenGL pipeline generally divides all three āstrā components by āqā, if projective texture lookup is made.

About your pictures. Seems, like somewhere in your formulaes, you forgot that you are working in somehow projected space (I mean, you apply texture shift before/after projective texlookup was done, and you forget to consider, that you have different T derivativeās normas).

Your problem seems not to be related to the situation I presented on the picture.
It rather looks like some bug in your code - some value is not divided by another or something like that.
It just seems like when performing displacement your shader travels faster in t coordinate than s coordinate.

By the way - for testing purposes you should probably use a texture with regular shape - itās easier to find some small non-linear distortions this way.

you had to do it manually, leaving ātā as is, wasnāt it?
Yep, I specify only funky āsā & āqā coordinates in glMultitexCoord4f(ā¦). But in fragment shader I divide āsā only: gl_TexCoord[0].s /= gl_TexCoord[0].q. As I said, I choose such way to avoid vertical shrinking as displayed in your earlier postsā link.

use a texture with regular shape
I tried that, just at the beginning of my investigations. Full texture on sqare geometry. I works well.

Besides, I can see some distortions even if I map square texture to rectangle (not sqare geometry).

I suppose this can be a result of

travels faster in t coordinate than s coordinate.
PS I tried out different divisions on offset vector in frag shader. This is really annoying thingā¦

rectangle & square

rectangle is 2:1 (x:y)

Pay close attention to how you calculate vector used for travelling across texture space.
Look at what values you use for s, t and q (depth).
Perhaps s is taken from normalized vector and t from unnormalized?

Simply compare codepath for s and t with codepath for q.

I found way to resolve case with rectangle. I scale this P vector in that direction.

But the real problem is, how to scale it in case of trapezoid. Even step is not constant during the search. (this causes non linear banding of the hills in my screen shots, in case of rectangle they are linear).

All this non-linear mappings make me sick :eek: . I have no idea how to apply āqā coordinate to P vector. Guys it is urgent. Any links are useful for me (I havenāt found any on this topic yetā¦)

Simply compare codepath for s and t with codepath for q.
Could you please give any example on this? In my case (geometry is sphere) I can compute q coord in vertex shader:

``````q = sqrt(1.0 - gl_Vertex.y * gl_Vertex.y)
gl_TexCoord[0].s *= q;

``````

In fragment:

``````gl_TexCoord[0].s /= q;

``````

In such way I got rid of specifying q in programā¦ It really works.

Here
you can see pairs of āshould beā & ācurrently isā pictures. Notice that on first search level (height is 1.0) they are similar, but on next levels we can see obvious differences (non-linear !!!).

āShould beā examples I rendered using non-square texture region (affine texture mapping).

Iāve found Paul S. Heckbertās āFundamentals of texture mapping and image warpingā there is some useful info on bilinear / affine / projective mappings. However, I canāt realize how to apply non-linear P changes. Any new ideas?
Itās not ānormalizeā issue for sureā¦