为方便查阅,此文是原网站文档翻译,如有侵权,请与本人联系。
官网
在Chrono::Sensor::ChCameraSensor中,合成数据是通过基于GPU的光线跟踪生成的。通过利用NVIDIA Optix Library提供的硬件加速支持和无头渲染功能。
摄像头传感器设置
chrono::ChFrame<double> offset_pose({10, 2, .5}, // Position
Q_from_AngAxis(CH_C_PI, {0, 0, 1})); // Rotation
auto Camera = chrono_types::make_shared<ChCameraSensor>(
parent_body, // body camera is attached to
update_rate, // update rate in Hz
offset_pose, // offset pose
image_width, // image width
image_height, // image height
fov, // camera's horizontal field of view
alias_factor, // supersample factor for antialiasing
lens_model, // lens model for optional distortion
use_global_illumination, // optional for enabling global illumination on camera
gamma, // optionally set the gamma correction exponent (defaults to 2.2)
use_fog // optionally enable fog for this camera
);
Camera->SetName("Camera Sensor");
Camera->SetLag(lag);
Camera->SetCollectionWindow(exposure_time);
// Sensor data access filter
Camera->PushFilter(chrono_types::make_shared<ChFilterRGBA8Access>());
// Add sensor to manager
manager->AddSensor(Camera);
有关更多详细信息,请参阅ChCameraSensor。
相机设置过程将自动将Optix渲染过滤器添加到过滤器列表中
如果摄影机supersample_factor大于1,则设置过程将调整分辨率并将“图像别名过滤器”附加到过滤器列表中。
渲染步骤
Chrono::sensor中的相机传感器使用Optix作为渲染引擎。对于每个像素,引擎将在该方向射出一条光线,并找到与该光线相交的第一个对象.默认情况下,引擎使用基于物理的BRDF着色器来渲染对象。它将以递归方式为阴影、反射和折射生成额外的光线。相机更新频率比物理更新频率慢得多。因此,ChOptixEngine生成一个线程来执行渲染,并且不会阻塞主线程
每次更新(主线程)
- 检查是否有需要更新的摄像头。如果有这样的摄像头
- 更新场景信息
- 将其推入渲染队列
- 检查是否有任何相机应该准备好数据,或者等待它们完成。
- 继续到下一个时间步骤
渲染线程
- 等待,直到渲染队列中有摄影机为止
- 更新这些摄影机,清除渲染队列,返回步骤1
过滤图
任何数量的过滤器都可以附加到列表中并修改最终结果。过滤器按照过滤器列表中的顺序执行。下面是一些例子。
- Camera Noise
- Image Alias Filter
- Transfer to Gray scale
- Save Result
- Visualize Result
摄影机动画
在模拟过程中,可以使用SetOffsetPose轻松更改相机的位置和旋转
Camera->SetOffsetPose(chrono::ChFrame<double>({8, 2, .5}, // Position
Q_from_AngAxis(CH_C_PI, {0, 0, 1}))); // Rotation
数据访问
滞后时间过后,数据将准备就绪。访问
RGBA_ptr = Camera->GetMostRecentBuffer<UserRGBA8BufferPtr>();
if (RGBA_ptr->Buffer) {
unsigned int height = RGBA_ptr->Height;
unsigned int width = RGBA_ptr->Width;
PixelRGBA8 pixel_at_100_100 = RGBA_ptr->Buffer[100 * width + 100];
uint8_t red_channel_at_100_100 = unsigned(pixel_at_100_100.R);
}