mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 16:09:06 +07:00
premult alpha for sprites and bitmap fonts, bm font outline support, optional vertex snapping
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2f1044cd99d8bd2b0576b06928493cf7cdad421bae5d71c56a436cc33f59c30a
|
||||
size 217444
|
||||
oid sha256:cdd1e2d175c5109ec5840ea37093e7f745fbf618b709ee334b7459ef1567960a
|
||||
size 61729
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"shader" : "font_bm_shader.json",
|
||||
"state_block" : {
|
||||
"blending_state" : {
|
||||
"src_factor" : "src_alpha",
|
||||
"src_factor" : "one",
|
||||
"dst_factor" : "one_minus_src_alpha"
|
||||
},
|
||||
"capabilities_state" : {
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
uniform float u_glyph_dilate;
|
||||
uniform float u_outline_width;
|
||||
uniform vec4 u_outline_color;
|
||||
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color;
|
||||
varying vec4 v_color0;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(u_texture, v_st0) * v_color;
|
||||
vec4 t = texture2D(u_texture, v_st0);
|
||||
|
||||
float glyph_alpha = t.a;
|
||||
float outline_alpha = t.r;
|
||||
|
||||
vec4 glyph_color = vec4(v_color0.rgb * v_color0.a, v_color0.a);
|
||||
vec4 outline_color = vec4(u_outline_color.rgb * u_outline_color.a, u_outline_color.a);
|
||||
|
||||
vec2 layers_mask = vec2(
|
||||
step(0.0001, v_color0.a),
|
||||
step(0.0001, u_outline_color.a * u_outline_width));
|
||||
|
||||
gl_FragColor =
|
||||
layers_mask.x * glyph_alpha * glyph_color +
|
||||
layers_mask.y * outline_alpha * outline_color * (1.0 - glyph_alpha);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
uniform vec2 u_screen_s;
|
||||
uniform mat4 u_matrix_m;
|
||||
uniform mat4 u_matrix_vp;
|
||||
|
||||
@@ -6,10 +7,33 @@ attribute vec2 a_st0;
|
||||
attribute vec4 a_color0;
|
||||
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color;
|
||||
varying vec4 v_color0;
|
||||
|
||||
#define VERTEX_SNAPPING_ON
|
||||
|
||||
vec2 round(vec2 v) {
|
||||
return vec2(
|
||||
floor(v.x + 0.5),
|
||||
floor(v.y + 0.5));
|
||||
}
|
||||
|
||||
vec4 pixel_snap(vec4 pos) {
|
||||
vec2 hpc = u_screen_s * 0.5;
|
||||
vec2 pixel_pos = round((pos.xy / pos.w) * hpc);
|
||||
pos.xy = pixel_pos / hpc * pos.w;
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec4 vertex_to_homo(vec3 pos) {
|
||||
return vec4(pos, 1.0) * u_matrix_m * u_matrix_vp;
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_st0 = vec2(a_st0.s, 1.0 - a_st0.t);
|
||||
v_color = a_color0;
|
||||
gl_Position = vec4(a_vertex, 1.0) * u_matrix_m * u_matrix_vp;
|
||||
v_color0 = a_color0;
|
||||
#ifndef VERTEX_SNAPPING_ON
|
||||
gl_Position = vertex_to_homo(a_vertex);
|
||||
#else
|
||||
gl_Position = pixel_snap(vertex_to_homo(a_vertex));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#ifdef GL_OES_standard_derivatives
|
||||
# extension GL_OES_standard_derivatives : require
|
||||
#endif
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
uniform float u_glyph_dilate;
|
||||
@@ -5,7 +9,7 @@ uniform float u_outline_width;
|
||||
uniform vec4 u_outline_color;
|
||||
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color;
|
||||
varying vec4 v_color0;
|
||||
|
||||
void main() {
|
||||
float distance = texture2D(u_texture, v_st0).a;
|
||||
@@ -17,13 +21,14 @@ void main() {
|
||||
float glyph_alpha = smoothstep(glyph_center - width, glyph_center + width, distance);
|
||||
float outline_alpha = smoothstep(outline_center - width, outline_center + width, distance);
|
||||
|
||||
vec4 glyph_color = vec4(v_color.rgb * v_color.a, v_color.a);
|
||||
vec4 glyph_color = vec4(v_color0.rgb * v_color0.a, v_color0.a);
|
||||
vec4 outline_color = vec4(u_outline_color.rgb * u_outline_color.a, u_outline_color.a);
|
||||
|
||||
vec2 layers_mask = vec2(
|
||||
step(0.01, v_color.a),
|
||||
step(0.01, u_outline_color.a * u_outline_width));
|
||||
step(0.0001, v_color0.a),
|
||||
step(0.0001, u_outline_color.a * u_outline_width));
|
||||
|
||||
gl_FragColor = glyph_alpha * glyph_color * layers_mask.x +
|
||||
outline_alpha * outline_color * layers_mask.y * (1.0 - glyph_alpha);
|
||||
gl_FragColor =
|
||||
layers_mask.x * glyph_alpha * glyph_color +
|
||||
layers_mask.y * outline_alpha * outline_color * (1.0 - glyph_alpha);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
uniform vec2 u_screen_s;
|
||||
uniform mat4 u_matrix_m;
|
||||
uniform mat4 u_matrix_vp;
|
||||
|
||||
@@ -6,10 +7,33 @@ attribute vec2 a_st0;
|
||||
attribute vec4 a_color0;
|
||||
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color;
|
||||
varying vec4 v_color0;
|
||||
|
||||
#define VERTEX_SNAPPING_ON
|
||||
|
||||
vec2 round(vec2 v) {
|
||||
return vec2(
|
||||
floor(v.x + 0.5),
|
||||
floor(v.y + 0.5));
|
||||
}
|
||||
|
||||
vec4 pixel_snap(vec4 pos) {
|
||||
vec2 hpc = u_screen_s * 0.5;
|
||||
vec2 pixel_pos = round((pos.xy / pos.w) * hpc);
|
||||
pos.xy = pixel_pos / hpc * pos.w;
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec4 vertex_to_homo(vec3 pos) {
|
||||
return vec4(pos, 1.0) * u_matrix_m * u_matrix_vp;
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_st0 = vec2(a_st0.s, 1.0 - a_st0.t);
|
||||
v_color = a_color0;
|
||||
gl_Position = vec4(a_vertex, 1.0) * u_matrix_m * u_matrix_vp;
|
||||
v_color0 = a_color0;
|
||||
#ifndef VERTEX_SNAPPING_ON
|
||||
gl_Position = vertex_to_homo(a_vertex);
|
||||
#else
|
||||
gl_Position = pixel_snap(vertex_to_homo(a_vertex));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3,6 +3,5 @@ uniform sampler2D u_texture;
|
||||
varying vec2 v_st0;
|
||||
|
||||
void main() {
|
||||
vec2 st = vec2(v_st0.s, 1.0 - v_st0.t);
|
||||
gl_FragColor = texture2D(u_texture, st);
|
||||
gl_FragColor = texture2D(u_texture, v_st0);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,11 @@ attribute vec2 a_st0;
|
||||
|
||||
varying vec2 v_st0;
|
||||
|
||||
void main() {
|
||||
v_st0 = a_st0;
|
||||
gl_Position = vec4(a_vertex, 1.0) * u_matrix_m * u_matrix_vp;
|
||||
vec4 vertex_to_homo(vec3 pos) {
|
||||
return vec4(pos, 1.0) * u_matrix_m * u_matrix_vp;
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_st0 = vec2(a_st0.s, 1.0 - a_st0.t);
|
||||
gl_Position = vertex_to_homo(a_vertex);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
}, {
|
||||
"prototype" : "ship_prefab.json",
|
||||
"components" : {
|
||||
"sprite_renderer" : {
|
||||
"tint" : [255,0,0,255]
|
||||
},
|
||||
"actor" : {
|
||||
"translation" : [50,-50,0]
|
||||
}
|
||||
@@ -31,7 +34,9 @@
|
||||
"components" : {
|
||||
"label" : {
|
||||
"text" : "bm font",
|
||||
"valign" : "center"
|
||||
"valign" : "center",
|
||||
"outline_width" : 0.5,
|
||||
"outline_color" : [0,0,0,255]
|
||||
},
|
||||
"actor" : {
|
||||
"translation" : [0,180,0],
|
||||
@@ -44,11 +49,11 @@
|
||||
"label" : {
|
||||
"text" : "sdf font",
|
||||
"valign" : "center",
|
||||
"outline_width" : 0.2,
|
||||
"outline_width" : 0.5,
|
||||
"outline_color" : [0,0,0,255]
|
||||
},
|
||||
"actor" : {
|
||||
"translation" : [0,-180,0],
|
||||
"translation" : [0.5,-180.5,0],
|
||||
"scale" : 3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"shader" : "sprite_shader.json",
|
||||
"state_block" : {
|
||||
"blending_state" : {
|
||||
"src_factor" : "src_alpha",
|
||||
"src_factor" : "one",
|
||||
"dst_factor" : "one_minus_src_alpha"
|
||||
},
|
||||
"capabilities_state" : {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
varying vec4 v_tint;
|
||||
varying vec2 v_st;
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color0;
|
||||
|
||||
void main() {
|
||||
vec2 st = vec2(v_st.s, 1.0 - v_st.t);
|
||||
gl_FragColor = texture2D(u_texture, st) * v_tint;
|
||||
vec4 c = texture2D(u_texture, v_st0) * v_color0;
|
||||
c.rgb *= c.a;
|
||||
gl_FragColor = c;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,36 @@
|
||||
uniform vec2 u_screen_s;
|
||||
uniform mat4 u_matrix_vp;
|
||||
|
||||
attribute vec3 a_vertex;
|
||||
attribute vec4 a_tint;
|
||||
attribute vec2 a_st;
|
||||
attribute vec2 a_st0;
|
||||
attribute vec4 a_color0;
|
||||
|
||||
varying vec4 v_tint;
|
||||
varying vec2 v_st;
|
||||
varying vec2 v_st0;
|
||||
varying vec4 v_color0;
|
||||
|
||||
vec2 round(vec2 v) {
|
||||
return vec2(
|
||||
floor(v.x + 0.5),
|
||||
floor(v.y + 0.5));
|
||||
}
|
||||
|
||||
vec4 pixel_snap(vec4 pos) {
|
||||
vec2 hpc = u_screen_s * 0.5;
|
||||
vec2 pixel_pos = round((pos.xy / pos.w) * hpc);
|
||||
pos.xy = pixel_pos / hpc * pos.w;
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec4 vertex_to_homo(vec3 pos) {
|
||||
return vec4(pos, 1.0) * u_matrix_vp;
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_st = a_st;
|
||||
v_tint = a_tint;
|
||||
gl_Position = vec4(a_vertex, 1.0) * u_matrix_vp;
|
||||
v_st0 = vec2(a_st0.s, 1.0 - a_st0.t);
|
||||
v_color0 = a_color0;
|
||||
#ifndef VERTEX_SNAPPING_ON
|
||||
gl_Position = vertex_to_homo(a_vertex);
|
||||
#else
|
||||
gl_Position = pixel_snap(vertex_to_homo(a_vertex));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace e2d
|
||||
class render_system::internal_state final : private noncopyable {
|
||||
public:
|
||||
internal_state()
|
||||
: drawer_(the<engine>(), the<debug>(), the<render>()) {}
|
||||
: drawer_(the<engine>(), the<debug>(), the<render>(), the<window>()) {}
|
||||
~internal_state() noexcept = default;
|
||||
|
||||
void process(ecs::registry& owner) {
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace e2d::render_system_impl
|
||||
static vertex_declaration decl() noexcept {
|
||||
return vertex_declaration()
|
||||
.add_attribute<v3f>("a_vertex")
|
||||
.add_attribute<v2f>("a_st")
|
||||
.add_attribute<color32>("a_tint").normalized();
|
||||
.add_attribute<v2f>("a_st0")
|
||||
.add_attribute<color32>("a_color0").normalized();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
const str_hash screen_s_property_hash = "u_screen_s";
|
||||
const str_hash matrix_v_property_hash = "u_matrix_v";
|
||||
const str_hash matrix_p_property_hash = "u_matrix_p";
|
||||
const str_hash matrix_vp_property_hash = "u_matrix_vp";
|
||||
@@ -32,6 +33,7 @@ namespace e2d::render_system_impl
|
||||
const const_node_iptr& cam_n,
|
||||
engine& engine,
|
||||
render& render,
|
||||
window& window,
|
||||
batcher_type& batcher)
|
||||
: render_(render)
|
||||
, batcher_(batcher)
|
||||
@@ -47,6 +49,9 @@ namespace e2d::render_system_impl
|
||||
const m4f& m_p = cam.projection();
|
||||
|
||||
batcher_.flush()
|
||||
.property(screen_s_property_hash, cam.target()
|
||||
? cam.target()->size().cast_to<f32>()
|
||||
: window.framebuffer_size().cast_to<f32>())
|
||||
.property(matrix_v_property_hash, m_v)
|
||||
.property(matrix_p_property_hash, m_p)
|
||||
.property(matrix_vp_property_hash, m_v * m_p)
|
||||
@@ -219,8 +224,9 @@ namespace e2d::render_system_impl
|
||||
// drawer
|
||||
//
|
||||
|
||||
drawer::drawer(engine& e, debug& d, render& r)
|
||||
drawer::drawer(engine& e, debug& d, render& r, window& w)
|
||||
: engine_(e)
|
||||
, render_(r)
|
||||
, window_(w)
|
||||
, batcher_(d, r) {}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace e2d::render_system_impl
|
||||
const const_node_iptr& cam_n,
|
||||
engine& engine,
|
||||
render& render,
|
||||
window& window,
|
||||
batcher_type& batcher);
|
||||
~context() noexcept;
|
||||
|
||||
@@ -59,13 +60,14 @@ namespace e2d::render_system_impl
|
||||
render::property_block property_cache_;
|
||||
};
|
||||
public:
|
||||
drawer(engine& e, debug& d, render& r);
|
||||
drawer(engine& e, debug& d, render& r, window& w);
|
||||
|
||||
template < typename F >
|
||||
void with(const camera& cam, const const_node_iptr& cam_n, F&& f);
|
||||
private:
|
||||
engine& engine_;
|
||||
render& render_;
|
||||
window& window_;
|
||||
batcher_type batcher_;
|
||||
};
|
||||
}
|
||||
@@ -74,7 +76,7 @@ namespace e2d::render_system_impl
|
||||
{
|
||||
template < typename F >
|
||||
void drawer::with(const camera& cam, const const_node_iptr& cam_n, F&& f) {
|
||||
context ctx{cam, cam_n, engine_, render_, batcher_};
|
||||
context ctx{cam, cam_n, engine_, render_, window_, batcher_};
|
||||
std::forward<F>(f)(ctx);
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user