dataarts / dat.guiVR

A flexible graphical user interface for changing variables within WebVR.
https://workshop.chromeexperiments.com/examples/guiVR/
Apache License 2.0
312 stars 49 forks source link

SDF fonts look like crap when small or at an angle #42

Closed customlogic closed 8 years ago

customlogic commented 8 years ago

The SDF fonts look pretty crappy and un-readable when small or at an angle, especially compared to the geometry based text we used on the GUI in Virtual Art Sessions VR.

Can we do anything to make the font more legible at a small size? This thread might have some tips: http://www.java-gaming.org/index.php?topic=33612.0

customlogic commented 8 years ago

I did some playing around.. setting the alphaTest value of the shader material to a smaller number helps a little bit (0.00001 say). Making the font bigger helps too, but doesn't eliminate the problem.

The latest version of the library supports something called "msdf", which might be worth looking into

mflux commented 8 years ago

Part of the problem is we're trying to save on file size...

In your linked example he's having problems at 1024x1024. We're only using 512x512. We could double the size but that would quadruple the filesize.

I'll see what I can do about the alphatest. There's probably also adjustments to be made when generating the font spritesheet.

customlogic commented 8 years ago

I don't think it's related to the quality of the texture.. it looks really good up-close. The problem is how it handles tiny font. I think the idea of "supersampling" is probably the fix, but it would require changing the shader in the SDF library. It looks like the MSDF shader is meant to create sharper fonts, but I'm not sure exactly if it'll fix our problem

mflux commented 8 years ago

I'm not sure either. We may have to ask an adult about this. I'm way out of my depth as far as SDF fonts go, I'm surprised it even functions -at all-.

Perhaps we can ask Matt DesLauriers or Jaume.

customlogic commented 8 years ago

Hahah, sounds good. Do you know Matt? I don't, but could try getting in touch. He's probably the best place to start

mflux commented 8 years ago

I'll get in touch and follow up.

mflux commented 8 years ago

So one thing we can do to enhance sharpness is enabling Anisotropic filtering. This does mean we have to pass in THREE.Renderer into datguivr though, because it needs the renderer to figure out the highest supported aniso value.

mflux commented 8 years ago

It looks experimental but there's an MSDF font generating path. Perhaps you can try it out? https://github.com/Jam3/three-bmfont-text/blob/master/docs/sdf.md

It supposedly works with the THREE-BMT-FNT we're using already, we probably need to update its shaders or something.

customlogic commented 8 years ago

Sweet, I'll look into those things.

mflux commented 8 years ago

Ok so the verdict to anisotropic filtering...

On this line here:

https://github.com/dataarts/dat.guiVR/blob/master/modules/datguivr/sdftext.js#L36

We should create a 1px canvas and then get the 3D context. Then, do what THREE.js does here: https://github.com/mrdoob/three.js/blob/master/src/renderers/webgl/WebGLCapabilities.js

for getMaxAnistropy

And finally we set that value in the texture's anistropicFiltering param.

customlogic commented 8 years ago

Ah, that's much better! I just did a quick test by getting the Anisotropy value from console.log(renderer.capabilities.getMaxAnisotropy()) For me, the value is 16. So I just hard coded that into sdftext.js and it looks much better.

DAT.gui VR doesn't know anything about the existing renderer, does it? You think creating a temp 1px canvas is the best way?

mflux commented 8 years ago

Nice! But I don't think we should hard-code that though, as far as I can tell this will break on systems that don't support that anistropy level.

Creating a 1px canvas is probably the best way. Less friction for the user, since yeah DATGUIVR knows nothing of the renderer.

On Wed, Sep 28, 2016 at 3:54 PM, Jeff Nusz notifications@github.com wrote:

Ah, that's much better! I just did a quick test by getting the Anistropy value from console.log(renderer.capabilities.getMaxAnisotropy()) For me, the value is 16. So I just hard coded that into sdftext.js and it looks much better.

DAT.gui VR doesn't know anything about the existing renderer, does it? You think creating a temp 1px canvas is the best way?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/dataarts/dat.guiVR/issues/42#issuecomment-250325072, or mute the thread https://github.com/notifications/unsubscribe-auth/AA_j0Fk9_idJ_yd93KWFDadme7i5xf1Wks5quvAIgaJpZM4KJMAT .

mflux commented 8 years ago

Oh maybe we should also try disabling mipmaps

texture.generateMipmaps = false;

customlogic commented 8 years ago

I tried that quickly, but didn't have any luck. All the letters turned into white squares. Maybe I was missing somethings?

On Wednesday, 28 September 2016, Michael Chang notifications@github.com wrote:

Oh maybe we should also try disabling mipmaps

texture.generateMipmaps = false;

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dataarts/dat.guiVR/issues/42#issuecomment-250331093, or mute the thread https://github.com/notifications/unsubscribe-auth/ABHLpMYvXv83m4S5zIIBsTwVICM3MZLuks5quvhOgaJpZM4KJMAT .

customlogic commented 8 years ago

Turning off MipMaps did it! I had to changetexture.minFilter to THREE.LinearFilter rather than THREE.LinearMipMapLinearFilter for it to work properly

It looks fine now, no need for any change to anistrophy or alphaTest. I've pushed the fix in d98ff13cb4bc3a763a4eae6a552b61f430bb7382