体渲染——Volume
2024-08-28 08:10:05
基本概念
体渲染(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;
};
最新文章
- Json格式示意图
- React 随笔二
- ubuntu 14.04 下svn + apache2 配置
- 报表引擎API开发入门—简单程序数据集
- 2.6内核LOGO制作方法
- 创建第一个Android 5.0应用程序
- Java学习之路(七)
- 20145129 《Java程序设计》第6周学习总结
- leetcode Largest Rectangle in Histogram 解法二
- 项目移植过程中报:“Project facet Java version 1.7 is not supported.” 错误
- XML简单的增改删操作
- django-xadmin隐藏菜单不显示
- 微服务之consul(一)
- SSM中的Mybatis的操作
- WebRTC 简介及服务搭建、测试
- c语言笔记: 对 void *lpObj 进行类型转换时,一不留神,后果很严重
- neutron-----openstack网络操作
- LostRoutes项目日志——玩家飞机精灵Fighter解析
- HTTP记录-HTTP介绍
- Centos7系统配置上的变化
热门文章
- 根据对象,返回&#39;&;键名=值&;键名=值‘形式
- Dart: 编码和解码各种存档和压缩格式
- NGK公链:夯实基础设施 实现产业大规模应用
- K8S线上集群排查,实测排查Node节点NotReady异常状态
- 如何在一台开发机中同时配置github、gitlab等多个账户
- lombok插件@Slf4j注解不生效问题解决办法
- 由endl对printf和cout的思考
- HDOJ-1213(简单并查集)
- Java基础学习--集合
- 翻译:《实用的Python编程》04_00_Overview