From 85bf17415a211a71a71ebd2d07b3bdbdc1828202 Mon Sep 17 00:00:00 2001 From: Noeri Huisman Date: Mon, 11 Dec 2023 20:54:19 +0100 Subject: [PATCH] Add support for fog, toneMapping, colorSpace conversion and logarithmicDepthBuffer to (m)sdf shaders --- src/shaders/msdf.js | 46 +++++++++++---- src/shaders/sdf.js | 138 +++++++++++++++++++++----------------------- 2 files changed, 102 insertions(+), 82 deletions(-) diff --git a/src/shaders/msdf.js b/src/shaders/msdf.js index 2b7d990478f..e66780748e3 100644 --- a/src/shaders/msdf.js +++ b/src/shaders/msdf.js @@ -1,26 +1,33 @@ var registerShader = require('../core/shader').registerShader; +var THREE = require('../lib/three'); var VERTEX_SHADER = [ - 'in vec2 uv;', - 'in vec3 position;', - 'uniform mat4 projectionMatrix;', - 'uniform mat4 modelViewMatrix;', + '#include ', + '#include ', + '#include ', + 'out vec2 vUV;', + 'void main(void) {', - ' gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);', ' vUV = uv;', + ' #include ', + ' #include ', + ' #include ', + ' #include ', '}' ].join('\n'); var FRAGMENT_SHADER = [ - 'precision highp float;', + '#include ', + '#include ', + '#include ', + 'uniform bool negate;', 'uniform float alphaTest;', 'uniform float opacity;', 'uniform sampler2D map;', 'uniform vec3 color;', 'in vec2 vUV;', - 'out vec4 fragColor;', 'float median(float r, float g, float b) {', ' return max(min(r, g), min(max(r, g), b));', @@ -50,7 +57,12 @@ var FRAGMENT_SHADER = [ ' // Do modified alpha test.', ' if (alpha < alphaTest * MODIFIED_ALPHATEST) { discard; return; }', - ' fragColor = vec4(color.xyz, alpha * opacity);', + ' gl_FragColor = vec4(color.xyz, alpha * opacity);', + + ' #include ', + ' #include ', + ' #include ', + ' #include ', '}' ].join('\n'); @@ -67,9 +79,21 @@ module.exports.Shader = registerShader('msdf', { opacity: {type: 'number', is: 'uniform', default: 1.0} }, - raw: true, - vertexShader: VERTEX_SHADER, - fragmentShader: FRAGMENT_SHADER + fragmentShader: FRAGMENT_SHADER, + + init: function (data) { + this.uniforms = THREE.UniformsUtils.merge([ + THREE.UniformsLib.fog, + this.initVariables(data, 'uniform') + ]); + this.material = new THREE.ShaderMaterial({ + uniforms: this.uniforms, + vertexShader: this.vertexShader, + fragmentShader: this.fragmentShader, + fog: true + }); + return this.material; + } }); diff --git a/src/shaders/sdf.js b/src/shaders/sdf.js index 152597287f3..18951fb3d15 100644 --- a/src/shaders/sdf.js +++ b/src/shaders/sdf.js @@ -1,95 +1,79 @@ var registerShader = require('../core/shader').registerShader; +var THREE = require('../lib/three'); var VERTEX_SHADER = [ - 'in vec2 uv;', - 'in vec3 position;', - 'uniform mat4 projectionMatrix;', - 'uniform mat4 modelViewMatrix;', + '#include ', + '#include ', + '#include ', + 'out vec2 vUV;', + 'void main(void) {', - ' gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);', ' vUV = uv;', + ' #include ', + ' #include ', + ' #include ', + ' #include ', '}' ].join('\n'); var FRAGMENT_SHADER = [ - 'precision highp float;', + '#include ', + '#include ', + '#include ', + 'uniform float alphaTest;', 'uniform float opacity;', 'uniform sampler2D map;', 'uniform vec3 color;', 'in vec2 vUV;', - 'out vec4 fragColor;', - '#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', + 'float contour(float width, float value) {', + ' return smoothstep(0.5 - value, 0.5 + value, width);', + '}', // 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 = texture(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(texture(map, box.xy).a, width)', - ' + contour(texture(map, box.zw).a, width)', - ' + contour(texture(map, box.xw).a, width)', - ' + contour(texture(map, box.zy).a, width)', - ' )) / 3.0;', - ' }', + ' vec2 uv = vUV;', + ' vec4 texColor = texture(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(texture(map, box.xy).a, width)', + ' + contour(texture(map, box.zw).a, width)', + ' + contour(texture(map, box.xw).a, width)', + ' + contour(texture(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 = texture(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', - - ' fragColor = vec4(color, opacity * alpha);', + ' if (alpha < alphaTest * MODIFIED_ALPHATEST) { discard; return; }', + + ' gl_FragColor = vec4(color, opacity * alpha);', + ' #include ', + ' #include ', + ' #include ', + ' #include ', '}' ].join('\n'); @@ -105,9 +89,21 @@ module.exports.Shader = registerShader('sdf', { opacity: {type: 'number', is: 'uniform', default: 1.0} }, - raw: true, - vertexShader: VERTEX_SHADER, - fragmentShader: FRAGMENT_SHADER + fragmentShader: FRAGMENT_SHADER, + + init: function (data) { + this.uniforms = THREE.UniformsUtils.merge([ + THREE.UniformsLib.fog, + this.initVariables(data, 'uniform') + ]); + this.material = new THREE.ShaderMaterial({ + uniforms: this.uniforms, + vertexShader: this.vertexShader, + fragmentShader: this.fragmentShader, + fog: true + }); + return this.material; + } });