Phong Shading的麻烦

Bab*_*aan 6 c++ graphics shader raytracing

我根据Phong模型写了一个着色器.我正在尝试实现这个等式:

在此输入图像描述

其中n是法线,l是光的方向,v是摄像机的方向,r是光反射.维基百科文章中更详细地描述了这些等式.

截至目前,我只测试定向光源,因此没有r ^ 2衰减.环境术语在以下功能之外添加,效果很好.如果点积为负,则函数maxDot3返回0,这通常在Phong模型中完成.

这是我的代码实现上面的等式:

#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*(n-l);
        r.Normalize();

        return (_diffuseColor*nl + _specularColor*powf(v.maxDot3(r),_exponent))*lightColor;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,由于某种原因,镜面术语似乎消失了.我的输出:

在此输入图像描述

正确输出:

在此输入图像描述

第一个球体只有漫反射和环境阴影.看起来不错.其余的都有镜面术语,并产生不正确的结果.我的实施有什么问题?

rha*_*oto 4

这行看起来是错误的:

r = 2*nl*(n-l);
Run Code Online (Sandbox Code Playgroud)

2*nl是一个标量,所以它的方向是n - l,这显然是错误的方向(您还对结果进行了归一化,因此乘以2*nl没有任何作用)。考虑何时nl指向同一方向。结果r也应该是相同的方向,但该公式产生零向量。

我认为你的括号放错地方了。我认为应该是:

r = (2*nl*n) - l;
Run Code Online (Sandbox Code Playgroud)

我们可以很容易地在两个边界上检查这个公式。当nl指向同一方向时,nl为 1,因此结果也是相同的向量,这是正确的。当l与曲面相切时,nl为零,结果也是-l正确的。