0
\$\begingroup\$

I'm having some issues with specular lights, to be more specific, the specular color seems to be flickering when I set high power, like 512 (I set the specular color to green, so you can see better):

http://i.imgur.com/PY0cmJA.gif

And when a power like 32 is used, everything seems ok:

1

Pixel shader hlsl:

pin.NormalW = normalize(pin.NormalW);

float3 toEyeW = normalize(gEyePosW - pin.PosW);

// Start with a sum of zero.
float4 ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 spec    = float4(0.0f, 0.0f, 0.0f, 0.0f);

// Sum the light contribution from each light source
float4 A, D, S;

ComputeDirectionalLight(gMaterial, gDirLight, pin.NormalW, toEyeW, A, D, S);

ambient += A;
diffuse += D;
spec    += S;

float4 litColor = ambient + diffuse + spec;

litColor.a = gMaterial.Diffuse.a;

return litColor;

ComputeDirectionalLight function:

void ComputeDirectionalLight(Material mat, DirectionalLight L, 
  float3 normal, float3 toEye,
out float4 ambient,
out float4 diffuse,
out float4 spec)
{
      // Initialize outputs.
      ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
      diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
      spec = float4(0.0f, 0.0f, 0.0f, 0.0f);

      // The light vector aims opposite the direction the light rays travel.
      float3 lightVec = -L.Direction;

      // Add ambient term.
      ambient = mat.Ambient * L.Ambient;

      // Add diffuse and specular term, provided the surface is in 
      // the line of site of the light.

      float diffuseFactor = dot(lightVec, normal);

      // Flatten to avoid dynamic branching.
      [flatten]
      if (diffuseFactor > 0.0f)
      {
          float3 v = reflect(-lightVec, normal);
          float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w);

          diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
          spec = specFactor * mat.Specular * L.Specular;
      }
  }

I'm using DirectX 11.

\$\endgroup\$
  • \$\begingroup\$ This does not look like traditional specular highlight.. Are you sure you are making one? \$\endgroup\$ – Kromster Nov 24 '14 at 6:03
  • \$\begingroup\$ What do you mean? Maybe It's because directional light source is almost in front of the sphere? \$\endgroup\$ – user41092 Nov 24 '14 at 9:31
  • \$\begingroup\$ Distance to light source is not used in the specular equation. \$\endgroup\$ – Kromster Nov 24 '14 at 10:53
0
\$\begingroup\$

The problem is that L.Direction vector is not normalized, so the dot product "max(dot(v, toEye)" is calculating |v|*cos Θ instead of cos Θ, which is not what we want. So normalizing it on CPU side solves the problem. Thank you @snake5 for helping me on chat with it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy