从零开始使用C ++编写Ray-Tracer
admin
2023-02-11 05:40:07
0

光线追踪是一种基于光传播模拟的3D渲染技术。该技术能够产生非常高的视觉真实感。

原理很简单。它包括滑动每个像素的屏幕像素。对于每个像素,请查看从相机经过该像素的光线是否会与场景中的任何对象相交。像素采用对象的颜色。如果不相交,则像素采用背景色。实际上,像素并不会照原样呈现对象颜色,而是通过称为着色的过程计算出的颜色。着色的目的是使渲染更加真实感。
摄像机的位置以及场景中的所有物体均由3d向量表示,颜色也由3d向量表示。因此,我们需要一直操纵向量。

#ifndef Vect_h
#define Vect_h

#include 

using namespace std;

class Vec3 {
public:
    float X;
    float Y;
    float Z;
    Vec3(float x, float y, float z) : X(x), Y(y), Z(z) {}
    Vec3 operator +(Vec3 vec) {
        return Vec3(X+vec.X,Y+vec.Y,Z+vec.Z);
    }
    Vec3 operator -(Vec3 vec) {
        return Vec3(X-vec.X,Y-vec.Y,Z-vec.Z);
    }
    Vec3 operator *(float scalar) {
        return Vec3(scalar*X,scalar*Y,scalar*Z);
    }
    float dot(Vec3 vec) {
        return X*vec.X+Y*vec.Y+Z*vec.Z;
    }
    float norm() {
        return sqrt(dot(*this));
    }
    Vec3 normalize() {
        return (*this)*(1/norm());
    }

};

#endif

射线与球体的交点:
从零开始使用C ++编写Ray-Tracer
以c为中心,半径为r的球面的方程为:
从零开始使用C ++编写Ray-Tracer
射线(一条线)的方程为:
从零开始使用C ++编写Ray-Tracer
其中o代表射线的原点,d代表射线的方向,t是参数。
那么对于相交点,t必须满足:
从零开始使用C ++编写Ray-Tracer
注意:
从零开始使用C ++编写Ray-Tracer
然后 :
从零开始使用C ++编写Ray-Tracer
这是二次方程。通过添加单位向量d,我们可以:
从零开始使用C ++编写Ray-Tracer
解(如果有)是:
从零开始使用C ++编写Ray-Tracer

    bool Sphere::intersect(Ray& ray, float &t) {
        Vec3 o = ray.get_origin();
        Vec3 d = ray.get_direction();

        Vec3 v = o - Center;

        const float b = 2 * v.dot(d);
        const float c = v.dot(v) - Radius*Radius;
        float delta = b*b - 4 * c;

        if (delta < 1e-4)
            return false;

        const float t1 = (-b - sqrt(delta))/2;
        const float t2 = (-b + sqrt(delta))/2;

        t = (t1 < t2) ? t1 : t2; // get the first intersection only

        return true;
    }

着色:
在开始之前,让我们介绍一些符号。
从零开始使用C ++编写Ray-Tracer
从要着色点到摄像机的单位向量V。
在所考虑点垂直于球体的法向量N。
易得给定球面一点的法向量:


    Vec3 Sphere::get_normal(Vec3 p) {
        return (p - Center) * (-1/(Radius));
    }

因为:在考虑的点p上的每个法向矢量必须与将p连接到球体中心的半径共线。
简单着色工作很好(正面比,此着色器将返回着色法线和入射光线方向的点积的绝对值,在其他渲染器中,也称为入射。):
facing ratio = V . N
它是V和N之间的夹角的余弦。我们可以使用它来对球体进行如下着色:

Vec3 Shading(Ray ray, Sphere sphere) { 
  Vec3 color(0, 0, 0);
  float t;
  if (sphere.intersect(ray, t)) {
    Vec3 V = ray.get_direction();
    Vec3 P = ray.get_origin() +  V * t;
    Vec3 N = sphere.get_normal(P);

    float facing_ratio = N.dot(V);

    color = sphere.get_color() * (facing_ratio * 0.5);
  }
  return color;
}

结果如下:
从零开始使用C ++编写Ray-Tracer

相关内容

热门资讯

裸体在家犯法还是拍别人裸照犯法... 近日,#男子在家裸体被邻居拍照发群#一事引发热议。据报道,某小区一名男业主在家中未穿衣物,对面女业主...
“每天跟遛狗一样”,万亿资金,... 进入7月,市场波动加大,A股关于量化交易的争议再次达到顶峰。由于散户与量化机构之间的“体感温差”显著...
特朗普:对伊朗战争进展顺利 当地时间7月23日,美国总统特朗普再次称,“美国在对抗伊朗方面进展很顺利,表现得极其出色,好得超乎任...
国务院成立广西六蓝水库溃坝灾害... 7月6日,广西南宁横州市六蓝水库发生溃坝,造成重大人员伤亡。根据国家有关法律法规规定,国务院成立调查...
倚美搞事,菲律宾政府连“为奴”... 南海的风浪,很大一部分是菲律宾政府自己搅起来的。近年来,菲政府在仁爱礁、黄岩岛等地小动作频频,不仅频...
雨花台区企业摘得国家科学技术进... 晨报讯(南京晨报/爱南京记者 陈彦)记者从南京市雨花台区获悉,在新近揭晓的2025年度国家科学技术奖...
美国公布新关税措施,日本、澳大... 据法新社、澳大利亚广播公司(ABC)报道,针对美国将于美东时间24日以所谓“强迫劳动”为名对数十个国...
济南大数据集团激活数据要素潜能... 走进“泉数汇·数港”线下体验空间,健康画像、求职背调、“泉涌”工作站等数据产品一字排开,来访者可以像...
太保寿险河南分公司举办员工家庭... 5月22日,中国太保寿险河南分公司在郑州举办绩优干部员工家庭开放日活动,邀请员工家属走进企业,参观办...
“展现了推动人工智能普惠向善发... 7月17日至20日,2026世界人工智能大会暨人工智能全球治理高级别会议在上海举行,习近平主席出席开...