• Create Account

## Specular Highlights Disappear Up Close

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

4 replies to this topic

### #1Aressera  Members

Posted 16 March 2014 - 09:00 PM

I've noticed that in my engine the specular highlights for shiny objects go away for objects that are closer to the camera. Interestingly, increasing the scale factor for the objects allows the camera to get much closer before the highlights disappear. Therefore, I don't think this is an inherent property of the geometry of specular lighting.

I am using a normalized Blinn-Phong lighting model and this issue exists for both point and directional light sources. I've checked my shader against examples online and it seems to match them. In addition, the same behavior was observed with the Phong lighting model.

I've attached two screenshots showing a series of 4 shiny objects. In the first, the highlight is most prominent on the distant object and least prominent for the closest. In the second, the scene was scaled by 5x, and the highlights are similar for all objects.

Has anyone else noticed this artifact? My only guess is that there is some problem with how I am computing the normal matrix (transpose of the inverse of the upper 3x3 of model view matrix) or view-space light direction (model view matrix * world space direction), but there doesn't seem to be any negative effect on the normals themselves or the diffuse lighting.

Edit: I was just playing around with it again and found that if I calculate the view-space half vector once for the entire view, rather than per-pixel, the highlights behave the way they should.

#### Attached Thumbnails

Edited by Aressera, 16 March 2014 - 09:11 PM.

### #2Hodgman  Moderators

Posted 16 March 2014 - 10:18 PM

Are your light, view, normal, half, etc vectors all normalized?

### #3Aressera  Members

Posted 16 March 2014 - 10:34 PM

Yes, I have made sure they are all normalized.

I rewrote my shader and I managed to fix the problem (even with per-pixel half vectors). The issue was how I was calculating the direction to the surface. I was using a 4D vector (x,y,z,w) to represent position, and neglecting the fact that the w component was non-zero. Therefore, the computed half vector wasn't correct.

// Old code
vec4 surfacePosition = interpolatedPosition;
vec4 surfaceDirection = normalize( surfacePosition );

// New code
vec4 surfacePosition = vec4( interpolatedPosition.xyz / interpolatedPosition.w, 1.0 );
vec4 surfaceDirection = vec4( normalize( surfacePosition.xyz ), 0.0 );


### #4Hodgman  Moderators

Posted 16 March 2014 - 11:23 PM

normalize( surfacePosition ) ... normalize( surfacePosition.xyz )
Yeah you've got to be careful with that stuff! It's very easy to ask the GPU to give you unit-length 4D vector instead of a unit-length 3D vector.

Internally, modern GPU's are actually all scalar (they work with floats, not vec4's) so it's best to always use the most appropriate variable types, e.g. a vec3 instead of a vec4 with an unused w component.

### #5Aressera  Members

Posted 17 March 2014 - 03:16 PM

normalize( surfacePosition ) ... normalize( surfacePosition.xyz )
Yeah you've got to be careful with that stuff! It's very easy to ask the GPU to give you unit-length 4D vector instead of a unit-length 3D vector.

Internally, modern GPU's are actually all scalar (they work with floats, not vec4's) so it's best to always use the most appropriate variable types, e.g. a vec3 instead of a vec4 with an unused w component.

Good to know, I guess I'm used to working with SIMD so I figured 4 component vectors would be better.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.