Experience-Monks / three-bmfont-text

renders BMFont files in ThreeJS with word-wrapping
http://jam3.github.io/three-bmfont-text/test/
MIT License
789 stars 172 forks source link

MSDFShader doesn't work under three@0.120.1 #38

Open gabitovanf opened 4 years ago

gabitovanf commented 4 years ago

With the latest versions:

three-bmfont-text v3.0.1 three v0.120.1

MSDFShader doesn't work

image

Test it here https://codesandbox.io/s/02-vertex-shader-forked-xz1cu?file=/src/components/WebGLFont/WebGLFont.js with the latest versions of the packages mentioned above.

(It is the demo to https://tympanus.net/codrops/2019/10/10/create-text-in-three-js-with-three-bmfont-text/)

If it's possible to configure renderer to render text correctly and not to get this error? Could you recommend something? Thank you!

gabitovanf commented 4 years ago

The problem has been the case from three v0.118.0.

usefulthink commented 4 years ago

Stumbled across this one as well. Solution is to use the WebGL1Renderer for now. To quote from the three docs:

Since r118 WebGLRenderer automatically uses a WebGL 2 rendering context. When upgrading an existing project to => r118, applications might break because of two reasons:

  • Custom shader code needs to be GLSL 3.0 conform.
  • WebGL 1 extension checks have to be changed.

If you replace your THREE.WebGLRenderer with THREE.WebGL1Renderer it should be back to working. Otherwise, I guess you'd need to update the shader to be GLES3.0 conforming, haven't looked into what that would need...

gusvogel commented 4 years ago

Hi, I ran into the same issue. I ended up updating the msdf shaders to #version 300 es for my own project.

vertexShader: '#version 300 es\n' + [ 'in vec2 uv;', 'in vec4 position;', 'uniform mat4 projectionMatrix;', 'uniform mat4 modelViewMatrix;', 'out vec2 vUv;', 'void main() {', 'vUv = uv;', 'gl_Position = projectionMatrix * modelViewMatrix * position;', '}' ].join('\n'), fragmentShader: [ '#version 300 es', '#ifdef GL_OES_standard_derivatives', '#extension GL_OES_standard_derivatives : enable', '#endif', 'precision ' + precision + ' float;', 'uniform float opacity;', 'uniform vec3 color;', 'uniform sampler2D map;', 'in vec2 vUv;', 'out vec4 myOutputColor;', 'float median(float r, float g, float b) {', ' return max(min(r, g), min(max(r, g), b));', '}', 'void main() {', ' vec3 s = ' + (negate ? '1.0 - ' : '') + 'texture(map, vUv).rgb;', ' float sigDist = median(s.r, s.g, s.b) - 0.5;', ' float alpha = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0);', ' myOutputColor = vec4(color.xyz, alpha * opacity);', alphaTest === 0 ? '' : ' if (myOutputColor.a < ' + alphaTest + ') discard;', '}' ].join('\n')

sorry can't get the formatting right but this replaces the code in msdf.js

it was straightforward to convert each compilation error one by one, referencing from: https://webgl2fundamentals.org/webgl/lessons/webgl1-to-webgl2.html

marioecg commented 4 years ago

I also stumbled upon this issue, either solution works good. Here are the formatted shaders from @gusvogel in case anyone needs it:

#version 300 es

in vec2 uv;
in vec4 position;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
out vec2 vUv;

void main() {
  vUv = uv;
  gl_Position = projectionMatrix * modelViewMatrix * position;
}
#version 300 es
#ifdef GL_OES_standard_derivatives
#extension GL_OES_standard_derivatives : enable
#endif

precision highp float;

uniform float opacity;
uniform vec3 color;
uniform sampler2D map;
in vec2 vUv;
out vec4 myOutputColor;

float median(float r, float g, float b) {
  return max(min(r, g), min(max(r, g), b));
}

void main() {
  vec3 s = texture(map, vUv).rgb;
  float sigDist = median(s.r, s.g, s.b) - 0.5;
  float alpha = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0);
  myOutputColor = vec4(color.xyz, alpha * opacity);
  if (myOutputColor.a < 0.0001) discard;
}
gusvogel commented 4 years ago

Thanks for formatting. I forgot to get back to this. One update, there's no need for the lines

ifdef GL_OES_standard_derivatives

extension GL_OES_standard_derivatives : enable

endif

I'm pretty sure this will always resolve to not defined, and so will do nothing since webgl2 has this extension as part of the main standard.