问题十九:怎么模拟ray tracing中漫射材料球体的颜色(diffuse materials)
来源:互联网 发布:淘宝秒杀助手 编辑:程序博客网 时间:2024/05/08 09:52
前面画一个球时,球体的颜色设置为红色;
前面画多个球时,球体的颜色设置为球在该点的单位法向量的色彩表映射值;
现在画多个漫射材料的球,球体的颜色设置为背景颜色的系数倍。(姑且表述为“背景颜色”吧,将在“问题二十一”中确切说明)
漫射材料不发光,只吸收和反射环境的光(反射光的方向是随机的),所以将漫射材料的球体的颜色设置为背景颜色乘以某系数是合理的。系数怎么确定呢?光线每被反射一次*1/2(因为光线没被反射一次会被吸收一半)。
既然已经知道漫射材料球体的颜色和反射次数有关,那么怎么获得光线反射次数呢;
光线反射次数=光线撞击球的次数;
撞击次数由反射光线的方向和起点(前一个撞击点)决定;
第一撞击点,呵呵,容易,之前画一个球或者多个球都是根据撞击点画的(撞上了才是球嘛);
OK,现在问题归结于怎么获取反射光线的方向。
之前就说了,漫射材料的反射光线的方向是随机的,怎么模拟一个随机方向的向量呢?
在交点处单位法向量的基础上加上一个长度小于1的随机向量。
已知P为交点,PS为球C在P点的单位法向量,现在要模拟一个起点为P方向向球C外面的任何方向的向量。
书上是这么做的:
1,找一个辅助球O,该球是球心在原点的单位球体;
2,在球O里面随机找一点E或者F;(E点在球体里面,也就是向量OE的长度小于1,by the way,单位法向量PS的长度为1);
3,OP+PS=OS,OS+OE=OM,OM-OP=PM。所以,PM=OP+PS+OE-OP=PS+OE。(辅助球O选球心在原点的单位球的原因,其一,“球心在原点”,方便计算;其二,“单位球”,可以确保PM的方向不会指向球C内部)。PS是已知的,所以只要获得OE即可。
4,怎么描述“起点在原点,长度小于1,方向随机”的向量呢?书上说:We’ll use what is usually the easiest algorithm: a rejection method.First, we pick a random point in the unit cube where x, y, and z all range from-1 to +1. We reject this point and try again if the point is outside thesphere. A do/while construct is perfect for that:
vec3 random_in_unit_sphere() { vec3 p; do { p = 2.0*vec3((rand()%(100)/(float)(100)), (rand()%(100)/(float)(100)), (rand()%(100)/(float)(100))) - vec3(1,1,1); } while (p.squared_length() >= 1.0); return p; }
Rejectionmethod是什么鬼???
先回顾一下,怎么产生(-1,1)间的随机浮点数?
x=(rand()%(100)/(float)(100))∈(0,1)推出 2x ∈(0,2)推出2x-1∈(-1,1)
所以,y= 2*x -1 = 2 * (rand()%(100)/(float)(100)) -1即为(-1,1)间的随机浮点数。
同理,向量a = (x, y, z),b = (2x-1, 2y-1, 2z-1), 其中x,y, z ∈(0,1)
推出2x-1, 2y-1, 2z-1∈(-1,1)推出(2x-1)2+(2y-1)2+(2z-1)2∈(0,3)推出|b|∈(0, 根号3)
而我们能接受的是|b|∈(0,1),所以采取“接受——拒绝”方式:只接受|b|∈(0,1)。
所以,就有了上面那段code啦!
将流程反过来看一遍:
1,起点为原点的光线撞击球C,获得撞击点P和单位法向量PS。
2,产生一个“起点在原点,长度小于1,方向随机”的向量OE。
3,OP+PS+OE-OP=PM,PM即为漫射材料的球体在P点的随机反射方向向量。
4,反射光线是以P为起点,PM为方向向量,所以,我们可以获得反射光线的方程
5,让反射光线去撞击其他球吧(回到第一步)
光线撞击球的次数=光线反射的次数è球体该像素点的颜色值对应背景颜色的系数值。
vec3 color(const ray& r, hitable *world) { hit_record rec; if (world->hit(r, 0.0, (numeric_limits<float>::max)(), rec)) { vec3 target = rec.p + rec.normal + random_in_unit_sphere();/*target为上图中OM向量, target-rec.p=OM-OP=PM*/ return 0.5*color( ray(rec.p, target-rec.p), world);/*撞击一次,乘以系数0.5。然后以反射光线(以P为起点,PM为方向向量)去撞击球,直到没有撞击到任何球,(下方else语句中)最后带着系数乘以背景颜色值作为球体该像素点的颜色*/ } else { vec3 unit_direction = unit_vector(r.direction()); float t = 0.5*(unit_direction.y() + 1.0); return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0);//white, light blue }}
贴出运行结果图:
放大8倍看截图:
有没有觉得太黑了,反正我觉得是有问题的。
- 问题十九:怎么模拟ray tracing中漫射材料球体的颜色(diffuse materials)
- 问题二十一:怎么模拟ray tracing图形中不同材料的颜色(diffuse and metal)
- 问题二十四:怎么模拟ray tracing图形中介质材料的颜色(dielectric)
- 问题二十九:测试ray tracing中camera几个主要参数
- 《Ray Tracing in One Weekend》——Chapter 7: Diffuse materials
- 【Ray Tracing in One Weekend】(ch4)场景中第一个物体,球体
- 问题五十三:怎么用ray tracing画参数方程表示的曲面(1)
- 问题十三:怎么用ray tracing画个球
- 问题十七:怎么用ray tracing画多个球?
- 问题五十四:怎么用ray tracing画参数方程表示的曲面(2)—— bezier surface
- 问题五十六:怎么用ray tracing画参数方程表示的曲面(3)—— b-spline surface
- 问题四十四:怎么用ray tracing画空间任意位置的圆环的任意片段
- 问题三十二:怎么用ray tracing画多边形(polygon, triangle)
- 问题三十三:怎么用ray tracing画特殊长方体(box)
- 问题三十四:怎么用ray tracing画任意长方体(generalized box)
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(1)——椭球面
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(3)——椭球抛物面
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(5)——汇总
- Markdown中代码段的标注显示特殊字符`如何输入?
- NPC问题证明
- 文章标题
- css基础
- <meta name="viewport" content="width=device-width, initial-scale=1"> 作用
- 问题十九:怎么模拟ray tracing中漫射材料球体的颜色(diffuse materials)
- Acunetix免费的网站安全辅助测试工具
- sql注入
- dozer
- HttpClient—Apache的HTTP 协议工具包
- iOS Objective-C 深入理解Copy
- 关于活动的几个小技巧
- Java并发编程:volatile关键字解析
- 蓝桥杯 历届试题 蚂蚁感冒 详解