add shaders
This commit is contained in:
parent
51058def87
commit
e1557285de
8 changed files with 449 additions and 0 deletions
12
data/ofxGPUFont/shaders/DEBUG_ES3/background.frag
Normal file
12
data/ofxGPUFont/shaders/DEBUG_ES3/background.frag
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec2 position;
|
||||||
|
|
||||||
|
out vec3 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float t = (position.y + 1.0) / 2.0;
|
||||||
|
vec3 bottom = vec3(75.0, 55.0, 201.0) / 255.0;
|
||||||
|
vec3 top = vec3(0.0, 12.0, 0.0) / 255.0;
|
||||||
|
color = mix(bottom, top, t);
|
||||||
|
}
|
15
data/ofxGPUFont/shaders/DEBUG_ES3/background.vert
Normal file
15
data/ofxGPUFont/shaders/DEBUG_ES3/background.vert
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
const vec2 vertices[4] = vec2[4](
|
||||||
|
vec2(-1.0, -1.0),
|
||||||
|
vec2( 1.0, -1.0),
|
||||||
|
vec2(-1.0, 1.0),
|
||||||
|
vec2( 1.0, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
out vec2 position;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
position = vertices[gl_VertexID];
|
||||||
|
gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0);
|
||||||
|
}
|
182
data/ofxGPUFont/shaders/DEBUG_ES3/font.frag
Normal file
182
data/ofxGPUFont/shaders/DEBUG_ES3/font.frag
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
#version 300 es
|
||||||
|
precision highp float;
|
||||||
|
precision highp isampler2D;
|
||||||
|
precision highp sampler2D;
|
||||||
|
|
||||||
|
// Based on: http://wdobbie.com/post/gpu-text-rendering-with-vector-textures/
|
||||||
|
|
||||||
|
struct Glyph {
|
||||||
|
int start, count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Curve {
|
||||||
|
vec2 p0, p1, p2;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform isampler2D glyphs;
|
||||||
|
uniform sampler2D curves;
|
||||||
|
uniform sampler2D iChannel0;
|
||||||
|
uniform vec4 color;
|
||||||
|
|
||||||
|
// Controls for debugging and exploring:
|
||||||
|
|
||||||
|
// Size of the window (in pixels) used for 1-dimensional anti-aliasing along each rays.
|
||||||
|
// 0 - no anti-aliasing
|
||||||
|
// 1 - normal anti-aliasing
|
||||||
|
// >=2 - exaggerated effect
|
||||||
|
uniform float antiAliasingWindowSize;
|
||||||
|
|
||||||
|
// Enable a second ray along the y-axis to achieve 2-dimensional anti-aliasing.
|
||||||
|
uniform bool enableSuperSamplingAntiAliasing;
|
||||||
|
|
||||||
|
// Draw control points for debugging (green - on curve, magenta - off curve).
|
||||||
|
uniform bool enableControlPointsVisualization;
|
||||||
|
|
||||||
|
|
||||||
|
in vec2 uv;
|
||||||
|
flat in int bufferIndex;
|
||||||
|
|
||||||
|
out vec4 result;
|
||||||
|
|
||||||
|
Glyph loadGlyph(int index) {
|
||||||
|
Glyph result;
|
||||||
|
ivec2 data = texelFetch(glyphs, ivec2(index, 0), 0).xy;
|
||||||
|
result.start = data.x;
|
||||||
|
result.count = data.y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Curve loadCurve(int index) {
|
||||||
|
Curve result;
|
||||||
|
result.p0 = texelFetch(curves, ivec2(3*index+0, 0), 0).xy;
|
||||||
|
result.p1 = texelFetch(curves, ivec2(3*index+1, 0), 0).xy;
|
||||||
|
result.p2 = texelFetch(curves, ivec2(3*index+2, 0), 0).xy;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float computeCoverage(float inverseDiameter, vec2 p0, vec2 p1, vec2 p2) {
|
||||||
|
if (p0.y > 0.0 && p1.y > 0.0 && p2.y > 0.0) return 0.0;
|
||||||
|
if (p0.y < 0.0 && p1.y < 0.0 && p2.y < 0.0) return 0.0;
|
||||||
|
|
||||||
|
// Note: Simplified from abc formula by extracting a factor of (-2) from b.
|
||||||
|
vec2 a = p0 - 2.0*p1 + p2;
|
||||||
|
vec2 b = p0 - p1;
|
||||||
|
vec2 c = p0;
|
||||||
|
|
||||||
|
float t0, t1;
|
||||||
|
if (abs(a.y) >= 1e-5) {
|
||||||
|
// Quadratic segment, solve abc formula to find roots.
|
||||||
|
float radicand = b.y*b.y - a.y*c.y;
|
||||||
|
if (radicand <= 0.0) return 0.0;
|
||||||
|
|
||||||
|
float s = sqrt(radicand);
|
||||||
|
t0 = (b.y - s) / a.y;
|
||||||
|
t1 = (b.y + s) / a.y;
|
||||||
|
} else {
|
||||||
|
// Linear segment, avoid division by a.y, which is near zero.
|
||||||
|
// There is only one root, so we have to decide which variable to
|
||||||
|
// assign it to based on the direction of the segment, to ensure that
|
||||||
|
// the ray always exits the shape at t0 and enters at t1. For a
|
||||||
|
// quadratic segment this works 'automatically', see readme.
|
||||||
|
float t = p0.y / (p0.y - p2.y);
|
||||||
|
if (p0.y < p2.y) {
|
||||||
|
t0 = -1.0;
|
||||||
|
t1 = t;
|
||||||
|
} else {
|
||||||
|
t0 = t;
|
||||||
|
t1 = -1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float alpha = 0.0;
|
||||||
|
|
||||||
|
if (t0 >= 0.0 && t0 < 1.0) {
|
||||||
|
float x = (a.x*t0 - 2.0*b.x)*t0 + c.x;
|
||||||
|
alpha += clamp(x * inverseDiameter + 0.5, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t1 >= 0.0 && t1 < 1.0) {
|
||||||
|
float x = (a.x*t1 - 2.0*b.x)*t1 + c.x;
|
||||||
|
alpha -= clamp(x * inverseDiameter + 0.5, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 rotate(vec2 v) {
|
||||||
|
return vec2(v.y, -v.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
//vec4 debug = texture(curves, vec2(uv.x, 0.5));
|
||||||
|
//ivec4 debug = texelFetch(glyphs, ivec2(uv.x * float(textureSize(glyphs, 0).x), 0), 0);
|
||||||
|
//result = vec4(debug.rgb, 1.0);
|
||||||
|
|
||||||
|
//Glyph gly = loadGlyph(bufferIndex);
|
||||||
|
//result = vec4((float(gly.start) / 1883.0), (float(gly.count) / 42.0), 0.0, 1.0);
|
||||||
|
|
||||||
|
// verify bufferIndex [x]
|
||||||
|
//result = vec4((float(bufferIndex) / 100.0), 0.0, 0.0, 1.0);
|
||||||
|
//return;
|
||||||
|
|
||||||
|
float alpha = 0.0;
|
||||||
|
|
||||||
|
// Inverse of the diameter of a pixel in uv units for anti-aliasing.
|
||||||
|
vec2 inverseDiameter = 1.0 / (antiAliasingWindowSize * fwidth(uv));
|
||||||
|
|
||||||
|
Glyph glyph = loadGlyph(bufferIndex);
|
||||||
|
for (int i = 0; i < glyph.count; i++) {
|
||||||
|
Curve curve = loadCurve(glyph.start + i);
|
||||||
|
|
||||||
|
vec2 p0 = curve.p0 - uv;
|
||||||
|
vec2 p1 = curve.p1 - uv;
|
||||||
|
vec2 p2 = curve.p2 - uv;
|
||||||
|
|
||||||
|
alpha += computeCoverage(inverseDiameter.x, p0, p1, p2);
|
||||||
|
if (enableSuperSamplingAntiAliasing) {
|
||||||
|
alpha += computeCoverage(inverseDiameter.y, rotate(p0), rotate(p1), rotate(p2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// DEBUG
|
||||||
|
//if (uv.x > 0.5) {
|
||||||
|
//ivec2 ts = textureSize(curves,0);
|
||||||
|
//float w = float(ts.x);
|
||||||
|
//float h = float(ts.y);
|
||||||
|
////float green = (float(glyph.count) / 27.0);
|
||||||
|
//float green = float(w) / (3.0 * 27.0);
|
||||||
|
//result = vec4(0.0,h * 0.5,0.0,1.0);
|
||||||
|
//} else {
|
||||||
|
//result = vec4(0.0,0.5,0.0,1.0);
|
||||||
|
//}
|
||||||
|
//return;
|
||||||
|
|
||||||
|
if (enableSuperSamplingAntiAliasing) {
|
||||||
|
alpha *= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpha = clamp(alpha, 0.0, 1.0);
|
||||||
|
result = color * alpha;
|
||||||
|
|
||||||
|
if (enableControlPointsVisualization) {
|
||||||
|
// Visualize control points.
|
||||||
|
vec2 fw = fwidth(uv);
|
||||||
|
float r = 4.0 * 0.5 * (fw.x + fw.y);
|
||||||
|
for (int i = 0; i < glyph.count; i++) {
|
||||||
|
Curve curve = loadCurve(glyph.start + i);
|
||||||
|
|
||||||
|
vec2 p0 = curve.p0 - uv;
|
||||||
|
vec2 p1 = curve.p1 - uv;
|
||||||
|
vec2 p2 = curve.p2 - uv;
|
||||||
|
|
||||||
|
if (dot(p0, p0) < r*r || dot(p2, p2) < r*r) {
|
||||||
|
result = vec4(0.0, 1.0, 0.0, 1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dot(p1, p1) < r*r) {
|
||||||
|
result = vec4(1.0, 0.0, 1.0, 1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
data/ofxGPUFont/shaders/DEBUG_ES3/font.vert
Normal file
21
data/ofxGPUFont/shaders/DEBUG_ES3/font.vert
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#version 300 es
|
||||||
|
precision highp float;
|
||||||
|
precision highp isampler2D;
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform float z;
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 vertexPosition;
|
||||||
|
layout (location = 1) in vec2 vertexUV;
|
||||||
|
layout (location = 2) in int vertexIndex;
|
||||||
|
|
||||||
|
out vec2 uv;
|
||||||
|
flat out int bufferIndex;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = projection * view * model * vec4(vertexPosition, z, 1.0);
|
||||||
|
uv = vertexUV;
|
||||||
|
bufferIndex = vertexIndex;
|
||||||
|
}
|
12
data/ofxGPUFont/shaders/ES3/background.frag
Normal file
12
data/ofxGPUFont/shaders/ES3/background.frag
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec2 position;
|
||||||
|
|
||||||
|
out vec3 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float t = (position.y + 1.0) / 2.0;
|
||||||
|
vec3 bottom = vec3(75.0, 55.0, 201.0) / 255.0;
|
||||||
|
vec3 top = vec3(0.0, 12.0, 0.0) / 255.0;
|
||||||
|
color = mix(bottom, top, t);
|
||||||
|
}
|
15
data/ofxGPUFont/shaders/ES3/background.vert
Normal file
15
data/ofxGPUFont/shaders/ES3/background.vert
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
const vec2 vertices[4] = vec2[4](
|
||||||
|
vec2(-1.0, -1.0),
|
||||||
|
vec2( 1.0, -1.0),
|
||||||
|
vec2(-1.0, 1.0),
|
||||||
|
vec2( 1.0, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
out vec2 position;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
position = vertices[gl_VertexID];
|
||||||
|
gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0);
|
||||||
|
}
|
171
data/ofxGPUFont/shaders/ES3/font.frag
Normal file
171
data/ofxGPUFont/shaders/ES3/font.frag
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
#version 300 es
|
||||||
|
precision highp float;
|
||||||
|
precision highp isampler2D;
|
||||||
|
precision highp sampler2D;
|
||||||
|
|
||||||
|
// Based on: http://wdobbie.com/post/gpu-text-rendering-with-vector-textures/
|
||||||
|
|
||||||
|
struct Glyph {
|
||||||
|
int start, count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Curve {
|
||||||
|
vec2 p0, p1, p2;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform isampler2D glyphs;
|
||||||
|
uniform sampler2D curves;
|
||||||
|
uniform vec4 color;
|
||||||
|
|
||||||
|
|
||||||
|
// Controls for debugging and exploring:
|
||||||
|
|
||||||
|
// Size of the window (in pixels) used for 1-dimensional anti-aliasing along each rays.
|
||||||
|
// 0 - no anti-aliasing
|
||||||
|
// 1 - normal anti-aliasing
|
||||||
|
// >=2 - exaggerated effect
|
||||||
|
uniform float antiAliasingWindowSize;
|
||||||
|
|
||||||
|
// Enable a second ray along the y-axis to achieve 2-dimensional anti-aliasing.
|
||||||
|
uniform bool enableSuperSamplingAntiAliasing;
|
||||||
|
|
||||||
|
// Draw control points for debugging (green - on curve, magenta - off curve).
|
||||||
|
uniform bool enableControlPointsVisualization;
|
||||||
|
|
||||||
|
|
||||||
|
in vec2 uv;
|
||||||
|
flat in int bufferIndex;
|
||||||
|
|
||||||
|
out vec4 result;
|
||||||
|
|
||||||
|
Glyph loadGlyph(int index) {
|
||||||
|
Glyph result;
|
||||||
|
ivec2 data = texelFetch(glyphs, ivec2(index, 0), 0).xy;
|
||||||
|
result.start = data.x;
|
||||||
|
result.count = data.y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Curve loadCurve(int index) {
|
||||||
|
Curve result;
|
||||||
|
result.p0 = texelFetch(curves, ivec2(3*index+0, 0), 0).xy;
|
||||||
|
result.p1 = texelFetch(curves, ivec2(3*index+1, 0), 0).xy;
|
||||||
|
result.p2 = texelFetch(curves, ivec2(3*index+2, 0), 0).xy;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float computeCoverage(float inverseDiameter, vec2 p0, vec2 p1, vec2 p2) {
|
||||||
|
if (p0.y > 0.0 && p1.y > 0.0 && p2.y > 0.0) return 0.0;
|
||||||
|
if (p0.y < 0.0 && p1.y < 0.0 && p2.y < 0.0) return 0.0;
|
||||||
|
|
||||||
|
// Note: Simplified from abc formula by extracting a factor of (-2) from b.
|
||||||
|
vec2 a = p0 - 2.0*p1 + p2;
|
||||||
|
vec2 b = p0 - p1;
|
||||||
|
vec2 c = p0;
|
||||||
|
|
||||||
|
float t0, t1;
|
||||||
|
if (abs(a.y) >= 1e-5) {
|
||||||
|
// Quadratic segment, solve abc formula to find roots.
|
||||||
|
float radicand = b.y*b.y - a.y*c.y;
|
||||||
|
if (radicand <= 0.0) return 0.0;
|
||||||
|
|
||||||
|
float s = sqrt(radicand);
|
||||||
|
t0 = (b.y - s) / a.y;
|
||||||
|
t1 = (b.y + s) / a.y;
|
||||||
|
} else {
|
||||||
|
// Linear segment, avoid division by a.y, which is near zero.
|
||||||
|
// There is only one root, so we have to decide which variable to
|
||||||
|
// assign it to based on the direction of the segment, to ensure that
|
||||||
|
// the ray always exits the shape at t0 and enters at t1. For a
|
||||||
|
// quadratic segment this works 'automatically', see readme.
|
||||||
|
float t = p0.y / (p0.y - p2.y);
|
||||||
|
if (p0.y < p2.y) {
|
||||||
|
t0 = -1.0;
|
||||||
|
t1 = t;
|
||||||
|
} else {
|
||||||
|
t0 = t;
|
||||||
|
t1 = -1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float alpha = 0.0;
|
||||||
|
|
||||||
|
if (t0 >= 0.0 && t0 < 1.0) {
|
||||||
|
float x = (a.x*t0 - 2.0*b.x)*t0 + c.x;
|
||||||
|
alpha += clamp(x * inverseDiameter + 0.5, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t1 >= 0.0 && t1 < 1.0) {
|
||||||
|
float x = (a.x*t1 - 2.0*b.x)*t1 + c.x;
|
||||||
|
alpha -= clamp(x * inverseDiameter + 0.5, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 rotate(vec2 v) {
|
||||||
|
return vec2(v.y, -v.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
//vec4 debug = texture(curves, vec2(uv.x, 0.5));
|
||||||
|
//ivec4 debug = texture(glyphs, vec2(uv.x, 0.5));
|
||||||
|
////ivec4 debug = texelFetch(glyphs, ivec2(uv.x * float(textureSize(glyphs, 0).x), 0), 0);
|
||||||
|
//result = vec4(debug.rgb, 1.0);
|
||||||
|
|
||||||
|
Glyph gly = loadGlyph(bufferIndex);
|
||||||
|
result = vec4((float(gly.start) / 1883.0), (float(gly.count) / 42.0), 0.0, 1.0);
|
||||||
|
|
||||||
|
// verify bufferIndex [x]
|
||||||
|
//result = vec4((float(bufferIndex) / 100.0), 0.0, 0.0, 1.0);
|
||||||
|
return;
|
||||||
|
|
||||||
|
float alpha = 0.0;
|
||||||
|
|
||||||
|
// Inverse of the diameter of a pixel in uv units for anti-aliasing.
|
||||||
|
vec2 inverseDiameter = 1.0 / (antiAliasingWindowSize * fwidth(uv));
|
||||||
|
|
||||||
|
Glyph glyph = loadGlyph(bufferIndex);
|
||||||
|
for (int i = 0; i < glyph.count; i++) {
|
||||||
|
Curve curve = loadCurve(glyph.start + i);
|
||||||
|
|
||||||
|
vec2 p0 = curve.p0 - uv;
|
||||||
|
vec2 p1 = curve.p1 - uv;
|
||||||
|
vec2 p2 = curve.p2 - uv;
|
||||||
|
|
||||||
|
alpha += computeCoverage(inverseDiameter.x, p0, p1, p2);
|
||||||
|
if (enableSuperSamplingAntiAliasing) {
|
||||||
|
alpha += computeCoverage(inverseDiameter.y, rotate(p0), rotate(p1), rotate(p2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableSuperSamplingAntiAliasing) {
|
||||||
|
alpha *= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpha = clamp(alpha, 0.0, 1.0);
|
||||||
|
result = color * alpha;
|
||||||
|
|
||||||
|
if (enableControlPointsVisualization) {
|
||||||
|
// Visualize control points.
|
||||||
|
vec2 fw = fwidth(uv);
|
||||||
|
float r = 4.0 * 0.5 * (fw.x + fw.y);
|
||||||
|
for (int i = 0; i < glyph.count; i++) {
|
||||||
|
Curve curve = loadCurve(glyph.start + i);
|
||||||
|
|
||||||
|
vec2 p0 = curve.p0 - uv;
|
||||||
|
vec2 p1 = curve.p1 - uv;
|
||||||
|
vec2 p2 = curve.p2 - uv;
|
||||||
|
|
||||||
|
if (dot(p0, p0) < r*r || dot(p2, p2) < r*r) {
|
||||||
|
result = vec4(0.0, 1.0, 0.0, 1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dot(p1, p1) < r*r) {
|
||||||
|
result = vec4(1.0, 0.0, 1.0, 1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
data/ofxGPUFont/shaders/ES3/font.vert
Normal file
21
data/ofxGPUFont/shaders/ES3/font.vert
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#version 300 es
|
||||||
|
precision highp float;
|
||||||
|
precision highp isampler2D;
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform float z;
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 vertexPosition;
|
||||||
|
layout (location = 1) in vec2 vertexUV;
|
||||||
|
layout (location = 2) in int vertexIndex;
|
||||||
|
|
||||||
|
out vec2 uv;
|
||||||
|
flat out int bufferIndex;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = projection * view * model * vec4(vertexPosition, z, 1.0);
|
||||||
|
uv = vertexUV;
|
||||||
|
bufferIndex = vertexIndex;
|
||||||
|
}
|
Loading…
Reference in a new issue