New shaders with outline support

This commit is contained in:
Roman Sorokin 2014-07-11 19:33:38 +02:00 committed by Alex Zolotarev
parent 0c68474f3e
commit 34164316c4
2 changed files with 124 additions and 68 deletions

View file

@ -1,47 +1,101 @@
uniform lowp vec4 u_color;
varying highp float v_dx;
varying highp vec4 v_radius;
varying highp vec4 v_centres;
varying highp vec2 v_type;
varying highp vec4 v_vertType;
varying highp vec4 v_distanceInfo;
varying highp vec4 baseColor;
varying highp vec4 outlineColor;
highp float cap(lowp float type, highp float dx, highp float dy)
void sphere_join(vec2 xy)
{
if (type == 0.0)
{
highp float hw = v_vertType.z/2.0;
return -(dx*dx + dy*dy) + hw*hw;
}
float r = v_radius.y;
float gip2 = xy.x*xy.x + xy.y*xy.y;
if(gip2 > r * r)
discard;
else
return 1.0;
{
gl_FragColor = baseColor;
if (gip2 > v_radius.w * v_radius.w)
{
gl_FragColor = vec4(outlineColor.rgb, outlineColor.a * (v_radius.y - sqrt(gip2)) / (v_radius.y - v_radius.w));
if (v_type.x > 0.6)
gl_FragColor = vec4(outlineColor.rgb, outlineColor.a * (v_radius.z - abs(v_dx * v_radius.z)) / r * 2.0);
}
else
{
gl_FragColor = baseColor;
if (v_type.x > 0.6)
{
if (abs(v_dx*v_radius.z) / 2.0 >= v_radius.z / 2.0 - r + v_radius.w)
gl_FragColor = vec4(outlineColor.rgb, outlineColor.a * (v_radius.z - abs(v_dx * v_radius.z)) / (r-v_radius.w));
else
gl_FragColor = baseColor;
}
}
}
}
highp float join(lowp float type, highp float dx, highp float dy)
void sphere_cap(float x, float y)
{
if (type > 0.0)
{
highp float hw = v_vertType.z/2.0;
return -(dx*dx + dy*dy) + hw*hw;
}
else
return 1.0;
float sq = x*x + y*y;
if (sq >= v_radius.y * v_radius.y)
discard;
if (sq > v_radius.w * v_radius.w)
gl_FragColor = vec4(outlineColor.rgb, outlineColor.a * (v_radius.y - sqrt(sq)) / (v_radius.y - v_radius.w));
}
void main(void)
{
lowp float vertType = v_vertType.x;
highp vec2 d = v_distanceInfo.zw - v_distanceInfo.xy;
if (vertType > 0.0)
float r = v_radius.y;
float dist = abs(v_radius.x);
gl_FragColor = baseColor;
if (v_type.x > 0.5)
{
lowp float joinType = v_vertType.y;
if ( join(joinType, d.x, d.y) < 0.0 )
discard;
}
else if (vertType < 0.0)
{
lowp float capType = v_vertType.y;
if ( cap(capType, d.x, d.y) < 0.0 )
discard;
}
float coord = (v_dx + 1.0) * v_radius.y / 2.0;
if (v_type.y > 0.5)
{
if (coord > v_radius.w)
gl_FragColor = vec4(outlineColor.rgb, outlineColor.a * (1.0 - (coord - v_radius.w) / (v_radius.y - v_radius.w)));
gl_FragColor = u_color;
if (dist > v_radius.w)
{
float alpha = min((1.0 - (coord - v_radius.w) / (v_radius.y - v_radius.w)), (v_radius.y - dist) / (v_radius.y - v_radius.w));
gl_FragColor = vec4(outlineColor.rgb, outlineColor.a * alpha);
}
}
else
{
if (coord < v_radius.y - v_radius.w)
gl_FragColor = vec4(outlineColor.rgb, outlineColor.a * coord / (v_radius.y - v_radius.w));
if (dist > v_radius.w)
{
float alpha = min(coord / (v_radius.y - v_radius.w), (v_radius.y - dist) / (v_radius.y - v_radius.w));
gl_FragColor = vec4(outlineColor.rgb, outlineColor.a * alpha);
}
}
}
else if (v_type.x < -0.5)
{
if (v_type.y > 0.5)
sphere_cap(dist, (v_dx + 1.0) * v_radius.y / 2.0);
else
sphere_cap(dist, v_radius.y - (v_dx + 1.0) * v_radius.y / 2.0);
}
else
{
gl_FragColor = baseColor;
if (dist > v_radius.w)
gl_FragColor = vec4(outlineColor.rgb, outlineColor.a * (v_radius.y - dist) / (v_radius.y - v_radius.w));
if (v_type.y>0.1)
{
if (v_dx >= 1.0)
sphere_join(vec2(dist, (v_dx - 1.0) * v_radius.z / 2.0));
else if (v_dx <= -1.0)
sphere_join(vec2(dist, (v_dx + 1.0) * v_radius.z / 2.0));
}
}
}

