zoukankan      html  css  js  c++  java
  • 同心映射定义和测试

    同心映射的算法原理如下图,具体阐述参考书籍:

    由于同心映射是针对于samples这个数组的映射,所以只需要修改samples这个数组的数据就行了。

    需要修改的Sampler类:

    #pragma once
    #ifndef __SAMPLER_HEADER__
    #define __SAMPLER_HEADER__
    
    #include "../utilities/geometry.h"
    
    class Sampler {
    public:
    	...
    	void map_to_unit_disk();//新增函数,同心映射
    protected:
    	integer nsamples;
    	integer nsets;
    	std::vector<Point3> samples;
    	std::vector<integer> shuffled_indices;
    	integer count;
    	integer jump;
    };
    #endif
    

    对应函数实现:

    void Sampler::map_to_unit_disk() {
    	std::vector<Point3> copySamples = samples;//备份
    	ldouble r, phi;
    	Point2 sp;
    	for (u_integer i = 0; i < copySamples.size(); i++) {
    		sp.x = 2.0 * copySamples[i].x - 1.0;
    		sp.y = 2.0 * copySamples[i].y - 1.0;
    		if (sp.x > -sp.y) {
    			if (sp.x > sp.y) {
    				r = sp.x;
    				phi = sp.y / sp.x;
    			}
    			else {
    				r = sp.y;
    				phi = 2.0 - sp.x / sp.y;
    			}
    		}
    		else {
    			if (sp.x < sp.y) {
    				r = -sp.x;
    				phi = 4 + sp.y / sp.x;
    			}
    			else {
    				r = -sp.y;
    				phi = (sp.y != 0) ? (6 - sp.x / sp.y) : 0;
    			}
    		}
    		phi *= M_PI / 4.0;
    		samples[i].x = r * cos(phi);
    		samples[i].y = r * sin(phi);
    	}
    }
    

      

    需要修改的World:render函数

    void World::render() {
    	Ray ray;
    	ldouble x, y;
    	open_window(vp.hres, vp.vres);
    	Point3 sp;
    	ray.o = Point3(0, 0, 1);
    	vp.sampler->map_to_unit_disk();//测试同心映射
    	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);
    		}
    }
    

      

    本测试结果采用的是Hammersley类的采样算法,然后再加上同心映射。测试结果图如下,明显边角梗圆润了:

    其余的半球和全球映射书上都给了代码,就不做测试了。不过我已经实现了。效果和这个差不多。就不发布代码了。请参考书本。

  • 相关阅读:
    20款最优秀的JavaScript编辑器
    清空windows系统网络配置
    如何禁止Chrome浏览器隐藏URL的WWW前缀
    EDK2开发环境搭建
    edk2中子目录介绍
    INTEL_BIOS 编译—for-ATOM_E3800
    英特尔vPro博锐技术激活
    gitea configure
    mpeg1、mpeg2和mpeg4标准对比分析和总结
    内置缓存
  • 原文地址:https://www.cnblogs.com/dalgleish/p/12603818.html
Copyright © 2011-2022 走看看