Prototype vector to raster conversion

This commit is contained in:
Dennis Kobert
2025-09-19 12:19:46 +02:00
parent 1587ff164d
commit 4a9fb5162b
9 changed files with 105 additions and 9 deletions

View File

@@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Local dependencies
core-types = { workspace = true }
graphic-types = { workspace = true }
raster-types = { workspace = true, features = ["wgpu"] }
graphene-application-io = { workspace = true, features = ["wgpu"] }
rendering = { workspace = true }
@@ -22,3 +23,4 @@ web-sys = { workspace = true }
winit = { workspace = true }
vello = { workspace = true }
bytemuck = { workspace = true }
log = { workspace = true }

View File

@@ -1,6 +1,7 @@
mod context;
pub mod shader_runtime;
pub mod texture_conversion;
pub mod vector_to_raster;
use crate::shader_runtime::ShaderRuntime;
use anyhow::Result;

View File

@@ -0,0 +1,75 @@
use crate::WgpuExecutor;
use core_types::ops::Convert;
use core_types::table::Table;
use core_types::transform::Footprint;
use graphic_types::Vector;
use graphic_types::raster_types::{GPU, Raster};
use rendering::{Render, RenderOutputType, RenderParams};
use wgpu::{CommandEncoderDescriptor, TextureFormat, TextureViewDescriptor};
/// Converts Table<Vector> to Table<Raster<GPU>> by rendering each vector to Vello scene and then to texture
impl<'i> Convert<Table<Raster<GPU>>, &'i WgpuExecutor> for Table<Vector> {
async fn convert(self, footprint: Footprint, executor: &'i WgpuExecutor) -> Table<Raster<GPU>> {
// Create render parameters for Vello rendering
let render_params = RenderParams {
render_mode: graphic_types::vector_types::vector::style::RenderMode::Normal,
hide_artboards: false,
for_export: false,
render_output_type: RenderOutputType::Vello,
footprint,
..Default::default()
};
log::debug!("rasterizing vector data with footprint {footprint:?}");
let vector = &self;
log::debug!("{:?}", vector);
// Create a Vello scene for this vector
let mut scene = vello::Scene::new();
let mut context = crate::RenderContext::default();
// Render the vector to the Vello scene with the row's transform
vector.render_to_vello(&mut scene, footprint.transform, &mut context, &render_params);
// Render the scene to a GPU texture
let resolution = footprint.resolution;
let background = core_types::Color::BLACK;
// Use async rendering to get the texture
let texture = async {
executor
.render_vello_scene_to_texture(&scene, resolution, &context, background)
.await
.expect("Failed to render Vello scene to texture")
};
// Block on the texture creation (we're in an async context)
let texture = futures::executor::block_on(texture);
let device = &executor.context.device;
let queue = &executor.context.queue;
let mut encoder = device.create_command_encoder(&CommandEncoderDescriptor::default());
let blitter = wgpu::util::TextureBlitter::new(device, TextureFormat::Rgba8UnormSrgb);
let view = texture.create_view(&TextureViewDescriptor::default());
let new_texture = device.create_texture(&wgpu::wgt::TextureDescriptor {
label: None,
size: wgpu::Extent3d {
width: texture.width(),
height: texture.height(),
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT,
format: TextureFormat::Rgba8UnormSrgb,
view_formats: &[],
});
let new_view = new_texture.create_view(&TextureViewDescriptor::default());
blitter.copy(device, &mut encoder, &view, &new_view);
let command_buffer = encoder.finish();
queue.submit([command_buffer]);
Table::new_from_element(Raster::new_gpu(new_texture))
}
}