Implement subpixel ECAA
This commit is contained in:
parent
6cbc7dc082
commit
3ee066bdf0
|
@ -28,7 +28,11 @@ interface UpperAndLower<T> {
|
||||||
export abstract class ECAAStrategy extends AntialiasingStrategy {
|
export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
constructor(level: number, subpixelAA: boolean) {
|
constructor(level: number, subpixelAA: boolean) {
|
||||||
super();
|
super();
|
||||||
this.framebufferSize = glmatrix.vec2.create();
|
|
||||||
|
this.subpixelAA = subpixelAA;
|
||||||
|
|
||||||
|
this.supersampledFramebufferSize = glmatrix.vec2.create();
|
||||||
|
this.destFramebufferSize = glmatrix.vec2.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
init(view: MonochromePathfinderView) {
|
init(view: MonochromePathfinderView) {
|
||||||
|
@ -52,7 +56,10 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
setFramebufferSize(view: MonochromePathfinderView) {
|
setFramebufferSize(view: MonochromePathfinderView) {
|
||||||
this.framebufferSize = view.destAllocatedSize;
|
this.destFramebufferSize = glmatrix.vec2.clone(view.destAllocatedSize);
|
||||||
|
glmatrix.vec2.mul(this.supersampledFramebufferSize,
|
||||||
|
this.destFramebufferSize,
|
||||||
|
this.supersampleScale);
|
||||||
|
|
||||||
this.initDirectFramebuffer(view);
|
this.initDirectFramebuffer(view);
|
||||||
this.initEdgeDetectFramebuffer(view);
|
this.initEdgeDetectFramebuffer(view);
|
||||||
|
@ -65,8 +72,9 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected initDirectFramebuffer(view: MonochromePathfinderView) {
|
protected initDirectFramebuffer(view: MonochromePathfinderView) {
|
||||||
this.directColorTexture = createFramebufferColorTexture(view.gl, this.framebufferSize);
|
this.directColorTexture = createFramebufferColorTexture(view.gl, this.destFramebufferSize);
|
||||||
this.directPathIDTexture = createFramebufferColorTexture(view.gl, this.framebufferSize);
|
this.directPathIDTexture = createFramebufferColorTexture(view.gl,
|
||||||
|
this.destFramebufferSize);
|
||||||
this.directFramebuffer =
|
this.directFramebuffer =
|
||||||
createFramebuffer(view.gl,
|
createFramebuffer(view.gl,
|
||||||
view.drawBuffersExt,
|
view.drawBuffersExt,
|
||||||
|
@ -81,15 +89,16 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
view.gl.texImage2D(view.gl.TEXTURE_2D,
|
view.gl.texImage2D(view.gl.TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
view.gl.RGB,
|
view.gl.RGB,
|
||||||
this.framebufferSize[0],
|
this.supersampledFramebufferSize[0],
|
||||||
this.framebufferSize[1],
|
this.supersampledFramebufferSize[1],
|
||||||
0,
|
0,
|
||||||
view.gl.RGB,
|
view.gl.RGB,
|
||||||
view.textureHalfFloatExt.HALF_FLOAT_OES,
|
view.textureHalfFloatExt.HALF_FLOAT_OES,
|
||||||
null);
|
null);
|
||||||
setTextureParameters(view.gl, view.gl.NEAREST);
|
setTextureParameters(view.gl, view.gl.NEAREST);
|
||||||
|
|
||||||
this.aaDepthTexture = createFramebufferDepthTexture(view.gl, this.framebufferSize);
|
this.aaDepthTexture = createFramebufferDepthTexture(view.gl,
|
||||||
|
this.supersampledFramebufferSize);
|
||||||
|
|
||||||
this.aaFramebuffer = createFramebuffer(view.gl,
|
this.aaFramebuffer = createFramebuffer(view.gl,
|
||||||
view.drawBuffersExt,
|
view.drawBuffersExt,
|
||||||
|
@ -219,9 +228,12 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare(view: MonochromePathfinderView) {
|
prepare(view: MonochromePathfinderView) {
|
||||||
const usedSize = view.destUsedSize;
|
const usedSize = this.supersampledUsedSize(view);;
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.directFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.directFramebuffer);
|
||||||
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
view.gl.viewport(0,
|
||||||
|
0,
|
||||||
|
this.supersampledFramebufferSize[0],
|
||||||
|
this.supersampledFramebufferSize[1]);
|
||||||
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
||||||
view.gl.enable(view.gl.SCISSOR_TEST);
|
view.gl.enable(view.gl.SCISSOR_TEST);
|
||||||
|
|
||||||
|
@ -268,9 +280,12 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
private cover(view: MonochromePathfinderView) {
|
private cover(view: MonochromePathfinderView) {
|
||||||
// Set state for conservative coverage.
|
// Set state for conservative coverage.
|
||||||
const coverProgram = view.shaderPrograms.ecaaCover;
|
const coverProgram = view.shaderPrograms.ecaaCover;
|
||||||
const usedSize = view.destUsedSize;
|
const usedSize = this.supersampledUsedSize(view);
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.aaFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.aaFramebuffer);
|
||||||
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
view.gl.viewport(0,
|
||||||
|
0,
|
||||||
|
this.supersampledFramebufferSize[0],
|
||||||
|
this.supersampledFramebufferSize[1]);
|
||||||
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
||||||
view.gl.enable(view.gl.SCISSOR_TEST);
|
view.gl.enable(view.gl.SCISSOR_TEST);
|
||||||
|
|
||||||
|
@ -290,6 +305,7 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0);
|
this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0);
|
||||||
this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1);
|
this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1);
|
||||||
view.pathTransformBufferTexture.bind(view.gl, uniforms, 2);
|
view.pathTransformBufferTexture.bind(view.gl, uniforms, 2);
|
||||||
|
view.gl.uniform1f(uniforms.uScaleX, this.supersampleScale[0]);
|
||||||
view.instancedArraysExt.drawElementsInstancedANGLE(view.gl.TRIANGLES,
|
view.instancedArraysExt.drawElementsInstancedANGLE(view.gl.TRIANGLES,
|
||||||
6,
|
6,
|
||||||
view.gl.UNSIGNED_BYTE,
|
view.gl.UNSIGNED_BYTE,
|
||||||
|
@ -299,9 +315,12 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
private setAAState(view: MonochromePathfinderView) {
|
private setAAState(view: MonochromePathfinderView) {
|
||||||
const usedSize = view.destUsedSize;
|
const usedSize = this.supersampledUsedSize(view);
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.aaFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.aaFramebuffer);
|
||||||
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
view.gl.viewport(0,
|
||||||
|
0,
|
||||||
|
this.supersampledFramebufferSize[0],
|
||||||
|
this.supersampledFramebufferSize[1]);
|
||||||
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
||||||
view.gl.enable(view.gl.SCISSOR_TEST);
|
view.gl.enable(view.gl.SCISSOR_TEST);
|
||||||
|
|
||||||
|
@ -317,6 +336,7 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0);
|
this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0);
|
||||||
this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1);
|
this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1);
|
||||||
view.pathTransformBufferTexture.bind(view.gl, uniforms, 2);
|
view.pathTransformBufferTexture.bind(view.gl, uniforms, 2);
|
||||||
|
view.gl.uniform1f(uniforms.uScaleX, this.supersampleScale[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private antialiasLines(view: MonochromePathfinderView) {
|
private antialiasLines(view: MonochromePathfinderView) {
|
||||||
|
@ -373,7 +393,7 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
// Set state for ECAA resolve.
|
// Set state for ECAA resolve.
|
||||||
const usedSize = view.destUsedSize;
|
const usedSize = view.destUsedSize;
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, view.destFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, view.destFramebuffer);
|
||||||
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
view.gl.viewport(0, 0, this.destFramebufferSize[0], this.destFramebufferSize[1]);
|
||||||
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
||||||
view.gl.enable(view.gl.SCISSOR_TEST);
|
view.gl.enable(view.gl.SCISSOR_TEST);
|
||||||
this.setResolveDepthState(view);
|
this.setResolveDepthState(view);
|
||||||
|
@ -391,6 +411,9 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
view.gl.activeTexture(view.gl.TEXTURE0);
|
view.gl.activeTexture(view.gl.TEXTURE0);
|
||||||
view.gl.bindTexture(view.gl.TEXTURE_2D, this.aaAlphaTexture);
|
view.gl.bindTexture(view.gl.TEXTURE_2D, this.aaAlphaTexture);
|
||||||
view.gl.uniform1i(resolveProgram.uniforms.uAAAlpha, 0);
|
view.gl.uniform1i(resolveProgram.uniforms.uAAAlpha, 0);
|
||||||
|
view.gl.uniform2i(resolveProgram.uniforms.uAAAlphaDimensions,
|
||||||
|
this.supersampledFramebufferSize[0],
|
||||||
|
this.supersampledFramebufferSize[1]);
|
||||||
this.setResolveUniforms(view, resolveProgram);
|
this.setResolveUniforms(view, resolveProgram);
|
||||||
view.setTransformSTAndTexScaleUniformsForDest(resolveProgram.uniforms);
|
view.setTransformSTAndTexScaleUniformsForDest(resolveProgram.uniforms);
|
||||||
view.gl.drawElements(view.gl.TRIANGLES, 6, view.gl.UNSIGNED_BYTE, 0);
|
view.gl.drawElements(view.gl.TRIANGLES, 6, view.gl.UNSIGNED_BYTE, 0);
|
||||||
|
@ -403,6 +426,12 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
|
|
||||||
protected setResolveDepthState(view: MonochromePathfinderView): void {}
|
protected setResolveDepthState(view: MonochromePathfinderView): void {}
|
||||||
|
|
||||||
|
protected supersampledUsedSize(view: MonochromePathfinderView): glmatrix.vec2 {
|
||||||
|
const usedSize = glmatrix.vec2.create();
|
||||||
|
glmatrix.vec2.mul(usedSize, view.destUsedSize, this.supersampleScale);
|
||||||
|
return usedSize;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract getResolveProgram(view: MonochromePathfinderView): PathfinderShaderProgram;
|
protected abstract getResolveProgram(view: MonochromePathfinderView): PathfinderShaderProgram;
|
||||||
protected abstract initEdgeDetectFramebuffer(view: MonochromePathfinderView): void;
|
protected abstract initEdgeDetectFramebuffer(view: MonochromePathfinderView): void;
|
||||||
protected abstract createEdgeDetectVAO(view: MonochromePathfinderView): void;
|
protected abstract createEdgeDetectVAO(view: MonochromePathfinderView): void;
|
||||||
|
@ -417,6 +446,10 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected get supersampleScale(): glmatrix.vec2 {
|
||||||
|
return glmatrix.vec2.fromValues(this.subpixelAA ? 3.0 : 1.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
abstract shouldRenderDirect: boolean;
|
abstract shouldRenderDirect: boolean;
|
||||||
|
|
||||||
private bVertexPositionBufferTexture: PathfinderBufferTexture;
|
private bVertexPositionBufferTexture: PathfinderBufferTexture;
|
||||||
|
@ -432,11 +465,17 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||||
protected directColorTexture: WebGLTexture;
|
protected directColorTexture: WebGLTexture;
|
||||||
protected directPathIDTexture: WebGLTexture;
|
protected directPathIDTexture: WebGLTexture;
|
||||||
protected aaDepthTexture: WebGLTexture;
|
protected aaDepthTexture: WebGLTexture;
|
||||||
protected framebufferSize: glmatrix.vec2;
|
|
||||||
|
protected supersampledFramebufferSize: glmatrix.vec2;
|
||||||
|
protected destFramebufferSize: glmatrix.vec2;
|
||||||
|
|
||||||
|
protected subpixelAA: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ECAAMonochromeStrategy extends ECAAStrategy {
|
export class ECAAMonochromeStrategy extends ECAAStrategy {
|
||||||
protected getResolveProgram(view: MonochromePathfinderView): PathfinderShaderProgram {
|
protected getResolveProgram(view: MonochromePathfinderView): PathfinderShaderProgram {
|
||||||
|
if (this.subpixelAA)
|
||||||
|
return view.shaderPrograms.ecaaMonoSubpixelResolve;
|
||||||
return view.shaderPrograms.ecaaMonoResolve;
|
return view.shaderPrograms.ecaaMonoResolve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,13 +516,16 @@ export class ECAAMulticolorStrategy extends ECAAStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected initDirectFramebuffer(view: MonochromePathfinderView) {
|
protected initDirectFramebuffer(view: MonochromePathfinderView) {
|
||||||
this._directDepthTexture = createFramebufferDepthTexture(view.gl, this.framebufferSize);
|
this._directDepthTexture =
|
||||||
|
createFramebufferDepthTexture(view.gl, this.supersampledFramebufferSize);
|
||||||
super.initDirectFramebuffer(view);
|
super.initDirectFramebuffer(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected initEdgeDetectFramebuffer(view: MonochromePathfinderView) {
|
protected initEdgeDetectFramebuffer(view: MonochromePathfinderView) {
|
||||||
this.bgColorTexture = createFramebufferColorTexture(view.gl, this.framebufferSize);
|
this.bgColorTexture = createFramebufferColorTexture(view.gl,
|
||||||
this.fgColorTexture = createFramebufferColorTexture(view.gl, this.framebufferSize);
|
this.supersampledFramebufferSize);
|
||||||
|
this.fgColorTexture = createFramebufferColorTexture(view.gl,
|
||||||
|
this.supersampledFramebufferSize);
|
||||||
this.edgeDetectFramebuffer = createFramebuffer(view.gl,
|
this.edgeDetectFramebuffer = createFramebuffer(view.gl,
|
||||||
view.drawBuffersExt,
|
view.drawBuffersExt,
|
||||||
[this.bgColorTexture, this.fgColorTexture],
|
[this.bgColorTexture, this.fgColorTexture],
|
||||||
|
@ -505,7 +547,10 @@ export class ECAAMulticolorStrategy extends ECAAStrategy {
|
||||||
// Set state for edge detection.
|
// Set state for edge detection.
|
||||||
const edgeDetectProgram = view.shaderPrograms.ecaaEdgeDetect;
|
const edgeDetectProgram = view.shaderPrograms.ecaaEdgeDetect;
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.edgeDetectFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.edgeDetectFramebuffer);
|
||||||
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
view.gl.viewport(0,
|
||||||
|
0,
|
||||||
|
this.supersampledFramebufferSize[0],
|
||||||
|
this.supersampledFramebufferSize[1]);
|
||||||
|
|
||||||
view.drawBuffersExt.drawBuffersWEBGL([
|
view.drawBuffersExt.drawBuffersWEBGL([
|
||||||
view.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL,
|
view.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL,
|
||||||
|
|
|
@ -30,6 +30,7 @@ export const SHADER_NAMES: Array<keyof ShaderMap<void>> = [
|
||||||
'ecaaLine',
|
'ecaaLine',
|
||||||
'ecaaCurve',
|
'ecaaCurve',
|
||||||
'ecaaMonoResolve',
|
'ecaaMonoResolve',
|
||||||
|
'ecaaMonoSubpixelResolve',
|
||||||
'ecaaMultiResolve',
|
'ecaaMultiResolve',
|
||||||
'demo3DMonument',
|
'demo3DMonument',
|
||||||
];
|
];
|
||||||
|
@ -79,6 +80,10 @@ const SHADER_URLS: ShaderMap<ShaderProgramURLs> = {
|
||||||
vertex: "/glsl/gles2/ecaa-mono-resolve.vs.glsl",
|
vertex: "/glsl/gles2/ecaa-mono-resolve.vs.glsl",
|
||||||
fragment: "/glsl/gles2/ecaa-mono-resolve.fs.glsl",
|
fragment: "/glsl/gles2/ecaa-mono-resolve.fs.glsl",
|
||||||
},
|
},
|
||||||
|
ecaaMonoSubpixelResolve: {
|
||||||
|
vertex: "/glsl/gles2/ecaa-mono-subpixel-resolve.vs.glsl",
|
||||||
|
fragment: "/glsl/gles2/ecaa-mono-subpixel-resolve.fs.glsl",
|
||||||
|
},
|
||||||
ecaaMultiResolve: {
|
ecaaMultiResolve: {
|
||||||
vertex: "/glsl/gles2/ecaa-multi-resolve.vs.glsl",
|
vertex: "/glsl/gles2/ecaa-multi-resolve.vs.glsl",
|
||||||
fragment: "/glsl/gles2/ecaa-multi-resolve.fs.glsl",
|
fragment: "/glsl/gles2/ecaa-multi-resolve.fs.glsl",
|
||||||
|
@ -101,6 +106,7 @@ export interface ShaderMap<T> {
|
||||||
ecaaLine: T;
|
ecaaLine: T;
|
||||||
ecaaCurve: T;
|
ecaaCurve: T;
|
||||||
ecaaMonoResolve: T;
|
ecaaMonoResolve: T;
|
||||||
|
ecaaMonoSubpixelResolve: T;
|
||||||
ecaaMultiResolve: T;
|
ecaaMultiResolve: T;
|
||||||
demo3DMonument: T;
|
demo3DMonument: T;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default class SSAAStrategy extends AntialiasingStrategy {
|
||||||
attachMeshes(view: PathfinderDemoView) {}
|
attachMeshes(view: PathfinderDemoView) {}
|
||||||
|
|
||||||
setFramebufferSize(view: PathfinderDemoView) {
|
setFramebufferSize(view: PathfinderDemoView) {
|
||||||
this.destFramebufferSize = view.destAllocatedSize;
|
this.destFramebufferSize = glmatrix.vec2.clone(view.destAllocatedSize);
|
||||||
|
|
||||||
this.supersampledFramebufferSize = glmatrix.vec2.create();
|
this.supersampledFramebufferSize = glmatrix.vec2.create();
|
||||||
glmatrix.vec2.mul(this.supersampledFramebufferSize,
|
glmatrix.vec2.mul(this.supersampledFramebufferSize,
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
#extension GL_EXT_draw_buffers : require
|
#extension GL_EXT_draw_buffers : require
|
||||||
#extension GL_EXT_frag_depth : require
|
#extension GL_EXT_frag_depth : require
|
||||||
|
|
||||||
|
#define LCD_FILTER_FACTOR_0 (86.0 / 255.0)
|
||||||
|
#define LCD_FILTER_FACTOR_1 (77.0 / 255.0)
|
||||||
|
#define LCD_FILTER_FACTOR_2 (8.0 / 255.0)
|
||||||
|
|
||||||
#define MAX_PATHS 65536
|
#define MAX_PATHS 65536
|
||||||
|
|
||||||
#define EPSILON 0.001
|
#define EPSILON 0.001
|
||||||
|
@ -133,6 +137,15 @@ float computeCoverage(vec2 p0,
|
||||||
return area * (slopeNegative ? 0.5 : -0.5);
|
return area * (slopeNegative ? 0.5 : -0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://www.freetype.org/freetype2/docs/reference/ft2-lcd_filtering.html
|
||||||
|
float lcdFilter(float shadeL2, float shadeL1, float shade0, float shadeR1, float shadeR2) {
|
||||||
|
return LCD_FILTER_FACTOR_2 * shadeL2 +
|
||||||
|
LCD_FILTER_FACTOR_1 * shadeL1 +
|
||||||
|
LCD_FILTER_FACTOR_0 * shade0 +
|
||||||
|
LCD_FILTER_FACTOR_1 * shadeR1 +
|
||||||
|
LCD_FILTER_FACTOR_2 * shadeR2;
|
||||||
|
}
|
||||||
|
|
||||||
int unpackUInt16(vec2 packedValue) {
|
int unpackUInt16(vec2 packedValue) {
|
||||||
ivec2 valueBytes = ivec2(floor(packedValue * 255.0));
|
ivec2 valueBytes = ivec2(floor(packedValue * 255.0));
|
||||||
return valueBytes.y * 256 + valueBytes.x;
|
return valueBytes.y * 256 + valueBytes.x;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
uniform ivec2 uFramebufferSize;
|
uniform ivec2 uFramebufferSize;
|
||||||
|
uniform float uScaleX;
|
||||||
uniform ivec2 uBVertexPositionDimensions;
|
uniform ivec2 uBVertexPositionDimensions;
|
||||||
uniform ivec2 uBVertexPathIDDimensions;
|
uniform ivec2 uBVertexPathIDDimensions;
|
||||||
uniform ivec2 uPathTransformDimensions;
|
uniform ivec2 uPathTransformDimensions;
|
||||||
|
@ -41,6 +42,7 @@ void main() {
|
||||||
int pathID = fetchUInt16Data(uBVertexPathID, pointIndices.x, uBVertexPathIDDimensions);
|
int pathID = fetchUInt16Data(uBVertexPathID, pointIndices.x, uBVertexPathIDDimensions);
|
||||||
|
|
||||||
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
|
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
|
||||||
|
transform.xz *= uScaleX;
|
||||||
|
|
||||||
upperLeftPosition = transformVertexPositionST(upperLeftPosition, transform);
|
upperLeftPosition = transformVertexPositionST(upperLeftPosition, transform);
|
||||||
upperRightPosition = transformVertexPositionST(upperRightPosition, transform);
|
upperRightPosition = transformVertexPositionST(upperRightPosition, transform);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
uniform ivec2 uFramebufferSize;
|
uniform ivec2 uFramebufferSize;
|
||||||
|
uniform float uScaleX;
|
||||||
uniform ivec2 uBVertexPositionDimensions;
|
uniform ivec2 uBVertexPositionDimensions;
|
||||||
uniform ivec2 uBVertexPathIDDimensions;
|
uniform ivec2 uBVertexPathIDDimensions;
|
||||||
uniform ivec2 uPathTransformDimensions;
|
uniform ivec2 uPathTransformDimensions;
|
||||||
|
@ -38,6 +39,7 @@ void main() {
|
||||||
int pathID = fetchUInt16Data(uBVertexPathID, pointIndices.x, uBVertexPathIDDimensions);
|
int pathID = fetchUInt16Data(uBVertexPathID, pointIndices.x, uBVertexPathIDDimensions);
|
||||||
|
|
||||||
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
|
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
|
||||||
|
transform.xz *= uScaleX;
|
||||||
|
|
||||||
// Transform the points, and compute the position of this vertex.
|
// Transform the points, and compute the position of this vertex.
|
||||||
vec2 position;
|
vec2 position;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
uniform mat4 uTransform;
|
uniform mat4 uTransform;
|
||||||
|
uniform float uScaleX;
|
||||||
uniform ivec2 uFramebufferSize;
|
uniform ivec2 uFramebufferSize;
|
||||||
uniform ivec2 uBVertexPositionDimensions;
|
uniform ivec2 uBVertexPositionDimensions;
|
||||||
uniform ivec2 uBVertexPathIDDimensions;
|
uniform ivec2 uBVertexPathIDDimensions;
|
||||||
|
@ -33,6 +34,7 @@ void main() {
|
||||||
int pathID = fetchUInt16Data(uBVertexPathID, pointIndices.x, uBVertexPathIDDimensions);
|
int pathID = fetchUInt16Data(uBVertexPathID, pointIndices.x, uBVertexPathIDDimensions);
|
||||||
|
|
||||||
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
|
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
|
||||||
|
transform.xz *= uScaleX;
|
||||||
|
|
||||||
// Transform the points, and compute the position of this vertex.
|
// Transform the points, and compute the position of this vertex.
|
||||||
vec2 position;
|
vec2 position;
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
// pathfinder/shaders/gles2/ecaa-mono-resolve.fs.glsl
|
// pathfinder/shaders/gles2/ecaa-mono-resolve.fs.glsl
|
||||||
//
|
//
|
||||||
// Copyright (c) 2017 Mozilla Foundation
|
// Copyright (c) 2017 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
// pathfinder/shaders/gles2/ecaa-mono-resolve.vs.glsl
|
// pathfinder/shaders/gles2/ecaa-mono-resolve.vs.glsl
|
||||||
//
|
//
|
||||||
// Copyright (c) 2017 Mozilla Foundation
|
// Copyright (c) 2017 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
// pathfinder/shaders/gles2/ecaa-subpixel-mono-resolve.fs.glsl
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
uniform vec4 uBGColor;
|
||||||
|
uniform vec4 uFGColor;
|
||||||
|
uniform sampler2D uAAAlpha;
|
||||||
|
uniform ivec2 uAAAlphaDimensions;
|
||||||
|
|
||||||
|
varying vec2 vTexCoord;
|
||||||
|
|
||||||
|
float sampleSource(float deltaX) {
|
||||||
|
return texture2D(uAAAlpha, vec2(vTexCoord.s + deltaX, vTexCoord.y)).r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float onePixel = 1.0 / float(uAAAlphaDimensions.x);
|
||||||
|
|
||||||
|
float shade0 = sampleSource(0.0);
|
||||||
|
vec3 shadeL = vec3(sampleSource(-1.0 * onePixel),
|
||||||
|
sampleSource(-2.0 * onePixel),
|
||||||
|
sampleSource(-3.0 * onePixel));
|
||||||
|
vec3 shadeR = vec3(sampleSource(1.0 * onePixel),
|
||||||
|
sampleSource(2.0 * onePixel),
|
||||||
|
sampleSource(3.0 * onePixel));
|
||||||
|
|
||||||
|
vec3 alpha = vec3(lcdFilter(shadeL.z, shadeL.y, shadeL.x, shade0, shadeR.x),
|
||||||
|
lcdFilter(shadeL.y, shadeL.x, shade0, shadeR.x, shadeR.y),
|
||||||
|
lcdFilter(shadeL.x, shade0, shadeR.x, shadeR.y, shadeR.z));
|
||||||
|
|
||||||
|
gl_FragColor = mix(uBGColor, uFGColor, vec4(alpha, 1.0));
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// pathfinder/shaders/gles2/ecaa-subpixel-mono-resolve.vs.glsl
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform vec4 uTransformST;
|
||||||
|
uniform vec2 uTexScale;
|
||||||
|
|
||||||
|
attribute vec2 aPosition;
|
||||||
|
attribute vec2 aTexCoord;
|
||||||
|
|
||||||
|
varying vec2 vTexCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(transformVertexPositionST(aPosition, uTransformST), -1.0, 1.0);
|
||||||
|
vTexCoord = aTexCoord * uTexScale;
|
||||||
|
}
|
|
@ -15,23 +15,10 @@ uniform ivec2 uSourceDimensions;
|
||||||
|
|
||||||
varying vec2 vTexCoord;
|
varying vec2 vTexCoord;
|
||||||
|
|
||||||
#define FILTER_0 (86.0 / 255.0)
|
|
||||||
#define FILTER_1 (77.0 / 255.0)
|
|
||||||
#define FILTER_2 (8.0 / 255.0)
|
|
||||||
|
|
||||||
float sampleSource(float deltaX) {
|
float sampleSource(float deltaX) {
|
||||||
return texture2D(uSource, vec2(vTexCoord.s + deltaX, vTexCoord.y)).r;
|
return texture2D(uSource, vec2(vTexCoord.s + deltaX, vTexCoord.y)).r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.freetype.org/freetype2/docs/reference/ft2-lcd_filtering.html
|
|
||||||
float lcdFilter(float shadeL2, float shadeL1, float shade0, float shadeR1, float shadeR2) {
|
|
||||||
return FILTER_2 * shadeL2 +
|
|
||||||
FILTER_1 * shadeL1 +
|
|
||||||
FILTER_0 * shade0 +
|
|
||||||
FILTER_1 * shadeR1 +
|
|
||||||
FILTER_2 * shadeR2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float onePixel = 1.0 / float(uSourceDimensions.x);
|
float onePixel = 1.0 / float(uSourceDimensions.x);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue