光线跟踪器-实现阴影
Raytracer - implementing shadows
我正在为一项本应实现光线跟踪器的任务而苦苦挣扎。我已经完成了一个基本的光线跟踪器,但我几乎不知道如何实现阴影。我将包括我们必须编程的一些函数和我们给出的一些数据结构。我想我在理论上知道该做什么,但我完全不知道如何正确实施这些。
void Raytracer::computeShading( Ray3D& ray ) {
LightListNode* curLight = _lightSource;
Ray3D shadowRay;
for (;;) {
if (curLight == NULL) break;
// Each lightSource provides its own shading function.
// Implement shadows here if needed.
if (!ray.intersection.none) {
shadowRay.origin = ray.intersection.point + 0.01 * ray.dir;
shadowRay.dir = (curLight->light->get_position() - ray.intersection.point);
shadowRay.dir.normalize();
}
curLight->light->shade(ray);
curLight = curLight->next;
}
}
}
Colour Raytracer::shadeRay( Ray3D& ray ) {
Colour col(0.0, 0.0, 0.0);
traverseScene(_root, ray);
// Don't bother shading if the ray didn't hit
// anything.
if (!ray.intersection.none) {
computeShading(ray);
col = ray.col;
}
// You'll want to call shadeRay recursively (with a different ray,
// of course) here to implement reflection/refraction effects.
return col;
}
struct Intersection {
// Location of intersection.
Point3D point;
// Normal at the intersection.
Vector3D normal;
// Material at the intersection.
Material* mat;
// Position of the intersection point on your ray.
// (i.e. point = ray.origin + t_value * ray.dir)
// This is used when you need to intersect multiply objects and
// only want to keep the nearest intersection.
double t_value;
// Set to true when no intersection has occured.
bool none;
};
// Ray structure.
struct Ray3D {
Ray3D() {
intersection.none = true;
}
Ray3D( Point3D p, Vector3D v ) : origin(p), dir(v) {
intersection.none = true;
}
// Origin and direction of the ray.
Point3D origin;
Vector3D dir;
// Intersection status, should be computed by the intersection
// function.
Intersection intersection;
// Current colour of the ray, should be computed by the shading
// function.
Colour col;
};
endif
我们应该在computerShading中实现阴影,尽管我认为我们也必须在shadeRay中做一些事情,但我真的不确定。我不确定在computerShading中,我应该在计算光线交点之前还是之后计算光线交点或创建新光线,或者我必须先计算新光线并计算交点。我们还有一个颜色函数。我还为单位正方形和球体实现了一些相交函数,两者都有效,但我只是不知道如何获得阴影!我真的很失落。请提供任何帮助都将是伟大的!
编辑:好的,所以我添加了一些东西,但我没有得到任何阴影,或者我得到了一个完整的黑色图像,这取决于参数的变化:
void Raytracer::computeShading( Ray3D& ray ) {
LightListNode* curLight = _lightSource;
for (;;) {
Ray3D shadowRay;
if (curLight == NULL) break;
// Each lightSource provides its own shading function.
// Implement shadows here if needed.
shadowRay.origin = ray.intersection.point + 0.01*ray.dir;
shadowRay.dir = curLight->light->get_position() - ray.intersection.point;
shadowRay.dir.normalize();
traverseScene(_root, shadowRay);
if (shadowRay.intersection.t_value >= 0.0 && shadowRay.intersection.t_value <= 1.0) {
shadowRay.col = Colour(0,0,0);
}
else {
curLight->light->shade(ray);
}
curLight = curLight->next;
}
}
其中遍历遍历每个对象并进行交集,并放置适当的值。也许我没有把这些东西放在合适的地方。
您应该在代码中的某个位置有一个函数来进行交集,即在Ray3D::intersection
中填充正确的值,对吗?创建shadowRay
后,必须调用该函数来检查shadowRay
是否与场景中的任何对象相交,并且该相交点位于原点和灯光位置之间。如果存在这样的交点,则当前点不会被该灯光照亮。
哪里有
// You'll want to call shadeRay recursively (with a different ray,
// of course) here to implement reflection/refraction effects.
你应该有射线击中的点的位置。您应该在该点和光源之间构建光线。如果光线与某个点相交(无论在哪里),则该点处于阴影中,如果不相交,则它将被照亮。一旦您有了这些信息,就将其传递给计算着色,以了解您是否应用了全乒乓模型(或您正在使用的任何模型),是否没有交集,或者只有环境色(如果有)。
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 光线跟踪器-实现阴影
- 解释在opencv中实现的阴影检测代码的工作原理
- 在光线追踪器中实现软阴影