I'm trying to implement the Ward shading model, the anisotropic, computationally efficient version:

enter image description here enter image description here

This is how I made it:

float alphaX=0.5, alphaY=0.5; // asinotropic roughness
float minFloat= 1.e-6; 

vec4 Ward(vec3 L, vec3 N, vec3 V)
    vec3 H= normalize(L+V);
    float NdotL= max(dot(N,L),0.0);
    float NdotV= max(dot(N,V),0.0);

    vec3 e= vec3(1.0,0.0,0.0);
    vec3 T= normalize(cross(N,e));
    vec3 B= normalize(cross(N,T));
    float HdotT= max(dot(H,T),0.0);
    float HdotB= max(dot(H,B),0.0);
    float HdotN= max(dot(H,N),0.0);

    float beta= -2.0 * ( pow(HdotN/alphaX, 2.0) + pow(HdotB/alphaY,2.0) ) / (1.0 + HdotN);
    float den= max(minFloat, 4.0 * pi * alphaX * alphaY * sqrt(NdotL * NdotV) );
    vec4 specular= Ps * 1.0/den * exp(beta);
    return (Pd + specular) * NdotL;

But I get a result similar to a lambertian surface or Oren-Nayar model, where the specular component is absent:

enter image description here

enter image description here

  • \$\begingroup\$ Shouldn't the first HdotN in beta be HdotT ? \$\endgroup\$
    – Ikun
    Commented Feb 25, 2020 at 0:40

2 Answers 2


The problem was solved by just changing the e vector to (0,0,-1). I also needed to clamp the returned color:

return clamp((Pd + specular) * NdotL, 0.0, 1.0);


enter image description here

  • \$\begingroup\$ Could you attach a "fixed" render result to the answer? :) \$\endgroup\$
    – Kromster
    Commented Dec 13, 2013 at 11:24
  • \$\begingroup\$ Added it, @KromStern . \$\endgroup\$ Commented Dec 13, 2013 at 14:07

Your alpha values are too high. You have them both set to 0.5, which represents a very rough surface, which will have a very broad and diffuse specular highlight. Try setting them to something like 0.01, and you should get a smaller, hotter highlight.

The alpha values in the Ward distribution work similarly to the "m" value in the Beckmann distribution - they control the typical slope of microfacets, so small values correspond to smooth, glossy surfaces.

  • \$\begingroup\$ Even with very low values of anisotropic roughness I don't see any part of the teapot shining, like it does with Blinn-Phong model. \$\endgroup\$ Commented Dec 5, 2013 at 20:51
  • \$\begingroup\$ @RamyAlZuhouri What is Ps set to? Otherwise, your code looks good to me. Although you should probably leave out the factor of pi in the denominator (see to pi or not to pi). \$\endgroup\$ Commented Dec 6, 2013 at 2:15
  • \$\begingroup\$ Ps is the specular component (specular material color multiplied for the specular light), Pd the diffuse component. \$\endgroup\$ Commented Dec 6, 2013 at 10:47
  • \$\begingroup\$ I removed the pi term and it's like before: the specular component is too low. \$\endgroup\$ Commented Dec 6, 2013 at 11:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .