先将上一章节的图放大8倍,看看局部:

边界的锯齿很清晰很明显很刺眼啊,有木有?我们现在要做的就是使得这些锯齿不那么清晰不那么明显不那么刺眼。简单地说,使边界模糊。

之前的图是每个像素点设置一个颜色值,相当于将像素中心位置的颜色设置给了整个像素。所以,如果两个像素点中心位置的颜色值相差比较大时,这两个像素点就会产生清晰的边界。那么问题来了,怎么使得两个像素点的边界模糊呢?

书上的做法是:

针对每个像素点随机采样100次,获得100个颜色值,然后将这100个颜色值的平均值设置为整个像素点的颜色值。

这样做为什么可以模糊边界呢?

先看两张示意图:

同一块区域,4个像素点时如左图,16个像素点时就有可能是右图这样子。

区域中左上四分之一区域:

采样一次时获得的就是中心位置的颜色值(黄色),然后将这个颜色值设置为这个四分之一区域的颜色值。

采样四次时,每次采样获得的可能是相邻两个四分之一区域中心点之间的颜色值。原左上四分之一区域的四个采样点的值可能和原左上四分之一区域(黄色)、左下四分之区域(红色)、右上四分之一区域(绿色)的原中心位置的颜色值相同。如右图中左上四分之一区域,包含了右边的绿色和下边的红色。如果此时将左上四分之一区域的颜色整体设置为该区域内四个采样值值的平均值,该值和右边、下边的值就相对比较接近了,也就是模糊了边界。

以上是个人的理解,下面贴出书上的代码:(只贴出相对之前有改动的函数,红色字体部分为函数中有改动的地方)

----------------------------------------------main.cpp----------------------------------------------

main.cpp

int main(){

int nx = 200;

int ny = 100;

intns = 100;

ofstream outfile(".\\results\\Antialiasing.txt", ios_base::out);

outfile <<"P3\n" << nx << " " << ny <<"\n255\n";

std::cout <<"P3\n" << nx << " " << ny <<"\n255\n";

hitable *list[2];

list[0] = newsphere(vec3(0,0,-1), 0.5);

list[1] = newsphere(vec3(0,-100.5,-1), 100);

hitable *world = newhitable_list(list,2);

camera cam;

for (int j = ny-1; j>= 0; j--){

for (int i = 0; i< nx; i++){

vec3 col(0, 0,0);

for (int s = 0; s < ns; s++){

/*每个像素点区域采样ns次,此处ns=100*/

float random = rand()%(100)/(float)(100);

/*generate a random in range[0,1]。每个像素点的区域是以像素中心点为中心向外距离为1的范围。中心点位置+random相当于在这个像素点的区域内采样 */

float u = float(i + random) / float(nx);

float v = float(j + random) / float(ny);

ray r = cam.get_ray(u, v);

/*获得这个像素点区域随机采样点的颜色值。我们已经将颜色获得函数封装成一个叫做“camera”的类,后续会贴出这个类的代码*/

//                vec3 p = r.point_at_parameter(2.0);

col += color(r, world);

/*将这个像素点区域的所有ns个随机采样点的颜色值累加*/

}

col /= float(ns);

/*将这个像素点区域的所有ns个随机采样点的颜色累加值除以ns获得其平均值,作为这个像素点区域最终的像素值。*/

int ir = int(255.99*col[0]);

int ig = int(255.99*col[1]);

int ib = int(255.99*col[2]);

outfile<< ir << " " << ig << " " <<ib << "\n";

std::cout<< ir << " " << ig << " " <<ib << "\n";

}

}

}

----------------------------------------------camera.h ----------------------------------------------
camera.h
/*不解释,因为只是将原本在main函数中的代码拿出来封装为一个独立的类*/
#ifndef CAMERA_H
#define CAMERA_H#include "ray.h"class camera
{public:camera() {lower_left_corner = vec3(-2.0, -1.0, -1.0);horizontal = vec3(4.0, 0.0, 0.0);vertical = vec3(0.0, 2.0, 0.0);origin = vec3(0.0, 0.0, 0.0);}ray get_ray(float u, float v) {return ray(origin, lower_left_corner + u*horizontal + v*vertical);}vec3 lower_left_corner;vec3 horizontal;vec3 vertical;vec3 origin;};#endif // CAMERA_H

----------------------------------------------camera.cpp----------------------------------------------

camera.cpp

为空。

模糊后的情况如下:(对比原图还是可以看出差异的哈)

原图放大8倍时:

抗干扰(消锯齿)后放大8倍时:

贴一句书上的原话:the big change is in edge pixels that are part background and part foreground.

另外,另外,另外,一直好奇那些随机数长什么样,所以将nx改成2,ny改成3,ns改成4,打印出来看了下,log如下:

一共有nx*ny(即2*3=6)个像素点的RGB值,每个像素点对应着ns(即4)个随机数。

P3

2 3

255

random======================================0.41

random======================================0.67

random======================================0.34

random======================================0

169 204 255

random======================================0.69

