feat: add anti-aliasing support for 3D models#1150
Conversation
- Add renderScale setting (defaults to devicePixelRatio, capped at 2x) for supersampling on HiDPI/4K displays - Add multisampling setting (defaults to 4 samples) for MSAA via the post-processing EffectComposer - Pass dpr prop to TresCanvas for native-resolution rendering - Both settings are persisted to localStorage and configurable Closes moeru-ai#1138
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Summary of ChangesHello, 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 introduces comprehensive anti-aliasing support for 3D VRM models, addressing issues with jagged rendering on various display resolutions. It implements two primary anti-aliasing techniques: supersampling via device pixel ratio and Multi-Sample Anti-Aliasing (MSAA) through the effect composer. Both methods are made configurable and persistable, empowering users to fine-tune rendering quality and performance according to their hardware capabilities. Highlights
Changelog
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this comment.
Code Review
This pull request introduces configurable anti-aliasing for 3D models, which is a great improvement for rendering quality. The implementation provides both supersampling via DPR and MSAA through the effect composer, giving users flexible control over performance and quality.
I've identified a couple of areas for improvement:
- A potential issue with Server-Side Rendering (SSR) due to direct
windowobject access. - A minor optimization regarding the
antialiasprop on theTresCanvaswhen using anEffectComposer.
My detailed comments are below. Overall, this is a solid feature addition.
Note: Security Review did not run due to the size of the PR.
| const ambientLightIntensity = useLocalStorage('settings/stage-ui-three/scenes/scene/ambient-light/intensity', 0.6) | ||
|
|
||
| // Rendering quality | ||
| const renderScale = useLocalStorage('settings/stage-ui-three/renderScale', Math.min(window.devicePixelRatio, 2)) |
There was a problem hiding this comment.
Direct access to window.devicePixelRatio during store initialization can cause the application to crash in a Server-Side Rendering (SSR) environment where the window object is not available. It's safer to guard this access to ensure it only runs on the client side.
| const renderScale = useLocalStorage('settings/stage-ui-three/renderScale', Math.min(window.devicePixelRatio, 2)) | |
| const renderScale = useLocalStorage('settings/stage-ui-three/renderScale', typeof window !== 'undefined' ? Math.min(window.devicePixelRatio, 2) : 2) |
| @@ -314,6 +316,7 @@ defineExpose({ | |||
| v-show="true" | |||
| :camera="camera" | |||
| :antialias="true" | |||
There was a problem hiding this comment.
When using an EffectComposer with its own anti-aliasing capabilities (like the :multisampling prop), the antialias prop on the main <TresCanvas> is typically not needed and should be set to false. The composer manages its own render targets and anti-aliasing, so enabling it on the canvas can be redundant and may have a small performance overhead without providing any visual benefit.
:antialias="false"
There was a problem hiding this comment.
Pull request overview
Adds anti-aliasing controls for VRM rendering in stage-ui-three by introducing configurable supersampling (via DPR) and MSAA (via post-processing multisampling), persisted in localStorage.
Changes:
- Add persisted rendering-quality settings (
renderScale,multisampling) to the 3D model Pinia store. - Apply supersampling by wiring
renderScaleintoTresCanvas’sdprprop. - Enable MSAA in the post-processing pipeline by passing
multisamplingtoEffectComposerPmndrs.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/stage-ui-three/src/stores/model-store.ts | Introduces persisted AA-related settings (renderScale, multisampling). |
| packages/stage-ui-three/src/components/ThreeScene.vue | Wires the new settings into TresCanvas DPR and EffectComposer multisampling. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const ambientLightIntensity = useLocalStorage('settings/stage-ui-three/scenes/scene/ambient-light/intensity', 0.6) | ||
|
|
||
| // Rendering quality | ||
| const renderScale = useLocalStorage('settings/stage-ui-three/renderScale', Math.min(window.devicePixelRatio, 2)) |
There was a problem hiding this comment.
renderScale default reads window.devicePixelRatio inside the store setup. This will throw ReferenceError: window is not defined in non-browser contexts (e.g., Vitest runs stage-ui tests in a Node environment) if useModelStore() is ever instantiated there. Use a guarded access (e.g., typeof window !== 'undefined' ? window.devicePixelRatio : 1) or VueUse's defaultWindow/useDevicePixelRatio to avoid hard dependency on window.
| const renderScale = useLocalStorage('settings/stage-ui-three/renderScale', Math.min(window.devicePixelRatio, 2)) | |
| const initialRenderScale = typeof window !== 'undefined' ? Math.min(window.devicePixelRatio, 2) : 1 | |
| const renderScale = useLocalStorage('settings/stage-ui-three/renderScale', initialRenderScale) |
| // Rendering quality | ||
| const renderScale = useLocalStorage('settings/stage-ui-three/renderScale', Math.min(window.devicePixelRatio, 2)) | ||
| const multisampling = useLocalStorage('settings/stage-ui-three/multisampling', 4) |
There was a problem hiding this comment.
Because renderScale is persisted as an absolute DPR value, the first run on a HiDPI screen (e.g., DPR=2) will save 2 and later sessions on a low-DPI screen will still render at 2x unless the user manually resets it. If the intended behavior is a multiplier (as described in the PR), consider persisting a multiplier (default 1) and computing the effective DPR from devicePixelRatio at runtime (still clamped) so it adapts across displays.
| @@ -314,6 +316,7 @@ defineExpose({ | |||
| v-show="true" | |||
| :camera="camera" | |||
| :antialias="true" | |||
There was a problem hiding this comment.
With EffectComposerPmndrs always present, :antialias="true" on TresCanvas typically won’t provide MSAA for the postprocessing render targets, but it can still allocate an MSAA backbuffer on the renderer. Since you’re already doing AA via :dpr and composer :multisampling, consider turning renderer antialias off when the composer is enabled to avoid extra GPU cost.
| :antialias="true" | |
| :antialias="false" |
Summary
Adds configurable anti-aliasing for 3D VRM models to fix aliased/jagged rendering on both 1080p and 4K displays. Addresses #1138.
Changes
Supersampling via Device Pixel Ratio (ThreeScene.vue)
:dpr="renderScale"prop to TresCanvas, which renders at a higher resolution and downscales — the most effective anti-aliasing approachwindow.devicePixelRatio(capped at 2x) so HiDPI/4K displays render at native resolution instead of being upscaled from 1xMSAA via EffectComposer (ThreeScene.vue)
:multisampling="multisampling"prop to EffectComposerPmndrs for hardware MSAA within the post-processing pipelineConfigurable Settings (model-store.ts)
renderScale: Pixel ratio multiplier (persisted to localStorage, default:Math.min(devicePixelRatio, 2))multisampling: MSAA sample count (persisted to localStorage, default: 4)Why this approach
Per the issue, the user explicitly requested effective AA like MSAA/TAA or supersampling, not SMAA. This implementation provides:
dpr— renders at higher resolution, most effective for fine geometrymultisamplingon the EffectComposer — hardware-accelerated edge smoothingCloses #1138