View file

@ -1,46 +1,48 @@
attribute highp vec4 a_position;
attribute highp vec4 a_direction;
attribute highp vec4 a_vertType;
attribute highp vec4 position;
attribute highp vec4 deltas;
attribute highp vec4 width_type;
attribute highp vec4 centres;
attribute highp vec4 color1;
attribute highp vec4 color2;
varying highp vec4 v_vertType;
varying highp vec4 v_distanceInfo;
varying highp float v_dx;
varying highp vec4 v_radius;
varying highp vec4 v_centres;
varying highp vec2 v_type;
varying highp vec4 baseColor;
varying highp vec4 outlineColor;
uniform highp mat4 modelView;
uniform highp mat4 projection;
void main(void)
{
highp float shift_mult = a_direction.z;
highp float vertexType = a_vertType.x;
float r = abs(width_type.x);
vec2 dir = position.zw - position.xy;
float len = length(dir);
vec4 pos2 = vec4(position.xy, deltas.z, 1) * modelView;
vec4 direc = vec4(position.zw, deltas.z, 1) * modelView;
dir = direc.xy - pos2.xy;
float l2 = length(dir);
dir = normalize(dir);
dir *= len * r;
pos2 += vec4(dir, 0, 0);
highp vec4 pos;
highp vec4 pivot = a_position * modelView;
gl_Position = pos2 * projection;
highp vec4 n = vec4(-a_direction.y, a_direction.x, 0, 0);
highp vec4 pn = normalize(n * modelView) * shift_mult;
highp vec4 d = vec4(a_direction.x, a_direction.y, 0, 0);
v_dx = (deltas.y + deltas.x * r / l2 * len);
v_radius.x = width_type.x;
v_radius.y = r;
v_radius.w = width_type.w;
vec2 centr1 = (vec4(centres.xy, 0, 1) * modelView).xy;
vec2 centr2 = (vec4(centres.zw, 0, 1) * modelView).xy;
float len2 = length(centr1 - centr2);
v_radius.z = len2;
v_centres.xy = centr1;
v_centres.zw = centr2;
v_type = width_type.yz;
if (vertexType < 0.0)
{
highp float quadWidth = 2.0 * abs(shift_mult);
highp vec4 pd = normalize(d * modelView) * quadWidth;
pos = (pn - pd + pivot);
}
else if (vertexType > 0.0)
{
if (shift_mult != 0.0)
pos = pivot + normalize(d * modelView) * shift_mult;
else
pos = pivot;
}
else
{
pos = (pn + pivot);
}
v_distanceInfo = vec4(pivot.x, pivot.y, pos.x, pos.y);
v_vertType = a_vertType;
gl_Position = pos * projection;
baseColor = color1;
outlineColor = color2;
}