Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update according to discussion
  • Loading branch information
nightgryphon committed Jul 17, 2023
commit f682e854bc08cebac111243b018d8a2bf49f4614
7 changes: 5 additions & 2 deletions src/core/shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,17 @@ Shader.prototype = {
* Called during shader initialization and is only run once.
*/
init: function (data) {
if( this.raw )
console.warn('RAW shaders enforced to GLSL3.');

this.attributes = this.initVariables(data, 'attribute');
this.uniforms = this.initVariables(data, 'uniform');
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,
glslVersion: this.glslVersion
fragmentShader: this.fragmentShader
});
return this.material;
},
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,7 @@
var registerShader = require('../core/shader').registerShader;
var THREE = require('../lib/three');

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 = [
var VERTEX_SHADER = [
'in vec2 uv;',
'in vec3 position;',
'uniform mat4 projectionMatrix;',
Expand All @@ -27,53 +13,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 = [
var FRAGMENT_SHADER = [
'precision highp float;',
'uniform bool negate;',
'uniform float alphaTest;',
Expand Down Expand Up @@ -115,8 +55,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 All @@ -135,6 +73,4 @@ module.exports.Shader = registerShader('msdf', {
vertexShader: VERTEX_SHADER,

fragmentShader: FRAGMENT_SHADER,

glslVersion: isWebGL2AVailable ? THREE.GLSL3 : null
});
108 changes: 2 additions & 106 deletions src/shaders/sdf.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
var registerShader = require('../core/shader').registerShader;
var THREE = require('../lib/three');

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 = [
var VERTEX_SHADER = [
'in vec2 uv;',
'in vec3 position;',
'uniform mat4 projectionMatrix;',
Expand All @@ -27,93 +13,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 = [
var FRAGMENT_SHADER = [
'precision highp float;',
'uniform float alphaTest;',
'uniform float opacity;',
Expand Down Expand Up @@ -194,8 +94,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 All @@ -213,6 +111,4 @@ module.exports.Shader = registerShader('sdf', {
vertexShader: VERTEX_SHADER,

fragmentShader: FRAGMENT_SHADER,

glslVersion: isWebGL2AVailable ? THREE.GLSL3 : null
});