这个算法是均匀采样算法,继承于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 == ®) 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); } } |
修改完后,运行程序,测试效果如下(放大后,发现边角圆润了不少,接下来我们测试别的采样算法):
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· 《HelloGitHub》第 108 期
· MQ 如何保证数据一致性?
· 一个基于 .NET 开源免费的异地组网和内网穿透工具