Make the rounding texture shaders smaller and more efficient.

This commit is contained in:
Felix Dick 2022-09-28 14:50:27 +02:00
parent 5ff44467d7
commit 7edbaea23d

View file

@ -4,137 +4,37 @@
inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVarName) -> std::string { inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVarName) -> std::string {
return R"#( return R"#(
if (pixCoord[0] < topLeft[0]) {
// we're close left
if (pixCoord[1] < topLeft[1]) {
// top
if (ignoreCorners == 1) { // branchless baby!
vec2 pixCoord = v_texcoord - vec2(0.5);
pixCoord *= (vec2(lessThan(pixCoord, vec2(0.0))) * vec2(-2.0) + vec2(1.0)) * fullSize;
pixCoord -= (bottomRight - topLeft) * vec2(0.5);
if (all(greaterThan(pixCoord, vec2(0.0)))) {
if (ignoreCorners == 1)
discard; discard;
return;
}
float topLeftDistance = distance(topLeft, pixCoord); float dist = length(pixCoord);
if (topLeftDistance > radius - 1.0) { if (dist > radius)
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard; discard;
return;
} else if (primitiveMultisample == 1) { if (primitiveMultisample == 1 && dist > radius - 1.0) {
float distances = 0.0; float distances = 0.0;
if (distance(topLeft, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; } if (length(pixCoord - vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; } if (length(pixCoord - vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; } if (length(pixCoord - vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; } if (length(pixCoord - vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) { if (distances == 0.0)
discard; discard;
return;
}
distances = distances / 4.0; distances = distances / 4.0;
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances; /* )#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances; */
}
}
} else if (pixCoord[1] > bottomRight[1]) {
// bottom
if (ignoreCorners == 1) {
discard;
return;
} }
float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
}
}
}
}
else if (pixCoord[0] > bottomRight[0]) {
// we're close right
if (pixCoord[1] < topLeft[1]) {
// top
if (ignoreCorners == 1) {
discard;
return;
}
float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
}
}
} else if (pixCoord[1] > bottomRight[1]) {
// bottom
if (ignoreCorners == 1) {
discard;
return;
}
float topLeftDistance = distance(bottomRight, pixCoord);
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(bottomRight, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
}
}
}
} }
)#"; )#";
}; };
@ -167,16 +67,11 @@ uniform int primitiveMultisample;
uniform int ignoreCorners; uniform int ignoreCorners;
void main() { void main() {
if (radius == 0.0) {
gl_FragColor = v_color;
return;
}
vec4 pixColor = v_color; vec4 pixColor = v_color;
vec2 pixCoord = fullSize * v_texcoord; if (radius > 0.0) {
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#( )#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
}
gl_FragColor = pixColor; gl_FragColor = pixColor;
})#"; })#";
@ -192,6 +87,7 @@ void main() {
v_texcoord = texcoord; v_texcoord = texcoord;
})#"; })#";
// this is texture rendering!!
inline const std::string TEXFRAGSRCRGBA = R"#( inline const std::string TEXFRAGSRCRGBA = R"#(
precision mediump float; precision mediump float;
varying vec2 v_texcoord; // is in 0-1 varying vec2 v_texcoord; // is in 0-1
@ -215,10 +111,9 @@ void main() {
vec4 pixColor = texture2D(tex, v_texcoord); vec4 pixColor = texture2D(tex, v_texcoord);
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) { if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
discard; discard;
return;
}
if (applyTint == 1) { if (applyTint == 1) {
pixColor[0] = pixColor[0] * tint[0]; pixColor[0] = pixColor[0] * tint[0];
@ -226,10 +121,7 @@ void main() {
pixColor[2] = pixColor[2] * tint[2]; pixColor[2] = pixColor[2] * tint[2];
} }
vec2 pixCoord = fullSize * v_texcoord; )#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
)#" + ROUNDED_SHADER_FUNC("pixColor") +
R"#(
gl_FragColor = pixColor * alpha; gl_FragColor = pixColor * alpha;
})#"; })#";
@ -255,10 +147,8 @@ uniform int ignoreCorners;
void main() { void main() {
if (discardOpaque == 1 && alpha == 1.0) { if (discardOpaque == 1 && alpha == 1.0)
discard; discard;
return;
}
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0); vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
@ -268,10 +158,7 @@ void main() {
pixColor[2] = pixColor[2] * tint[2]; pixColor[2] = pixColor[2] * tint[2];
} }
vec2 pixCoord = fullSize * v_texcoord; )#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
)#" + ROUNDED_SHADER_FUNC("pixColor") +
R"#(
gl_FragColor = pixColor * alpha; gl_FragColor = pixColor * alpha;
})#"; })#";
@ -293,6 +180,7 @@ void main() {
sum += texture2D(tex, uv + halfpixel.xy * radius); sum += texture2D(tex, uv + halfpixel.xy * radius);
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius); sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius);
sum += texture2D(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius); sum += texture2D(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius);
gl_FragColor = sum / 8.0; gl_FragColor = sum / 8.0;
} }
)#"; )#";
@ -348,10 +236,8 @@ void main() {
vec4 pixColor = texture2D(texture0, v_texcoord); vec4 pixColor = texture2D(texture0, v_texcoord);
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) { if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
discard; discard;
return;
}
if (applyTint == 1) { if (applyTint == 1) {
pixColor[0] = pixColor[0] * tint[0]; pixColor[0] = pixColor[0] * tint[0];
@ -359,10 +245,7 @@ void main() {
pixColor[2] = pixColor[2] * tint[2]; pixColor[2] = pixColor[2] * tint[2];
} }
vec2 pixCoord = fullSize * v_texcoord; )#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
)#" + ROUNDED_SHADER_FUNC("pixColor") +
R"#(
gl_FragColor = pixColor * alpha; gl_FragColor = pixColor * alpha;
})#"; })#";