Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add Pixel Preview render mode and fix Vello rendering regression with a tilted viewport#3847

Open
Keavon wants to merge 3 commits intomasterfrom
fix-tilt-add-pixel-render-mode
Open

Add Pixel Preview render mode and fix Vello rendering regression with a tilted viewport#3847
Keavon wants to merge 3 commits intomasterfrom
fix-tilt-add-pixel-render-mode

Conversation

@Keavon
Copy link
Member

@Keavon Keavon commented Mar 3, 2026

Closes #320. Fixes tilt behavior broken in #3722 with Vello rendering (the render modes Normal, Outline, and now this new mode Pixel Preview).

@Keavon Keavon requested a review from TrueDoctor March 3, 2026 02:59
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the editor's rendering capabilities by introducing a new 'Pixel Preview' mode, which allows users to inspect their designs at their final export resolution with pixel-perfect accuracy. Concurrently, it addresses and resolves a critical rendering regression that previously caused visual distortions when the viewport was tilted or rotated. These improvements ensure a more faithful and robust visual representation of the document under various viewing conditions.

Highlights

  • New Render Mode: Pixel Preview: Introduced a 'Pixel Preview' render mode that displays the document at its export resolution, showing individual pixels upscaled with nearest-neighbor filtering when zoomed in. This provides a precise view of the final pixel output.
  • Tilted Viewport Rendering Fix: Resolved a rendering regression that caused incorrect display when the viewport was tilted (rotated). The rendering pipeline now correctly composites cached regions and applies a bilinear resampling pass for accurate tilted views.
  • Generic Texture Resampling Utility: Added a new resample_texture function to the WGPU executor, capable of resampling textures with an affine transform using either nearest-neighbor or linear filtering. This is used for both Pixel Preview and tilted viewport corrections.
  • Improved Viewport Bounding Box Calculation: Enhanced the calculation of the viewport's axis-aligned bounding box in document space to correctly account for tilted viewports, ensuring all four corners are transformed to determine the true bounds.
Changelog
  • editor/src/messages/portfolio/document/document_message_handler.rs
    • Enabled the 'Pixel Preview' option within the render mode selection UI.
    • Updated the WebGPU compatibility fallback message to include 'Pixel Preview' as a mode that requires WebGPU.
  • node-graph/libraries/vector-types/src/vector/style.rs
    • Added the PixelPreview variant to the RenderMode enum.
    • Updated the documentation for the PixelPreview render mode to describe its behavior.
  • node-graph/libraries/wgpu-executor/src/lib.rs
    • Implemented a new public function resample_texture to perform affine texture resampling using WGPU, supporting both nearest and linear filtering.
    • Created a dedicated WGPU shader and pipeline for the texture resampling operation.
  • node-graph/nodes/gstd/src/render_cache.rs
    • Modified render_output_cache to accurately compute the axis-aligned bounding box (AABB) for tilted viewports by transforming all four corners.
    • Introduced logic to detect if the viewport is tilted based on the footprint transform.
    • Updated the composite_cached_regions function signature to accept has_tilt and footprint_transform parameters.
    • Adjusted composite_cached_regions to use an intermediate texture for compositing when the viewport is tilted, followed by a bilinear resampling step using resample_texture to apply the rotation.
    • Ensured correct pixel offset calculations for compositing into the potentially intermediate texture.
  • node-graph/nodes/gstd/src/render_node.rs
    • Imported necessary UVec2 and RenderMode types.
    • Implemented the core logic for the 'Pixel Preview' render mode: when active and zoomed in, it renders the scene at 100% document scale into an intermediate texture.
    • Calculated the document-space AABB of the viewport and snapped the origin to integer pixels for stable antialiasing in 'Pixel Preview' mode.
    • Applied an infinite-transform fix specifically sized for the document-resolution render target in 'Pixel Preview' mode.
    • Utilized the new resample_texture function with Nearest filtering to upscale the intermediate document texture to the final physical resolution, applying the viewport's inverse transform for 'Pixel Preview'.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully adds a Pixel Preview render mode and fixes a rendering regression with tilted viewports. The implementation for both features is solid. The fix for tilted viewports correctly uses a two-pass approach with an intermediate texture and resampling, and the calculation of the required transforms is accurate. The Pixel Preview mode also correctly renders at 100% scale and then upscales with nearest-neighbor filtering. I have a suggestion regarding uniform buffer construction.

Comment on lines +180 to +194
// Layout: mat2x2<f32> (4 floats = 16 bytes) + vec2<f32> (2 floats = 8 bytes) = 24 bytes
let mut params_data = [0_u8; 24];
params_data[0..4].copy_from_slice(&source_transform.x_axis.x.to_le_bytes());
params_data[4..8].copy_from_slice(&source_transform.x_axis.y.to_le_bytes());
params_data[8..12].copy_from_slice(&source_transform.y_axis.x.to_le_bytes());
params_data[12..16].copy_from_slice(&source_transform.y_axis.y.to_le_bytes());
params_data[16..20].copy_from_slice(&source_offset.x.to_le_bytes());
params_data[20..24].copy_from_slice(&source_offset.y.to_le_bytes());
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("resample_params"),
size: 24,
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
});
queue.write_buffer(&uniform_buf, 0, &params_data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Manually constructing the params_data byte array and using a magic number for the size is error-prone. It would be safer and more readable to define a #[repr(C)] struct that matches the shader's uniform buffer layout and use bytemuck to safely cast it to a byte slice. This avoids manual byte manipulation and makes the code's intent clearer.

You would need to add bytemuck = { version = "1", features = ["derive"] } to your Cargo.toml and use bytemuck::{Pod, Zeroable};.

		#[repr(C)]
		#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
		struct Uniforms {
			transform: glam::Mat2,
			offset: glam::Vec2,
		}

		let params_data = *bytemuck::cast_ref(&Uniforms {
			transform: source_transform,
			offset: source_offset,
		});

		let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
			label: Some("resample_params"),
			size: params_data.len() as u64,
			usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
			mapped_at_creation: false,
		});
		queue.write_buffer(&uniform_buf, 0, &params_data);

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement the Pixel Preview render mode

1 participant