•      Sign In
• Create Account

Need scary sound effects or creepy audio loops for your next horror-themed game? Check out Highscore Vol.3 - The Horror Edition in our marketplace. 50 sounds and 10 loops for only \$9.99!

# interpolating scalar instead of vector

7 replies to this topic

### #1JohnnyCode  Members   -  Reputation: 228

Like
0Likes
Like

Posted 02 October 2013 - 02:07 PM

Hi,

In most simple shader of a light, a vertex postion gets subtracted from light postion and the result is normalized. Then, this vector is an input into pixel function, along with normal of the vertex. Thus, pixel shader interpolates this light vector and the normal vector and in the function it dots the two vectors getting light component, a single float. My question is, wheather I could dot those two vectors in vertex function already, and pass the component single float into pixel function. Would it result in the same value as the component would be interpolated?

Sponsor:

### #2unbird  Crossbones+   -  Reputation: 3456

Like
3Likes
Like

Posted 02 October 2013 - 02:30 PM

Nope, that would be vertex lighting (here's an example with Gouraud shading), because you do your lighting calculation per vertex, not per pixel. A high triangle count can give you pretty good if not even equal result though.

Edited by unbird, 02 October 2013 - 02:31 PM.

### #3Zaoshi Kaba  Crossbones+   -  Reputation: 2156

Like
1Likes
Like

Posted 02 October 2013 - 02:31 PM

Yes you can. No, value will be different.

### #4BornToCode  Members   -  Reputation: 768

Like
0Likes
Like

Posted 08 October 2013 - 11:54 AM

If you go down that route then it will interpolate across vertices instead of pixels. That basically means all the pixels across vertex bounds will have the same value.

Edited by BornToCode, 08 October 2013 - 11:55 AM.

### #5mhagain  Crossbones+   -  Reputation: 5545

Like
4Likes
Like

Posted 08 October 2013 - 01:35 PM

As a general rule, if you can plot a function as a straight line, then you can safely do the calculation in your vertex shader and rely on interpolation for the rest.  If a function plots as a curve (or anything other than a straight line, e.g. a wave) then you can't (well, you can, but you'll either need an extremely fine level of tesselation or you'll get artefacts).

Normalization involves a square root, and a square root plots as a curve, so you should do that in your pixel shader.  However, your first calculation (lpos - vpos) is a straight line, so that's OK to do in your vertex shader.

Likewise, a dotproduct can be expressed as a square; if you've got dot (x, y) and if x == y, then (assuming 3 component vectors) dot (x, y) = x.x2 + x.y2 +x.z2.  Again, this plots as a curve, so it's pixel shader work.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.

### #6JohnnyCode  Members   -  Reputation: 228

Like
0Likes
Like

Posted 11 October 2013 - 09:11 AM

As a general rule, if you can plot a function as a straight line, then you can safely do the calculation in your vertex shader and rely on interpolation for the rest.  If a function plots as a curve (or anything other than a straight line, e.g. a wave) then you can't (well, you can, but you'll either need an extremely fine level of tesselation or you'll get artefacts).

Normalization involves a square root, and a square root plots as a curve, so you should do that in your pixel shader.  However, your first calculation (lpos - vpos) is a straight line, so that's OK to do in your vertex shader.

Likewise, a dotproduct can be expressed as a square; if you've got dot (x, y) and if x == y, then (assuming 3 component vectors) dot (x, y) = x.x2 + x.y2 +x.z2.  Again, this plots as a curve, so it's pixel shader work.

uff, my main concern is to put normalization to vertex shader, and mainly becouse of reciprocal computation. Division is extremly expensive. I believe that unit vector interpolates into an unit vector, since barycentric coordinates sum is always 1.0. So I just will dot the interpolated light direction with interpolated normal in pixel shader.

### #7Brother Bob  Moderators   -  Reputation: 6404

Like
2Likes
Like

Posted 11 October 2013 - 09:16 AM

The linear interpolation between two unit vectors is not itself a unit vector. Normalization is a non-linear operation, thus order is relevant: normalization followed by interpolation is not the same thing as interpolation followed by normalization.

### #8mhagain  Crossbones+   -  Reputation: 5545

Like
2Likes
Like

Posted 11 October 2013 - 12:12 PM

uff, my main concern is to put normalization to vertex shader, and mainly becouse of reciprocal computation. Division is extremly expensive.

I wouldn't be so sure about that, and it seems as though you may be pre-emptively optimizing, with perhaps a smidgin of assuming that rules which hold good for CPUs also hold good for GPUs.

In the old days (i.e. ~10 years ago) it was common to see a cubemap lookup used as a replacement for per-pixel normalization.  Nobody does that anymore, and with very good reason: the performance of ALU instructions has increased at a rate that has far outpaced anything else, and - if your shader compiler optimizes them to interleave with texture lookups - they can often be had effectively for free.

In other words, pulling tricks to avoid a division is no longer something worth worrying about, at least not in the common case.  If you know that you're programming to a GPU on which division is expensive (i.e. the vendor has documented it as so), then is the time to start looking at alternatives.  Not before.

So just normalize in your pixel shader and be done with it; I'm willing to bet that you'll find very little (or even no) significant performance difference.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.

PARTNERS