Skip to content

Conversation

Glypse
Copy link

@Glypse Glypse commented Aug 13, 2025

This is my first PR to three.js.

When using the Ascii Effect, I thought it'd be nice to be able to use a user-specified font and to pass in a post-processed render as input (instead of the bare render only). This PR is mainly focused on achieving those two things.

Exhaustive changelog (at time of first commit):

  • Moved charSet inside the constructor options.
    • I understand this might be a breaking change, in which case that would not be accepted, but I believe it makes sense. Previously, you had to input a charSet to be able to set the options (unless I'm mistaken, not yet a Javascript pro). Now, you don't have to specify it to access the other options, but you can.
  • Added fontFamily, fontWeight, fontSize and letterSpacing options. fontFamily and fontWeight are because they're the main goal of this PR, but it turns out that monospace fonts' characters are rarely fitting in a perfect square: if the user adds a custom fontFamily, they'll want to customize letterSpacing, otherwise the output might be squished/stretched.
  • Added composer as an option, allowing to pass a post-processed render as input of the Ascii Effect, instead of the bare render only.
  • Updated the logic accordingly.
  • Updated the example page with UnrealBloomPass to show the newly added option.
  • Set the canvas pixelRatio to the AsciiEffect's for performance gain.

Possible mistakes to look out for (my first three.js PR)

  • strFontSize defaults to 'Dynamically computed according to resolution'. This allows for logic check later, but might be misinterpreted by users/LLMs trying to use the effect.
  • Incorrect JSDoc usage, type checking, etc.
  • Breaking change by moving charSet inside the constructor options.

@Glypse
Copy link
Author

Glypse commented Aug 13, 2025

Do I need to take care of Definitely Typed/three? Is it automatic? Will another contributor take care of it?

@cmhhelgeson
Copy link
Contributor

Do I need to take care of Definitely Typed/three? Is it automatic? Will another contributor take care of it?

DefinitelyTyped should inherit the JSDoc types. There's typically no need to make a separate PR for DefinitelyTyped/three unless it's a special case or you encounter type errors after your code has been implemented.

@WestLangley
Copy link
Collaborator

Temporary live example:

https://raw.githack.com/Glypse/three.js/moreAsciiEffectFeatures/examples/webgl_effects_ascii.html

@Mugen87
Copy link
Collaborator

Mugen87 commented Aug 13, 2025

In general, it's not recommended to add too many features at once to an addon. This makes it less likely the PR is merged since the review process tends to be long and sometimes the PR just gets lost. How about focusing on a single feature for now?

@Glypse
Copy link
Author

Glypse commented Aug 13, 2025

@Mugen87 understood and agreed. Would love to know what you think should be prioritized?

@Mugen87
Copy link
Collaborator

Mugen87 commented Aug 13, 2025

Added fontFamily, fontWeight, fontSize and letterSpacing options. fontFamily and fontWeight are because they're the main goal of this PR, but it turns out that monospace fonts' characters are rarely fitting in a perfect square: if the user adds a custom fontFamily, they'll want to customize letterSpacing, otherwise the output might be squished/stretched.

How about this one? Using custom font settings sounds interesting.

@Glypse
Copy link
Author

Glypse commented Aug 14, 2025

First commit of these two is to simplify the commit back to only font-features. Second is to address the XSS concern that DeepScan had, with minimal performance impact. I don't know much about cross-site scripting but the solution, pretty simple, was partially made by Claude Sonnet 4.

@Glypse
Copy link
Author

Glypse commented Aug 14, 2025

This commits adds two things:

  • A major optimization to the rendering: if the asciiEffect resolution is set to a low value (0.15 by default), there is no need to render the canvas at full pixel density. Setting it to have a pixelRatio equal to the resolution of the asciiEffect greatly saves on ressources. I don't see why a user would want the canvas to be rendered at a high resolution, for it to then only be rendered in ascii at a fraction. Please correct me if I'm wrong.
  • Added stats and controls.

The propositions I'm making to the font customisation seem to have broken the Scale and String Resolution, but I frankly still do not understand their original purpose. I propose to get rid of them.

Live example at https://raw.githack.com/Glypse/three.js/moreAsciiEffectFeatures/examples/webgl_effects_ascii.html

@Glypse Glypse marked this pull request as draft August 14, 2025 13:19
@Glypse
Copy link
Author

Glypse commented Aug 14, 2025

Converting this to draft because the current system is too unstable and I spotted quite a few bugs. Will work on an auto-detection function for letter spacing, instead of having to deal with letter spacing manually.

@Glypse
Copy link
Author

Glypse commented Aug 14, 2025

This commit:

  • Adds a dispose method.
  • Replaces the previously implemented manual spacing for automatic spacing management. The user now can properly choose any truly monospace font and the effect will compute the proper letter spacing for perfectly square pixel (the previous implementation had 2 letters per pixel horizontally). I believe the current implementation to be much better for getting a good result fast.
  • Adds the updateVisualSettings function that allows for changing options of the effect without needing to completely recompute all values, just what's needed. This is a big performance upgrade compared to last commit.
  • Removes the scale and strResolution options as they would interfere with the current implementation.

@Glypse Glypse marked this pull request as ready for review August 14, 2025 16:15
@Glypse
Copy link
Author

Glypse commented Aug 14, 2025

I guess maybe I should add an optional parameter to output 2 characters per horizontal pixel, like the effect previously did? Currently, the computed render has a 2* higher pixel density than the ascii output, but each character occupies a perfect square, whereas they previously occupied a 1:2 rectangle.

Would love to have your thoughts.

@Glypse
Copy link
Author

Glypse commented Aug 14, 2025

Just noticed this only behaves correctly on desktop Firefox. Switching to draft again until I figure this out.

@Glypse Glypse marked this pull request as draft August 14, 2025 19:05
@Glypse Glypse marked this pull request as ready for review August 15, 2025 10:29
@Glypse
Copy link
Author

Glypse commented Aug 15, 2025

This is in a state that I believe has good performance, useful options, and fully working. Would love your input. As usual, find it at https://raw.githack.com/Glypse/three.js/moreAsciiEffectFeatures/examples/webgl_effects_ascii.html

@Glypse
Copy link
Author

Glypse commented Aug 15, 2025

Safari does render the line-height weirdly, but I'll blame that on them, except if anyone has a potential fix.

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.

4 participants