基本概念

  体渲染(Volume),是绘制类似烟、雾、云的效果。这种渲染和之前的表面渲染不同,光线可以在物体内部进行散射。

体渲染的主要特点

   1. 可以在物体内部散射。

   2. 从进入volume到发生散射的距离,与密度成反比

   3. 光线散射的方向,可以是任意方向

实现

  主要需要解决的问题:在什么位置发生碰撞(scatter),以及scatter ray的方向。

  碰撞的问题在hitable中解决。散射的问题在material中解决。

class constant_medium : public hitable {
public:
constant_medium(hitable *b, float d, texture *a) : boundary(b), density(d) {
phase_function = new isotropic(a);
}
virtual bool hit(const ray& r, float t_min, float t_max, hit_record& rec) const;
virtual bool bounding_box(float t0, float t1, aabb& box) const {
return boundary->bounding_box(t0, t1, box);
}
hitable *boundary;
float density;
material *phase_function;
};

  碰撞函数:

  先和volume的轮廓求交,确定和轮廓的两个交点,这样体内的碰撞,将发生在两个交点的连线上。

  其在volume内的distance,不会超过上述近交点和远交点的距离,并且与density成反比。

bool constant_medium::hit(const ray& r, float t_min, float t_max, hit_record& rec) const {

	hit_record rec1, rec2;

	//直线与盒子的近交点
if (boundary->hit(r, -FLT_MAX, FLT_MAX, rec1)) {
//直线与盒子的远交点
if (boundary->hit(r, rec1.t + 0.0001, FLT_MAX, rec2)) { if (debugging) std::cerr << "\nt0 t1 " << rec1.t << " " << rec2.t << '\n'; if (rec1.t < t_min) rec1.t = t_min;
if (rec2.t > t_max) rec2.t = t_max; if (rec1.t >= rec2.t)
return false;
if (rec1.t < 0)
rec1.t = 0;
//近交点和远交点的距离
float distance_inside_boundary = (rec2.t - rec1.t) * r.direction().length();
//随机生成传输距离,与密度成反比
float hit_distance = -(1 / density) * log(random_double()); if (hit_distance < distance_inside_boundary) { //确定最终的碰撞位置
rec.t = rec1.t + hit_distance / r.direction().length();
rec.p = r.point_at_parameter(rec.t); rec.normal = vec3(1, 0, 0); // arbitrary
rec.normal = unit_vector(vec3(random_double(), random_double(), random_double()));
//决定scatter ray的材质
rec.mat_ptr = phase_function;
return true;
}
}
}
return false;
}

  散射函数:

  使用random_in_unit_sphere()表示散射光线为任意方向。

class isotropic : public material {
public:
isotropic(texture *a) : albedo(a) {}
virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered) const {
//起点为碰撞点,方向为任意方向
scattered = ray(rec.p, random_in_unit_sphere(), r_in.time());
attenuation = albedo->value(rec.u, rec.v, rec.p);
return true;
}
texture *albedo;
};

最新文章

  1. Json格式示意图
  2. React 随笔二
  3. ubuntu 14.04 下svn + apache2 配置
  4. 报表引擎API开发入门—简单程序数据集
  5. 2.6内核LOGO制作方法
  6. 创建第一个Android 5.0应用程序
  7. Java学习之路(七)
  8. 20145129 《Java程序设计》第6周学习总结
  9. leetcode Largest Rectangle in Histogram 解法二
  10. 项目移植过程中报:“Project facet Java version 1.7 is not supported.” 错误
  11. XML简单的增改删操作
  12. django-xadmin隐藏菜单不显示
  13. 微服务之consul(一)
  14. SSM中的Mybatis的操作
  15. WebRTC 简介及服务搭建、测试
  16. c语言笔记: 对 void *lpObj 进行类型转换时,一不留神,后果很严重
  17. neutron-----openstack网络操作
  18. LostRoutes项目日志——玩家飞机精灵Fighter解析
  19. HTTP记录-HTTP介绍
  20. Centos7系统配置上的变化

热门文章

  1. 根据对象,返回&#39;&amp;键名=值&amp;键名=值‘形式
  2. Dart: 编码和解码各种存档和压缩格式
  3. NGK公链:夯实基础设施 实现产业大规模应用
  4. K8S线上集群排查,实测排查Node节点NotReady异常状态
  5. 如何在一台开发机中同时配置github、gitlab等多个账户
  6. lombok插件@Slf4j注解不生效问题解决办法
  7. 由endl对printf和cout的思考
  8. HDOJ-1213(简单并查集)
  9. Java基础学习--集合
  10. 翻译:《实用的Python编程》04_00_Overview