【图像处理】Ray Tracing in a Weekend [2]

1.光线追踪

实现类:vec3,sphere(球体),ray(射线,由射线起始点+射线方向向量组成)

camera.h hitable.h hitable_list.h

ray.cpp + ray.h

sphere.h

vec3.h + vec3.cpp

图显示工具:ffplay.exe

sphere.h

#ifndef SPHEREH
#define SPHEREH
#include "hitable.h"
class sphere: public hitable {
    public:
    sphere() {}
    sphere(vec3 cen, float r): center(cen), radius(r) {}
    virtual bool hit(const ray& r, float tmin, float tmax,
    hit_record& rec) const;
    vec3 center;
    float radius;
};

bool sphere::hit(const ray& r, float t_min, float t_max, hit_record& rec) const {
    vec3 oc = r.origin() - center;
    float a = dot(r.direction(), r.direction());
    float b = dot(oc, r.direction());
    float c = dot(oc, oc) - radius * radius;
    float discriminant = b * b - a * c;
    if (discriminant > 0) {
        float temp = (-b - sqrt(b * b - a * c)) / a;
        if (temp < t_max && temp > t_min) {
            rec.t = temp;
            rec.p = r.point_at_parameter(rec.t);
            rec.normal = (rec.p - center) / radius;
            return true;
        }
        temp = (-b + sqrt(b * b - a * c)) / a;
        if (temp < t_max && temp > t_min) {
            rec.t = temp;
            rec.p = r.point_at_parameter(rec.t);
            rec.normal = (rec.p - center) / radius;
            return true;
        }
    }
    return false;
}
#endif

 

着色消除锯齿

 

增加光照反射

vec3 color(const ray& r, hitable* world) {
    hit_record rec;
    if (world->hit(r, 0.001, FLT_MAX, rec)) {
        vec3 rnd = random_in_unit_shpere();
        vec3 target = rec.p + rec.normal + rnd;
        // printf("%f %f %f\n", rnd[0], rnd[1], rnd[2]);
        return 0.5 * color(ray(rec.p, target - rec.p), world);
    }
    else {
        vec3 unit_direction = unit_vector(r.direction());
        float t = 0.5 * (unit_direction.y() + 1.0);
        return (1.0 - t) * vec3(1.0, 1.0, 1.0) + t * vec3(0.5, 0.7, 1.0);
    }
}

 

猜你喜欢

转载自www.cnblogs.com/wangzming/p/11967122.html