random======================================0.24

random======================================0.78

random======================================0.58

165 201 255

random======================================0.62

random======================================0.64

random======================================0.05

random======================================0.45

172 226 223

random======================================0.81

random======================================0.27

random======================================0.61

random======================================0.91

194 185 245

random======================================0.95

random======================================0.42

random======================================0.27

random======================================0.36

123 211 157

random======================================0.91

random======================================0.04

random======================================0.02

random======================================0.53

129 255 128

问题十八:怎么对ray tracing图形进行消锯齿相关推荐

  1. 问题二十:C++全局debug “ray tracing图形”实例

    紧接上文,漫射材料的球体颜色是不是太黑了呢?为什么会这么黑? 接下来要debug啦!!! 第一步:取消"消锯齿" 首先想到的是:应该减少光线条数.所以,将"消锯齿&quo ...

  2. 问题二十一:怎么模拟ray tracing图形中不同材料的颜色(diffuse and metal)

    在漫射材料章节,我们将多个球都模拟成漫射材料的颜色.那么问题来了,我们能不能将不同的球模拟成不同材料的颜色呢?可以哈!我们这一章节就干这事. 21.1总结一下设置颜色的几种方法 我们还是先回忆一下:r ...

  3. 问题四十五:怎么画ray tracing图形中的blending and joining surface

    当两个曲面在空间相交时,怎么连接相交处? 比如,两个相互垂直的柱面在空间相交如下: 怎么将黑色圈内的相交处画得平滑些?也就是将相交处包起来,添加一个类似水管的四通接口. 45.1 数学推导 45.2 ...

  4. 问题二十四:怎么模拟ray tracing图形中介质材料的颜色(dielectric)

    这里的"介质"是指光可以通过的物质.比如,水,玻璃等.也就是我们常说的具有一定透明度的物质. 24.1 预备知识 24.1.1 反射和折射光线的方向向量 反射光线的方向向量: 漫反 ...

  5. 问题六十:怎么用ray tracing画回旋体(rotational sweeping / revolution)

    60.1 概述 回旋体,大概是长这个样子: 回旋体是指曲线(称为"基本曲线")围绕y轴转一圈得到的图形. (基本曲线是由多段b-spline曲线段连接而成) 这里先强调一下: 上图 ...

  6. 问题五十:怎么用ray tracing画blobs

    这一节,画这个: 参考文献: Blinn, J.F., A generalization of algebraic surfacedrawing. ACM Trans. Graph. 1(3) , 2 ...

  7. 问题二十九:测试ray tracing中camera几个主要参数

    camera(vec3 lookfrom, vec3 lookat, vec3vup, float vfov, float aspect, float aperture, float focus_di ...

  8. 《Ray Tracing in One Weekend》——Chapter 6: Antialiasing

    总结<Ray Tracing in One Weekend>全文 第一部分:学习总结 问题十八:怎么对ray tracing图形进行消锯齿 第二部分:原文截图 总结<Ray Trac ...

  9. 问题六十七:ray tracing学习总结(2016.11.13, 2017.02.05)

    从2016.11.13开始接触ray tracing到今天2017.02.05,差不多80天的时间.截至当前,学习ray tracing的过程,也是我重新找回自己或者说是"find what ...

最新文章

  1. 基于 Dash Bio 的生物信息学数据可视化
  2. 注册页面所涉及的知识
  3. java.util.concurrent.CyclicBarrier;
  4. 破解入门(六)-----实战“内存镜像法”脱壳
  5. shiro登录认证过程讲解(转)
  6. Java Stream API性能测试
  7. 导入数据库怎么导入_导入必要的库
  8. 程序代码错误检测_错误检测代码
  9. iOS 9 学习系列:Storyboard References
  10. opencv-python学习一--人脸检测
  11. Atitit.有分区情况下的表查询策略流程
  12. Julia :PyPlot库安装中需注意的问题
  13. C++搭建集群聊天室(二):安装muduo网络库
  14. matlab如何用二分法求函数零点,用二分法求函数零点的步骤.PPT
  15. 2021年12月四六级考试成绩批量查询Java
  16. 操作系统 | 银行家算法
  17. 冰汽朋克侦查机器人_冰汽时代机器流玩法 寒霜朋克机器人流玩法怎么玩
  18. matlab去除红眼代码及详细介绍
  19. 和ChatGPT的一番对话
  20. Windows自带虚拟化服务工具Hyper-V学习了解和实操

热门文章

  1. Chapter 1. Asp.Net 概述
  2. CentOS利用LVM实现磁盘弹性扩容
  3. CF Fox And Two Dots (DFS)
  4. JS来推断文本框内容改变事件
  5. 利用linux mutt 发送邮件(在Shell脚本中使用比较方便)
  6. Glade3 tutorial in chinese
  7. 【动态规划】LeetCode 62. Unique Paths
  8. 程序员面试金典——4.7最近公共祖先
  9. 事件相互独立的几种不同说法
  10. End-to-End Object Detection with Transformers的部分解读