Phong Shading Issues

I am writing a shader according to the Phong Model . I am trying to implement this equation:

enter image description here

where n is normal, l is the direction of light, v is the direction to the camera, r is the reflection of light. The equations are described in more detail in the Wikipedia article.

As of now, I am only testing on directional light sources, so there is no recession r ^ 2. The external term is added beyond the function below, and it works well. The maxDot3 function returns 0 if the point product is negative, as is usually done in the Phong model.

Here is my code that implements the above equation:

#include "PhongMaterial.h" PhongMaterial::PhongMaterial(const Vec3f &diffuseColor, const Vec3f &specularColor, float exponent,const Vec3f &transparentColor, const Vec3f &reflectiveColor,float indexOfRefraction){ _diffuseColor = diffuseColor; _specularColor = specularColor; _exponent = exponent; _reflectiveColor = reflectiveColor; _transparentColor = transparentColor; } Vec3f PhongMaterial::Shade(const Ray &ray, const Hit &hit, const Vec3f &dirToLight, const Vec3f &lightColor) const{ Vec3f n,l,v,r; float nl; l = dirToLight; n = hit.getNormal(); v = -1.0*(hit.getIntersectionPoint() - ray.getOrigin()); l.Normalize(); n.Normalize(); v.Normalize(); nl = n.maxDot3(l); r = 2*nl*(nl); r.Normalize(); return (_diffuseColor*nl + _specularColor*powf(v.maxDot3(r),_exponent))*lightColor; } 

Unfortunately, the mirror term seems to disappear for some reason. My conclusion:

enter image description here

The correct conclusion:

enter image description here

The first sphere has only diffuse and ambient shading. It looks right. The rest have mirror expressions and give incorrect results. What is wrong with my implementation?

+6
source share
1 answer

This line looks wrong:

 r = 2*nl*(nl); 

2*nl is a scalar, so it is in the n - l direction, which is clearly the wrong direction (you also normalize the result, so multiplying by 2*nl does nothing). Consider when n and l pointing in the same direction. The result of r should also be in one direction, but this formula gives a zero vector.

I think your parentheses are inappropriate. I believe this should be:

 r = (2*nl*n) - l; 

We can easily verify this formula at two boundaries. When n and l pointing in the same direction, nl is 1, then the result is also the same vector that is correct. When l touches the surface, nl is zero, and the result -l also correct.

+3
source

Source: https://habr.com/ru/post/970600/


All Articles