Add an edge detection shader for ECAA, untested as of yet

This commit is contained in:
Patrick Walton 2017-08-15 17:28:07 -07:00
parent 7dc8f5debb
commit 3f7fc8baf6
4 changed files with 93 additions and 0 deletions

View File

@ -39,6 +39,10 @@ const SHADER_URLS: ShaderMap<ShaderProgramURLs> = {
vertex: "/glsl/gles2/direct-interior.vs.glsl",
fragment: "/glsl/gles2/direct-interior.fs.glsl",
},
ecaaEdgeDetect: {
vertex: "/glsl/gles2/ecaa-edge-detect.vs.glsl",
fragment: "/glsl/gles2/ecaa-edge-detect.fs.glsl",
},
};
interface UnlinkedShaderProgram {
@ -67,6 +71,7 @@ interface ShaderMap<T> {
blit: T;
directCurve: T;
directInterior: T;
ecaaEdgeDetect: T;
}
interface UniformMap {
@ -322,8 +327,10 @@ class PathfinderView {
// Initialize the OpenGL context.
this.gl = expectNotNull(this.canvas.getContext('webgl', { antialias: false, depth: true }),
"Failed to initialize WebGL! Check that your browser supports it.");
this.gl.getExtension('EXT_frag_depth');
this.gl.getExtension('OES_element_index_uint');
this.gl.getExtension('WEBGL_depth_texture');
this.gl.getExtension('WEBGL_draw_buffers');
// Upload quad buffers.
this.quadPositionsBuffer = unwrapNull(this.gl.createBuffer());

View File

@ -4,6 +4,9 @@
#version 100
#extension GL_EXT_draw_buffers : require
#extension GL_EXT_frag_depth : require
#define MAX_PATHS 65536
precision highp float;

View File

@ -0,0 +1,68 @@
// pathfinder/shaders/gles2/ecaa-edge-detect.fs.glsl
//
// Copyright (c) 2017 Mozilla Foundation
precision highp float;
uniform ivec2 uFramebufferSize;
uniform sampler2D uColor;
uniform sampler2D uDepth;
varying vec2 vTexCoord;
vec3 checkFG(vec3 fgPosition, vec3 queryPosition) {
return queryPosition.z > fgPosition.z ? queryPosition : fgPosition;
}
void main() {
// Unpack.
vec2 position = vTexCoord;
// Compute positions.
vec2 onePixel = 1.0 / vec2(uFramebufferSize);
vec2 positionL = position + vec2(-onePixel.x, 0.0);
vec2 positionR = position + vec2( onePixel.x, 0.0);
vec2 positionB = position + vec2(0.0, -onePixel.x);
vec2 positionT = position + vec2(0.0, onePixel.x);
// Determine the topmost path.
float centerDepth = texture2D(uDepth, position).r;
vec4 neighborDepths = vec4(texture2D(uDepth, positionL).r,
texture2D(uDepth, positionR).r,
texture2D(uDepth, positionT).r,
texture2D(uDepth, positionB).r);
// Determine the position of the foreground color.
vec3 fgPosition = vec3(position, centerDepth);
fgPosition = checkFG(fgPosition, vec3(positionL, neighborDepths.x));
fgPosition = checkFG(fgPosition, vec3(positionR, neighborDepths.y));
fgPosition = checkFG(fgPosition, vec3(positionT, neighborDepths.z));
fgPosition = checkFG(fgPosition, vec3(positionB, neighborDepths.w));
// Determine the position of the background color.
vec2 bgPosition;
if (fgPosition.z != centerDepth)
bgPosition = fgPosition.xy;
else if (fgPosition.z != neighborDepths.x)
bgPosition = positionL;
else if (fgPosition.z != neighborDepths.y)
bgPosition = positionR;
else if (fgPosition.z != neighborDepths.z)
bgPosition = positionT;
else
bgPosition = positionB;
// Determine the foreground and background colors.
vec4 fgColor = texture2D(uColor, fgPosition.st);
vec4 bgColor = texture2D(uColor, bgPosition);
// Determine the depth.
//
// If all colors are the same, avoid touching this pixel in any further passes.
float outDepth = fgColor == bgColor ? 0.0 : fgPosition.z;
// Output results.
gl_FragData[0] = fgColor;
gl_FragData[1] = bgColor;
gl_FragDepthEXT = outDepth;
}

View File

@ -0,0 +1,15 @@
// pathfinder/shaders/gles2/ecaa-edge-detect.vs.glsl
//
// Copyright (c) 2017 Mozilla Foundation
precision highp float;
attribute vec2 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
void main() {
gl_Position = vec4(aPosition, 0.0, 1.0);
vTexCoord = aTexCoord;
}