Skip to content

Commit

Permalink
FIX sdf/msdf shaders, add Shader.glslVersion (#5328)
Browse files Browse the repository at this point in the history
* FIX sdf/msdf shaders, add Shader.glslVersion

* Update according to discussion

* Remove Shader.glslVersion

* Cleanup. Huh...

* Formatting checks...

* Remove warning
  • Loading branch information
nightgryphon authored Jul 18, 2023
1 parent 1e97b6d commit c185a2b
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 172 deletions.
1 change: 1 addition & 0 deletions src/core/shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Shader.prototype = {
this.material = new (this.raw ? THREE.RawShaderMaterial : THREE.ShaderMaterial)({
// attributes: this.attributes,
uniforms: this.uniforms,
glslVersion: this.raw ? THREE.GLSL3 : undefined,
vertexShader: this.vertexShader,
fragmentShader: this.fragmentShader
});
Expand Down
68 changes: 2 additions & 66 deletions src/shaders/msdf.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,6 @@
var registerShader = require('../core/shader').registerShader;

var isWebGL2AVailable = !!document.createElement('canvas').getContext('webgl2');

var VERTEX_SHADER_WEBGL1 = [
'attribute vec2 uv;',
'attribute vec3 position;',
'uniform mat4 projectionMatrix;',
'uniform mat4 modelViewMatrix;',
'varying vec2 vUV;',
'void main(void) {',
' gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
' vUV = uv;',
'}'
].join('\n');

var VERTEX_SHADER_WEBGL2 = [
'#version 300 es',
var VERTEX_SHADER = [
'in vec2 uv;',
'in vec3 position;',
'uniform mat4 projectionMatrix;',
Expand All @@ -27,54 +12,7 @@ var VERTEX_SHADER_WEBGL2 = [
'}'
].join('\n');

var VERTEX_SHADER = isWebGL2AVailable ? VERTEX_SHADER_WEBGL2 : VERTEX_SHADER_WEBGL1;

var FRAGMENT_SHADER_WEBGL1 = [
'#ifdef GL_OES_standard_derivatives',
'#extension GL_OES_standard_derivatives: enable',
'#endif',
'precision highp float;',
'uniform bool negate;',
'uniform float alphaTest;',
'uniform float opacity;',
'uniform sampler2D map;',
'uniform vec3 color;',
'varying vec2 vUV;',

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

// FIXME: Experimentally determined constants.
'#define BIG_ENOUGH 0.001',
'#define MODIFIED_ALPHATEST (0.02 * isBigEnough / BIG_ENOUGH)',

'void main() {',
' vec3 sampleColor = texture2D(map, vUV).rgb;',
' if (negate) { sampleColor = 1.0 - sampleColor; }',

' float sigDist = median(sampleColor.r, sampleColor.g, sampleColor.b) - 0.5;',
' float alpha = clamp(sigDist / fwidth(sigDist) + 0.5, 0.0, 1.0);',
' float dscale = 0.353505;',
' vec2 duv = dscale * (dFdx(vUV) + dFdy(vUV));',
' float isBigEnough = max(abs(duv.x), abs(duv.y));',

// When texel is too small, blend raw alpha value rather than supersampling.
// FIXME: Experimentally determined constant.
' // Do modified alpha test.',
' if (isBigEnough > BIG_ENOUGH) {',
' float ratio = BIG_ENOUGH / isBigEnough;',
' alpha = ratio * alpha + (1.0 - ratio) * (sigDist + 0.5);',
' }',

' // Do modified alpha test.',
' if (alpha < alphaTest * MODIFIED_ALPHATEST) { discard; return; }',
' gl_FragColor = vec4(color.xyz, alpha * opacity);',
'}'
].join('\n');

var FRAGMENT_SHADER_WEBGL2 = [
'#version 300 es',
var FRAGMENT_SHADER = [
'precision highp float;',
'uniform bool negate;',
'uniform float alphaTest;',
Expand Down Expand Up @@ -116,8 +54,6 @@ var FRAGMENT_SHADER_WEBGL2 = [
'}'
].join('\n');

var FRAGMENT_SHADER = isWebGL2AVailable ? FRAGMENT_SHADER_WEBGL2 : FRAGMENT_SHADER_WEBGL1;

/**
* Multi-channel signed distance field.
* Used by text component.
Expand Down
108 changes: 2 additions & 106 deletions src/shaders/sdf.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,6 @@
var registerShader = require('../core/shader').registerShader;

var isWebGL2AVailable = !!document.createElement('canvas').getContext('webgl2');

var VERTEX_SHADER_WEBGL1 = [
'attribute vec2 uv;',
'attribute vec3 position;',
'uniform mat4 projectionMatrix;',
'uniform mat4 modelViewMatrix;',
'varying vec2 vUV;',
'void main(void) {',
' gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
' vUV = uv;',
'}'
].join('\n');

var VERTEX_SHADER_WEBGL2 = [
'#version 300 es',
var VERTEX_SHADER = [
'in vec2 uv;',
'in vec3 position;',
'uniform mat4 projectionMatrix;',
Expand All @@ -27,94 +12,7 @@ var VERTEX_SHADER_WEBGL2 = [
'}'
].join('\n');

var VERTEX_SHADER = isWebGL2AVailable ? VERTEX_SHADER_WEBGL2 : VERTEX_SHADER_WEBGL1;

var FRAGMENT_SHADER_WEBGL1 = [
'#ifdef GL_OES_standard_derivatives',
'#extension GL_OES_standard_derivatives: enable',
'#endif',

'precision highp float;',
'uniform float alphaTest;',
'uniform float opacity;',
'uniform sampler2D map;',
'uniform vec3 color;',
'varying vec2 vUV;',

'#ifdef GL_OES_standard_derivatives',
' float contour(float width, float value) {',
' return smoothstep(0.5 - value, 0.5 + value, width);',
' }',
'#else',
' float aastep(float value, float afwidth) {',
' return smoothstep(0.5 - afwidth, 0.5 + afwidth, value);',
' }',
'#endif',

// FIXME: Experimentally determined constants.
'#define BIG_ENOUGH 0.001',
'#define MODIFIED_ALPHATEST (0.02 * isBigEnough / BIG_ENOUGH)',
'#define ALL_SMOOTH 0.4',
'#define ALL_ROUGH 0.02',
'#define DISCARD_ALPHA (alphaTest / (2.2 - 1.2 * ratio))',

'void main() {',
// When we have derivatives and can get texel size for supersampling.
' #ifdef GL_OES_standard_derivatives',
' vec2 uv = vUV;',
' vec4 texColor = texture2D(map, uv);',
' float dist = texColor.a;',
' float width = fwidth(dist);',
' float alpha = contour(dist, width);',
' float dscale = 0.353505;',

' vec2 duv = dscale * (dFdx(uv) + dFdy(uv));',
' float isBigEnough = max(abs(duv.x), abs(duv.y));',

// When texel is too small, blend raw alpha value rather than supersampling.
// FIXME: experimentally determined constant
' if (isBigEnough > BIG_ENOUGH) {',
' float ratio = BIG_ENOUGH / isBigEnough;',
' alpha = ratio * alpha + (1.0 - ratio) * dist;',
' }',

// Otherwise do weighted supersampling.
// FIXME: why this weighting?
' if (isBigEnough <= BIG_ENOUGH) {',
' vec4 box = vec4 (uv - duv, uv + duv);',
' alpha = (alpha + 0.5 * (',
' contour(texture2D(map, box.xy).a, width)',
' + contour(texture2D(map, box.zw).a, width)',
' + contour(texture2D(map, box.xw).a, width)',
' + contour(texture2D(map, box.zy).a, width)',
' )) / 3.0;',
' }',

// Do modified alpha test.
' if (alpha < alphaTest * MODIFIED_ALPHATEST) { discard; return; }',

' #else',
// When we don't have derivatives, use approximations.
' vec4 texColor = texture2D(map, vUV);',
' float value = texColor.a;',
// FIXME: if we understood font pixel dimensions, this could probably be improved
' float afwidth = (1.0 / 32.0) * (1.4142135623730951 / (2.0 * gl_FragCoord.w));',
' float alpha = aastep(value, afwidth);',

// Use gl_FragCoord.w to guess when we should blend.
// FIXME: If we understood font pixel dimensions, this could probably be improved.
' float ratio = (gl_FragCoord.w >= ALL_SMOOTH) ? 1.0 : (gl_FragCoord.w < ALL_ROUGH) ? 0.0 : (gl_FragCoord.w - ALL_ROUGH) / (ALL_SMOOTH - ALL_ROUGH);',
' if (alpha < alphaTest) { if (ratio >= 1.0) { discard; return; } alpha = 0.0; }',
' alpha = alpha * ratio + (1.0 - ratio) * value;',
' if (ratio < 1.0 && alpha <= DISCARD_ALPHA) { discard; return; }',
' #endif',

' gl_FragColor = vec4(color, opacity * alpha);',
'}'
].join('\n');

var FRAGMENT_SHADER_WEBGL2 = [
'#version 300 es',
var FRAGMENT_SHADER = [
'precision highp float;',
'uniform float alphaTest;',
'uniform float opacity;',
Expand Down Expand Up @@ -195,8 +93,6 @@ var FRAGMENT_SHADER_WEBGL2 = [
'}'
].join('\n');

var FRAGMENT_SHADER = isWebGL2AVailable ? FRAGMENT_SHADER_WEBGL2 : FRAGMENT_SHADER_WEBGL1;

/**
* Signed distance field.
* Used by text component.
Expand Down

0 comments on commit c185a2b

Please sign in to comment.