Skip to content

feat: add anti-aliasing support for 3D models#1150

Merged
nekomeowww merged 1 commit intomoeru-ai:mainfrom
NJX-njx:NJX-njx/feat/3d-model-antialiasing
Mar 6, 2026
Merged

feat: add anti-aliasing support for 3D models#1150
nekomeowww merged 1 commit intomoeru-ai:mainfrom
NJX-njx:NJX-njx/feat/3d-model-antialiasing

Conversation

@NJX-njx
Copy link
Contributor

@NJX-njx NJX-njx commented Mar 5, 2026

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)

  • Added :dpr="renderScale" prop to TresCanvas, which renders at a higher resolution and downscales — the most effective anti-aliasing approach
  • Defaults to window.devicePixelRatio (capped at 2x) so HiDPI/4K displays render at native resolution instead of being upscaled from 1x

MSAA via EffectComposer (ThreeScene.vue)

  • Added :multisampling="multisampling" prop to EffectComposerPmndrs for hardware MSAA within the post-processing pipeline
  • Defaults to 4 samples (a good balance between quality and performance)

Configurable 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)
  • Both settings can be adjusted for performance tuning (lower values for weaker GPUs)

Why this approach

Per the issue, the user explicitly requested effective AA like MSAA/TAA or supersampling, not SMAA. This implementation provides:

  1. Supersampling via dpr — renders at higher resolution, most effective for fine geometry
  2. MSAA via multisampling on the EffectComposer — hardware-accelerated edge smoothing
  3. Both settings are configurable and persisted, so users can balance quality vs performance

Closes #1138

- 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
Copilot AI review requested due to automatic review settings March 5, 2026 15:55
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@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 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

  • Supersampling Implementation: Implemented supersampling for 3D models by adding a :dpr="renderScale" prop to TresCanvas, allowing rendering at a higher resolution and downscaling for improved visual quality. This defaults to window.devicePixelRatio (capped at 2x) for HiDPI/4K displays.
  • MSAA Integration: Integrated Multi-Sample Anti-Aliasing (MSAA) by adding a :multisampling="multisampling" prop to EffectComposerPmndrs, enabling hardware-accelerated edge smoothing within the post-processing pipeline with a default of 4 samples.
  • Configurable Quality Settings: Introduced renderScale and multisampling as new configurable settings in model-store.ts. These settings are persisted to localStorage, allowing users to adjust anti-aliasing quality versus performance.
Changelog
  • packages/stage-ui-three/src/components/ThreeScene.vue
    • Added renderScale and multisampling to the destructured storeToRefs(modelStore).
    • Bound renderScale to the :dpr prop of TresCanvas.
    • Bound multisampling to the :multisampling prop of EffectComposerPmndrs.
  • packages/stage-ui-three/src/stores/model-store.ts
    • Declared renderScale and multisampling as useLocalStorage variables with default values.
    • Exported renderScale and multisampling from the store.
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 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:

  1. A potential issue with Server-Side Rendering (SSR) due to direct window object access.
  2. A minor optimization regarding the antialias prop on the TresCanvas when using an EffectComposer.

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))
Copy link
Contributor

Choose a reason for hiding this comment

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

high

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.

Suggested change
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"
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

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"

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 renderScale into TresCanvas’s dpr prop.
  • Enable MSAA in the post-processing pipeline by passing multisampling to EffectComposerPmndrs.

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))
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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)

Copilot uses AI. Check for mistakes.
Comment on lines +142 to +144
// Rendering quality
const renderScale = useLocalStorage('settings/stage-ui-three/renderScale', Math.min(window.devicePixelRatio, 2))
const multisampling = useLocalStorage('settings/stage-ui-three/multisampling', 4)
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
@@ -314,6 +316,7 @@ defineExpose({
v-show="true"
:camera="camera"
:antialias="true"
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
:antialias="true"
:antialias="false"

Copilot uses AI. Check for mistakes.
@nekomeowww nekomeowww merged commit 5d571c5 into moeru-ai:main Mar 6, 2026
3 of 4 checks passed
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.

Feature Request : Add anti-aliasing (or supersampling) to 3D models

3 participants