gpt4 book ai didi

c++ - 什么会导致 Phong 镜面反射着色产生色域溢出?

转载 作者:太空狗 更新时间:2023-10-29 22:53:25 27 4
gpt4 key购买 nike

我目前正在用 C++ 实现一个基本的光线追踪器。到目前为止效果很好,哑光 Material (具有环境光和漫反射 brdf)到目前为止按预期工作。

添加镜面高光会导致完整的 Phong Model这正是我试图做的。

不幸的是,我遇到了色域溢出,镜面反射常数 ks 和指数的各种值。以下是一些示例。

// Sphere material definition:
ka = 0.9;
kd = 1.0;
ks = 0.3;
exp = 1.0;
color = rgb(1.0, 1.0, 0.98);

图片: http://dl.dropbox.com/u/614366/cornell_1.png

// Sphere material definition:
ka = 0.9;
kd = 1.0;
ks = 0.3;
exp = 20.0; // only changed exp
color = rgb(1.0, 1.0, 0.98);

图片: http://dl.dropbox.com/u/614366/cornell_2.png

// Sphere material definition:
ka = 0.9;
kd = 1.0;
ks = 0.1; // only changes here
exp = 0.1; // and here
color = rgb(1.0, 1.0, 0.98);

图片: http://dl.dropbox.com/u/614366/cornell_3.png

以下是代码的一些相关摘录:

在 raycast.cpp 中

namespace {
const float floatmax = std::numeric_limits<float>::max();
}

rgb
RayCast::trace ( const Ray& ray ) const
{
HitRecord rec(scene_ptr_);
float tmax = floatmax;
float tmin = 0.0;

if ( scene_ptr_->shapes.hit(ray,tmin,tmax,rec) )
{
rec.ray = ray;
return rec.material_ptr->shade(rec);
}

return scene_ptr_->bgcolor;
}

在 phong.cpp 中

rgb
Phong::shade ( HitRecord& hitrec ) const
{
Vector wo = - hitrec.ray.dir();

rgb L = ambient_brdf_ptr_->rho(hitrec,wo) *
hitrec.scene_ptr->ambient_ptr->L(hitrec);

int num_lights = hitrec.scene_ptr->lights.size();

for (int i = 0; i < num_lights; ++i)
{
Vector wi = hitrec.scene_ptr->lights[i]->get_direction(hitrec);
float ndotwi = dot(hitrec.normal, wi);

if ( ndotwi > 0.0 )
{
L += ( diffuse_brdf_ptr_->f (hitrec, wo, wi) +
specular_brdf_ptr_->f(hitrec, wo, wi)
) * hitrec.scene_ptr->lights[i]->L(hitrec) * ndotwi;
}
}

return L;
}

在 specular.cpp 中

namespace {
const rgb black(0.0,0.0,0.0);
}

rgb
Specular::f ( const HitRecord& hitrec, const Vector& wo, const Vector& wi ) const
{
rgb L(0,0,0);
float ndotwi = dot(hitrec.normal, wi);

Vector r = -wi + 2.0 * hitrec.normal * ndotwi;
float rdotwo = dot(r, wo);

// reflection detected
if ( rdotwo > 0.0 )
L = ks_ * pow(rdotwo, exp_);

return L;
}

rgb
Specular::rho ( const HitRecord& hitrec, const Vector& wo ) const
{
return black;
}

在 sphere.cpp 中

bool
Sphere::hit ( const Ray& ray, interval_t tmin, interval_t tmax, HitRecord& hitrec ) const
{
Vector org = ray.origin() - center_;
Vector dir = ray.dir();
float a = dot(dir, dir);
float b = dot(dir, org) * 2;
float c = dot(org, org) - pow(radius_, 2);
float discriminant = pow(b,2) - 4*a*c;

if ( discriminant > 0 )
{
discriminant = sqrt(discriminant);
double t = ( -b - discriminant ) / ( 2*a );

if ( t < tmin )
t = ( -b + discriminant ) / ( 2*a );

if ( t > tmin and t < tmax )
{
// hit detected
hitrec.t = t;
hitrec.hit = true;
hitrec.normal = unify( t*ray.dir() + org );
hitrec.material_ptr = material_ptr_;
hitrec.hitpoint = ray.origin() + t * ray.dir();
hitrec.ray = ray;

return true;
}
}

return false;
}

您是否知道可能导致错误的地方?导致这种结果的可能因素有哪些?

提前致谢,帕特里克。

最佳答案

问题的解决方案是必须统一 wo vector (在 Phong::shade 中)。

关于c++ - 什么会导致 Phong 镜面反射着色产生色域溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2384405/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com