diff options
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_text_frag.glsl | 119 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_text_vert.glsl | 21 |
2 files changed, 105 insertions, 35 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl index f9f195c31d6..554596fa9ae 100644 --- a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl @@ -1,9 +1,13 @@ flat in vec4 color_flat; noperspective in vec2 texCoord_interp; +flat in int glyph_offset; +flat in ivec2 glyph_dim; +flat in int interp_size; + out vec4 fragColor; -uniform sampler2D glyph; +uniform sampler1DArray glyph; const vec2 offsets4[4] = vec2[4]( vec2(-0.5, 0.5), vec2(0.5, 0.5), vec2(-0.5, -0.5), vec2(-0.5, -0.5)); @@ -25,54 +29,107 @@ const vec2 offsets16[16] = vec2[16](vec2(-1.5, 1.5), vec2(0.5, -1.5), vec2(1.5, -1.5)); -#define sample_glyph_offset(texco, texel, ofs) texture(glyph, texco + ofs * texel).r +//#define GPU_NEAREST +#define sample_glyph_offset(texel, ofs) texture_1D_custom_bilinear_filter(texCoord_interp + ofs * texel) + +float texel_fetch(int index) +{ + int size_x = textureSize(glyph, 0).r; + if (index >= size_x) { + return texelFetch(glyph, ivec2(index % size_x, index / size_x), 0).r; + } + return texelFetch(glyph, ivec2(index, 0), 0).r; +} + +bool is_inside_box(ivec2 v) +{ + return all(greaterThanEqual(v, ivec2(0))) && all(lessThan(v, glyph_dim)); +} + +float texture_1D_custom_bilinear_filter(vec2 uv) +{ + vec2 texel_2d = uv * glyph_dim + 0.5; + ivec2 texel_2d_near = ivec2(texel_2d) - 1; + int frag_offset = glyph_offset + texel_2d_near.y * glyph_dim.x + texel_2d_near.x; + + float tl = 0.0; + + if (is_inside_box(texel_2d_near)) { + tl = texel_fetch(frag_offset); + } + +#ifdef GPU_NEAREST + return tl; +#else //GPU_LINEAR + int offset_x = 1; + int offset_y = glyph_dim.x; + + float tr = 0.0; + float bl = 0.0; + float br = 0.0; + + if (is_inside_box(texel_2d_near + ivec2(1, 0))) { + tr = texel_fetch(frag_offset + offset_x); + } + if (is_inside_box(texel_2d_near + ivec2(0, 1))) { + bl = texel_fetch(frag_offset + offset_y); + } + if (is_inside_box(texel_2d_near + ivec2(1, 1))) { + br = texel_fetch(frag_offset + offset_x + offset_y); + } + + vec2 f = fract(texel_2d); + float tA = mix(tl, tr, f.x); + float tB = mix(bl, br, f.x); + + return mix(tA, tB, f.y); +#endif +} void main() { // input color replaces texture color fragColor.rgb = color_flat.rgb; - vec2 texel = 1.0 / vec2(textureSize(glyph, 0)); - vec2 texco = abs(texCoord_interp); - // modulate input alpha & texture alpha - if (texCoord_interp.x > 0) { - fragColor.a = texture(glyph, texco).r; + if (interp_size == 0) { + fragColor.a = texture_1D_custom_bilinear_filter(texCoord_interp); } else { + vec2 texel = 1.0 / glyph_dim; fragColor.a = 0.0; - if (texCoord_interp.y > 0) { + if (interp_size == 1) { /* 3x3 blur */ /* Manual unroll for perf. (stupid glsl compiler) */ - fragColor.a += sample_glyph_offset(texco, texel, offsets4[0]); - fragColor.a += sample_glyph_offset(texco, texel, offsets4[1]); - fragColor.a += sample_glyph_offset(texco, texel, offsets4[2]); - fragColor.a += sample_glyph_offset(texco, texel, offsets4[3]); + fragColor.a += sample_glyph_offset(texel, offsets4[0]); + fragColor.a += sample_glyph_offset(texel, offsets4[1]); + fragColor.a += sample_glyph_offset(texel, offsets4[2]); + fragColor.a += sample_glyph_offset(texel, offsets4[3]); fragColor.a *= (1.0 / 4.0); } else { /* 5x5 blur */ /* Manual unroll for perf. (stupid glsl compiler) */ - fragColor.a += sample_glyph_offset(texco, texel, offsets16[0]); - fragColor.a += sample_glyph_offset(texco, texel, offsets16[1]); - fragColor.a += sample_glyph_offset(texco, texel, offsets16[2]); - fragColor.a += sample_glyph_offset(texco, texel, offsets16[3]); - - fragColor.a += sample_glyph_offset(texco, texel, offsets16[4]); - fragColor.a += sample_glyph_offset(texco, texel, offsets16[5]) * 2.0; - fragColor.a += sample_glyph_offset(texco, texel, offsets16[6]) * 2.0; - fragColor.a += sample_glyph_offset(texco, texel, offsets16[7]); - - fragColor.a += sample_glyph_offset(texco, texel, offsets16[8]); - fragColor.a += sample_glyph_offset(texco, texel, offsets16[9]) * 2.0; - fragColor.a += sample_glyph_offset(texco, texel, offsets16[10]) * 2.0; - fragColor.a += sample_glyph_offset(texco, texel, offsets16[11]); - - fragColor.a += sample_glyph_offset(texco, texel, offsets16[12]); - fragColor.a += sample_glyph_offset(texco, texel, offsets16[13]); - fragColor.a += sample_glyph_offset(texco, texel, offsets16[14]); - fragColor.a += sample_glyph_offset(texco, texel, offsets16[15]); + fragColor.a += sample_glyph_offset(texel, offsets16[0]); + fragColor.a += sample_glyph_offset(texel, offsets16[1]); + fragColor.a += sample_glyph_offset(texel, offsets16[2]); + fragColor.a += sample_glyph_offset(texel, offsets16[3]); + + fragColor.a += sample_glyph_offset(texel, offsets16[4]); + fragColor.a += sample_glyph_offset(texel, offsets16[5]) * 2.0; + fragColor.a += sample_glyph_offset(texel, offsets16[6]) * 2.0; + fragColor.a += sample_glyph_offset(texel, offsets16[7]); + + fragColor.a += sample_glyph_offset(texel, offsets16[8]); + fragColor.a += sample_glyph_offset(texel, offsets16[9]) * 2.0; + fragColor.a += sample_glyph_offset(texel, offsets16[10]) * 2.0; + fragColor.a += sample_glyph_offset(texel, offsets16[11]); + + fragColor.a += sample_glyph_offset(texel, offsets16[12]); + fragColor.a += sample_glyph_offset(texel, offsets16[13]); + fragColor.a += sample_glyph_offset(texel, offsets16[14]); + fragColor.a += sample_glyph_offset(texel, offsets16[15]); fragColor.a *= (1.0 / 20.0); } } diff --git a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl index 28437208e91..768638e5229 100644 --- a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl @@ -2,20 +2,33 @@ uniform mat4 ModelViewProjectionMatrix; in vec4 pos; /* rect */ -in vec4 tex; /* rect */ in vec4 col; +in int offset; +in ivec2 glyph_size; flat out vec4 color_flat; noperspective out vec2 texCoord_interp; +flat out int glyph_offset; +flat out ivec2 glyph_dim; +flat out int interp_size; void main() { + color_flat = col; + glyph_offset = offset; + glyph_dim = abs(glyph_size); + interp_size = int(glyph_size.x < 0) + int(glyph_size.y < 0); + /* Quad expension using instanced rendering. */ float x = float(gl_VertexID % 2); float y = float(gl_VertexID / 2); vec2 quad = vec2(x, y); - gl_Position = ModelViewProjectionMatrix * vec4(mix(pos.xy, pos.zw, quad), 0.0, 1.0); - texCoord_interp = mix(abs(tex.xy), abs(tex.zw), quad) * sign(tex.xw); - color_flat = col; + vec2 interp_offset = float(interp_size) / abs(pos.zw - pos.xy); + texCoord_interp = mix(-interp_offset, 1.0 + interp_offset, quad); + + vec2 final_pos = mix( + pos.xy + ivec2(-interp_size, interp_size), pos.zw + ivec2(interp_size, -interp_size), quad); + + gl_Position = ModelViewProjectionMatrix * vec4(final_pos, 0.0, 1.0); } |