麻烦Phong底纹 [英] Trouble with Phong Shading

查看:118
本文介绍了麻烦Phong底纹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在根据 Phong模型撰写着色器。我试图实现这个公式:





其中n是法线,l是光的方向,v是相机的方向,r是光线反射。这些方程式在维基百科文章中有更详细的描述。



截至目前,我只测试定向光源,因此没有衰减。环境术语被添加到下面的函数之外,它运行良好。如果点积是负数,则函数maxDot3返回0,如通常在Phong模型中所做的那样。



以下是我的代码实现上述等式:

  #includePhongMaterial.h

PhongMaterial :: PhongMaterial(const Vec3f& diffuseColor,const Vec3f& specularColor,
float exponent,const Vec3f& transparentColor,
const Vec3f& reflectiveColor,float indexOfRefraction){

_diffuseColor = diffuseColor;
_specularColor = specularColor;
_exponent =指数;
_reflectiveColor = reflectiveColor;
_transparentColor = transparentColor;



$ b 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-1);
r.Normalize();

return(_diffuseColor * nl + _specularColor * powf(v.maxDot3(r),_ exponent))* lightColor;
}

不幸的是,镜面词似乎因为某些原因而消失。我的输出:





正确输出:


第一个球体只有漫反射和环境阴影。它看起来不错。其余的有镜面词汇,并产生不正确的结果。我的实现出了什么问题?

解决方案

这条线看起来不对:

  r = 2 * nl *(nl); 

2 * nl 是一个标量,所以这是朝着 n -l <​​/ code>的方向,这显然是错误的方向(你也将结果归一化,所以乘以 2 * nl 什么都不做)。考虑 n l 指向同一方向。结果 r 也应该在同一个方向,但是这个公式产生零向量。



我认为你的圆括号错位。我相信它应该是:

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

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


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

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

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

Here's my code implementing 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*(n-l);
        r.Normalize();

        return (_diffuseColor*nl + _specularColor*powf(v.maxDot3(r),_exponent))*lightColor;
}

Unfortunately, the specular term seems to disappear for some reason. My output:

Correct output:

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

解决方案

This line looks wrong:

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

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

I think your parentheses are misplaced. I believe it should be:

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

We can check this formula on two boundaries easily. When n and l point in the same direction, nl is 1 so the result is also the same vector which is correct. When l is tangent to the surface, nl is zero and the result is -l which is also correct.

这篇关于麻烦Phong底纹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