问题十八:怎么对ray tracing图形进行消锯齿
2017-01-14 19:21
218 查看
先将上一章节的图放大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.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
边界的锯齿很清晰很明显很刺眼啊,有木有?我们现在要做的就是使得这些锯齿不那么清晰不那么明显不那么刺眼。简单地说,使边界模糊。
之前的图是每个像素点设置一个颜色值,相当于将像素中心位置的颜色设置给了整个像素。所以,如果两个像素点中心位置的颜色值相差比较大时,这两个像素点就会产生清晰的边界。那么问题来了,怎么使得两个像素点的边界模糊呢?
书上的做法是:
针对每个像素点随机采样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
相关文章推荐
- 第三方分享QQ QQZONE
- 户口证明办理记
- 高精度模板
- VS增加插件 Supercharger破解教程
- DNS正反向解析和主从同步配置
- Android Design Support Library - TabLayout的用法
- 51nod1092(lcs简单运用/dp)
- PM的烦恼---转版本!
- RAID和LVM
- Android Design Support Library - TabLayout的用法
- Java基础-day01-常见的DOS命令
- SDH基础(2)
- Genymotion的安装与eclipse配置教程
- 开箱即用 - Memcache缓存
- Xamarin原生跨平台概述(精简概述,命中要害。PS:无图)
- SQL语句 不足位数补0
- 时序收敛以及 synplify 技巧timing constraint
- 小试牛刀RxJava2之首页检查
- Ubuntu 12.04 LTS上使用WPS及相关字体问题
- mybatis动态SQL语句