1

Blinn-phong shading...?

Normals Blinn-phong

So the issue I'm having, as the above image hopefully illustrates, is that I can't seem to get my specular highlights to shade smoothly. The problem is the abrupt cutoff along face edges, which shouldn't be happening. The diffuse lighting appears to be working quite well, and it uses the same interpolated values. Here's the code for the blinn-phong specular highlights:

vec3 halfAngle = normalize(lightDirection.xyz + viewRay);

float blinnTerm = dot(normal.xyz, halfAngle);
blinnTerm = clamp(blinnTerm, 0.0f, 1.0f);
blinnTerm = pow(blinnTerm, 300.0f);

float specIntensity = intensity * blinnTerm;

vec4 specColour = specIntensity * specColour;

lightDirection is constant, it's infinitely far away (ie. the sun). As for viewRay, it's computed in the vertex shader like so, using the projection matrix:

viewRay = vec3(-(UV.x * 2.0f - 1.0f) / projection[0].x,
               -(UV.y * 2.0f - 1.0f) / projection[1].y,
                     1.0f);

I'm using deferred rendering, which is where the UV values come from (rendering to a full screen texture).

The only thing I can think of is that the normal interpolation just isn't smooth enough. But if that's the case, how would I go about fixing it? (I'm storing the normals as 16-bit floats, but upping it to 32 bits didn't make a difference).

Fault
  • 420
  • 3
  • 17
  • I think your viewRay computations might be off. In my deferred renderer, I'm calculating the view vector from object's world position (one of the G-buffer textures - does your UV contain this as well?) and camera's world position (passed in as uniform). Then a simple subtraction between those points gives you the view vector. I don't follow the logic of your viewRay computation and can't say whether it should work or not. – Arttu Peltonen Feb 26 '14 at 10:13
  • My first thought was that the normals weren't stored with sufficient precision, but I see you have that covered. What sort of field-of-view are you using? That highlight looks quite large for a 300 specular power. – GuyRT Feb 26 '14 at 11:28
  • @ArttuPeltonen The viewRay should be correct. Essentially what I'm doing is multiplying clip-space coordinates by the inverse perspective matrix to get camera-space coordinates. This allows me to reconstruct position using depth information, and thus save memory bandwidth (one less texture to upload). – Fault Feb 26 '14 at 18:25
  • @GuyRT Field of view is 45 degrees, but I was intentionally boosting the specIntensity to exaggerate the issue. In my answer it's the same 300 term, just... subdued a little. – Fault Feb 26 '14 at 18:27

1 Answers1

3

enter image description here

And the teapot is now fixed! There was an issue with interpolating the normals, but thankfully it was an easy fix; I was normalizing the normals in my vertex shader, then interpolating, rather than interpolating first and then normalizing. It's still not perfect, but it's certainly an improvement!

The lesson here: if your image looks flat, you're probably doing something you shouldn't be doing in the vertex shader.

Fault
  • 420
  • 3
  • 17
  • Woah, your advice completely saved me, thanks! I had a very similar problem. Could you perhaps expand a bit on why interpolating 'normalized' normals is bad? I don't completely understand why this fixes it. – EarthenSky Apr 15 '21 at 04:58