随笔 - 71,  文章 - 0,  评论 - 0,  阅读 - 42270

这个算法是均匀采样算法,继承于Sampler类。

类声明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once
#ifndef __REGULAR_HEADER__
#define __REGULAR_HEADER__
 
#include "sampler.h"
 
class Regular :public Sampler {
public:
    Regular();
    ~Regular();
    Regular(const integer samps);
    Regular(const integer samps, const integer sets);
    Regular(const Regular& reg);
    Regular& operator=(const Regular& reg);
    virtual Sampler* clone() const;
    virtual void generate_samples();
};
#endif  

类实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include "pch.h"
#include "regular.h"
 
Regular::Regular() :Sampler() {
    generate_samples();
}
 
Regular::~Regular() {}
 
Regular::Regular(const integer samps) : Sampler(samps) {
    generate_samples();
}
 
Regular::Regular(const integer samps, const integer sets) : Sampler(samps, sets) {
    generate_samples();
}
 
Regular::Regular(const Regular& reg) : Sampler(reg) {
    generate_samples();
}
 
Regular& Regular::operator=(const Regular& reg) {
    if (this == &reg)
        return *this;
    Sampler::operator=(reg);
    return *this;
}
 
Sampler* Regular::clone() const {
    return new Regular(*this);
}
 
void Regular::generate_samples() {
    integer n = (integer)std::sqrt((ldouble)nsamples);
    for (integer p = 0; p < nsets; p++) {
        for (integer i=0;i<n;i++)
            for (integer j = 0; j < n; j++) {
                Point2 sp((j + 0.5) / n, (i + 0.5) / n); //均匀采样
                samples.push_back(sp);
            }
    }
}

 

测试采样算法:

添加Sampler类和采样数到ViewPlane类中,增加函数(若无特殊声明,不再重复修改的部分)

void set_samples(const integer n);

void set_sampler(Sampler* const sp);

ViewPlane类具体声明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#pragma once
#ifndef __VIEWPLANE_HEADER__
#define __VIEWPLANE_HEADER__
 
#include "../../Types.h"
 
class Sampler;
 
class ViewPlane {
public:
    ViewPlane();
    ViewPlane(const ViewPlane& vp);
    void set_hres(const integer hr);
    void set_vres(const integer vr);
    void set_pixelsize(const ldouble ps);
    void set_gamma(const ldouble ga);
    void set_samples(const integer n);//新增
    void set_sampler(Sampler* const sp);//新增
    integer hres;
    integer vres;
    integer nsamples;//新增
    ldouble s;
    ldouble g;
    Sampler* sampler;//新增
};
 
#endif 

需要修改的类成员:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "pch.h"
#include "viewplane.h"
#include "../samplers/jittered.h"
 
 
ViewPlane::ViewPlane() :hres(200), vres(100), s(0.02), g(1), nsamples(16), sampler(nullptr) {}
 
ViewPlane::ViewPlane(const ViewPlane& vp)
    : hres(vp.hres), vres(vp.vres), s(vp.s), g(vp.g), nsamples(vp.nsamples), sampler(vp.sampler) {}
 
...
 
void ViewPlane::set_samples(const integer n) {//和书上不同,剔除特殊性,增加兼容性
    nsamples = n;
    sampler->clear();
    sampler->set_num_samples(nsamples);
    sampler->setup_shuffled_indices();
    sampler->generate_samples();
}
 
void ViewPlane::set_sampler(Sampler* const sp) {
    if (sampler != nullptr) {
        delete sampler;
        sampler = nullptr;
    }
    nsamples = sp->get_num_samples();
    sampler = sp;
}

  

World类只修改build和render部分:

1
2
3
4
5
6
7
8
9
10
11
12
void World::build() {
    vp.set_hres(200);
    vp.set_vres(100);
    vp.set_sampler(new Regular());//所有采样修改都在这里测试
    tracer_ptr = new MultiSphere(this);
    Geometrics* obj = new Sphere(0, 0.5);
    obj->set_color(RGBColor(1, 0, 0));
    add_object(obj);
    obj = new Sphere(Point3(0, -100.5, 0), 100);
    obj->set_color(RGBColor(0, 0, 1));
    add_object(obj);
}

render部分若无特殊声明,之后不再重复修改部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void World::render() {
    Ray ray;
    ldouble x, y;
    open_window(vp.hres, vp.vres);
    Point3 sp;
    ray.o = Point3(0, 0, 1);
    for (integer r = vp.vres - 1; r >= 0; r--)//render from left-corner to right-corner
        for (integer c = 0; c < vp.hres; c++) {
            RGBColor color;
            for (integer p = 0; p < vp.nsamples; p++) {//增加样本
                sp = vp.sampler->sample_unit_square();
                x = vp.s * (c - 0.5 * vp.hres + sp.x);
                y = vp.s * (r - 0.5 * vp.vres + sp.y);
                ray.d = Point3(x, y, -1);
                color += tracer_ptr->trace_ray(ray);
            }
            color /= vp.nsamples;
            display_pixel(r, c, color);
        }
}

  

修改完后,运行程序,测试效果如下(放大后,发现边角圆润了不少,接下来我们测试别的采样算法):

posted on   dalgleish  阅读(215)  评论(0编辑  收藏  举报
编辑推荐:
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
阅读排行:
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· 《HelloGitHub》第 108 期
· MQ 如何保证数据一致性?
· 一个基于 .NET 开源免费的异地组网和内网穿透工具
点击右上角即可分享
微信分享提示