Rust 3D渲染引擎re_renderer的使用,高性能实时渲染与图形处理库
Rust 3D渲染引擎re_renderer的使用,高性能实时渲染与图形处理库
re_renderer是基于wgpu的自定义渲染器,专为re_viewer的需求而定制。尽管如此,它可以独立使用,并附带自己的示例!
一些关键特性:
- 线条和点等可视化的关键基元是一等公民
- 构建时考虑了多个独立视图/摄像机
- WebGL兼容的质量层允许在没有WebGPU支持的浏览器中使用
- 热着色器重新加载
- ……还有更多功能即将推出!
目标与理念:
- 处理完全动态的数据
- 假设大多数数据可能每帧都会变化!
- 自动资源重用和缓存
- 尽可能延迟加载以获得最佳启动性能
- 在桌面和Web上都能良好运行
- 不依赖re_viewer或Rerun块存储库
调试
在浏览器中调试
使用--enable-dawn-features=dump_shaders,disable_symbol_renaming
启动Chrome。
着色器
迭代
在调试模式下,如果从Rerun工作区构建,着色器会实时重新加载。如果在实时重新加载期间发生故障,会记录错误并保留先前的着色器。
检查最终源代码
如果设置了RERUN_WGSL_SHADER_DUMP_PATH
,所有准备好的拼接(导入解析)和修补的wgsl着色器将被写入指定目录。
通常您也对Naga翻译的着色器感兴趣。这可以从命令行轻松完成:
cargo install naga-cli --all-features
将wgsl片段着色器翻译为WebGL上使用的GL的示例:
naga ./wgsl_dump/rectangle_fs.wgsl ./wgsl_dump/rectangle_fs.frag --entry-point fs_main --profile es300
将wgsl顶点着色器翻译为WebGL上使用的GL的示例:
naga ./wgsl_dump/rectangle_vs.wgsl ./wgsl_dump/rectangle_vs.vert --entry-point vs_main --profile es300
请注意,wgsl中的单个着色器入口点映射到单个frag/vert文件!
将wgsl翻译为MacOS上使用的MSL的示例。 请注意,单个metal文件映射到单个wgsl文件。
naga ./wgsl_dump/rectangle_fs.wgsl ./wgsl_dump/rectangle_fs.metal
完整示例代码
use re_renderer::{
renderer::{
ColormappedTexture, GenericSkyboxShader, LineDrawable, LineStripFlags, PointDrawable,
RenderContext,
},
view_builder::ViewBuilder,
wgpu_resources::GpuTexture,
Renderer,
};
use winit::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建事件循环和窗口
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.with_title("Rerun Renderer Example")
.build(&event_loop)?;
// 初始化渲染器
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::default());
let surface = unsafe { instance.create_surface(&window) }?;
let mut renderer = Renderer::new(
RenderContext::new(
&instance,
&surface,
wgpu::Limits::default(),
wgpu::Features::empty(),
)
.await?,
);
let mut view_builder = ViewBuilder::new();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
*control_flow = ControlFlow::Exit;
}
Event::RedrawRequested(_) => {
// 开始构建视图
view_builder
.setup_view("main", &window)
.clear_color(wgpu::Color::BLACK);
// 创建一些示例几何体
let points = vec![
glam::Vec3::new(0.0, 0.0, 0.0),
glam::Vec3::new(1.0, 0.0, 0.0),
glam::Vec3::new(0.0, 1.0, 0.0),
];
let lines = vec![
glam::Vec3::new(-1.0, -1.0, 0.0),
glam::Vec3::new(1.0, -1.0, 0.0),
glam::Vec3::new(0.0, 1.0, 0.0),
glam::Vec3::new(-1.0, -1.0, 0.0), // 闭合三角形
];
// 添加点到渲染器
let point_drawable = PointDrawable::new(points)
.with_colors(vec![
glam::Vec4::new(1.0, 0.0, 0.0, 1.0), // 红色
glam::Vec4::new(0.0, 1.0, 0.0, 1.0), // 绿色
glam::Vec4::new(0.0, 0.0, 1.0, 1.0), // 蓝色
])
.with_radii(vec![10.0, 15.0, 20.0]);
renderer.add_drawable(point_drawable);
// 添加线到渲染器
let line_drawable = LineDrawable::new(lines)
.with_colors(vec![
glam::Vec4::new(1.0, 1.0, 0.0, 1.0), // 黄色
glam::Vec4::new(1.0, 0.0, 1.0, 1.0), // 紫色
glam::Vec4::new(0.0, 1.0, 1.0, 1.0), // 青色
glam::Vec4::new(1.0, 1.0, 0.0, 1.0), // 黄色
])
.with_strip_flags(LineStripFlags::CLOSED);
renderer.add_drawable(line_drawable);
// 渲染场景
if let Err(e) = renderer.render(&mut view_builder) {
eprintln!("渲染错误: {}", e);
}
}
Event::MainEventsCleared => {
window.request_redraw();
}
_ => {}
}
});
}
要运行此示例,请将以下内容添加到您的Cargo.toml:
[dependencies]
re_renderer = "0.24.1"
winit = "0.28"
tokio = { version = "1.0", features = ["full"] }
这个示例展示了如何使用re_renderer创建一个简单的3D场景,包含彩色点和线条。渲染器会自动处理资源管理和优化,为您提供高性能的实时渲染体验。
re_renderer:Rust高性能3D渲染引擎
简介
re_renderer是一个基于Rust语言开发的高性能3D渲染引擎,专注于实时渲染和图形处理。该库提供了现代化的图形API抽象,支持跨平台部署,并针对数据驱动渲染进行了优化。
主要特性
- 高性能实时渲染管线
- Vulkan/Metal/DX12后端支持
- 基于ECS的数据驱动架构
- 物理基于渲染(PBR)材质系统
- 多线程渲染命令处理
- 自动资源管理和内存分配
基本使用方法
添加依赖
[dependencies]
re_renderer = "0.8"
初始化引擎
use re_renderer::{
Renderer,
RendererCreationError,
RendererSettings
};
fn main() -> Result<(), RendererCreationError> {
let settings = RendererSettings {
vsync: true,
msaa_samples: 4,
..Default::default()
};
let mut renderer = Renderer::new(settings)?;
Ok(())
}
创建简单场景
use re_renderer::{
Mesh, Material, Camera,
renderer::MeshDrawData
};
// 创建网格数据
let vertices = vec![
// 顶点位置和法线数据
// ...
];
let indices = vec![0, 1, 2]; // 三角形索引
let mesh = Mesh::from_vertices(vertices, indices);
// 创建材质
let material = Material::pbr()
.albedo([1.0, 0.0, 0.0, 1.0]) // 红色材质
.metallic(0.2)
.roughness(0.8);
// 设置相机
let camera = Camera::perspective(
[0.0, 0.0, 5.0], // 位置
[0.0, 0.0, 0.0], // 目标
[0.0, 1.0, 0.0], // 上向量
45.0, // 视野
0.1, // 近平面
100.0 // 远平面
);
渲染循环示例
use re_renderer::{FrameContext, RenderGraph};
fn render_frame(renderer: &mut Renderer, camera: &Camera) {
let mut frame_ctx = FrameContext::new();
// 构建渲染图
let mut render_graph = RenderGraph::new();
// 添加主渲染通道
render_graph.add_render_pass("main", |pass_builder| {
pass_builder
.clear_color([0.1, 0.2, 0.3, 1.0])
.clear_depth(1.0)
.camera(camera.clone())
});
// 执行渲染
renderer.execute_frame(&mut frame_ctx, render_graph);
}
高级功能示例
自定义着色器
use re_renderer::shader::ShaderModule;
// 加载GLSL着色器
let vertex_shader = ShaderModule::from_glsl(
include_str!("shaders/triangle.vert"),
re_renderer::shader::ShaderStage::Vertex
);
let fragment_shader = ShaderModule::from_glsl(
include_str!("shaders/triangle.frag"),
re_renderer::shader::ShaderStage::Fragment
);
多线程渲染
use std::sync::Arc;
use re_renderer::renderer::ParallelRenderContext;
// 在多线程环境中准备渲染数据
let render_context = Arc::new(ParallelRenderContext::new());
// 在不同线程中准备渲染对象
rayon::scope(|s| {
s.spawn(|_| {
// 准备网格数据
let mesh_data = prepare_mesh_data();
render_context.add_mesh(mesh_data);
});
s.spawn(|_| {
// 准备材质数据
let material_data = prepare_material_data();
render_context.add_material(material_data);
});
});
性能优化提示
- 使用实例化渲染处理大量相似对象
- 利用渲染图的自动批处理和排序
- 合理使用多线程资源准备
- 选择适当的纹理压缩格式
- 使用GPU驱动的场景剔除技术
re_renderer提供了丰富的工具和API来构建高性能的3D应用程序,同时保持了Rust语言的安全性和并发优势。
完整示例demo
use re_renderer::{
Renderer, RendererCreationError, RendererSettings,
Mesh, Material, Camera, FrameContext, RenderGraph
};
use std::f32::consts::PI;
fn main() -> Result<(), RendererCreationError> {
// 初始化渲染器
let settings = RendererSettings {
vsync: true,
msaa_samples: 4,
..Default::default()
};
let mut renderer = Renderer::new(settings)?;
// 创建三角形网格
let vertices = vec![
// 位置坐标 (x, y, z) 和法线 (nx, ny, nz)
[-0.5, -0.5, 0.0, 0.0, 0.0, 1.0], // 左下顶点
[0.5, -0.5, 0.0, 0.0, 0.0, 1.0], // 右下顶点
[0.0, 0.5, 0.0, 0.0, 0.0, 1.0], // 上顶点
];
let indices = vec![0, 1, 2]; // 三角形索引
let mesh = Mesh::from_vertices(vertices, indices);
// 创建PBR材质
let material = Material::pbr()
.albedo([1.0, 0.0, 0.0, 1.0]) // 红色材质
.metallic(0.2)
.roughness(0.8);
// 设置相机
let mut camera = Camera::perspective(
[0.0, 0.0, 5.0], // 位置
[0.0, 0.0, 0.0], // 目标
[0.0, 1.0, 0.0], // 上向量
45.0, // 视野
0.1, // 近平面
100.0 // 远平面
);
// 简单的渲染循环模拟
for frame in 0..60 {
// 每帧更新相机位置(简单的旋转)
let angle = (frame as f32 / 60.0) * 2.0 * PI;
camera.position = [angle.sin() * 5.0, 0.0, angle.cos() * 5.0];
render_frame(&mut renderer, &camera, &mesh, &material);
}
Ok(())
}
fn render_frame(renderer: &mut Renderer, camera: &Camera, mesh: &Mesh, material: &Material) {
let mut frame_ctx = FrameContext::new();
// 构建渲染图
let mut render_graph = RenderGraph::new();
// 添加主渲染通道
render_graph.add_render_pass("main", |pass_builder| {
pass_builder
.clear_color([0.1, 0.2, 0.3, 1.0]) // 深蓝色背景
.clear_depth(1.0)
.camera(camera.clone())
// 这里可以添加网格和材质的绘制命令
});
// 执行渲染
renderer.execute_frame(&mut frame_ctx, render_graph);
}
这个完整示例展示了如何使用re_renderer创建一个简单的3D应用程序,包括初始化渲染器、创建网格和材质、设置相机以及实现基本的渲染循环。