gl_engine: fix svg gradient position not correct

* change the color and stop size to 16 in shader and buffer block
* calculate transform when upload gradient info to gpu pipeline
This commit is contained in:
RuiwenTang 2023-12-20 20:51:03 +08:00 committed by Hermet Park
parent a38ee1e04e
commit edb118a0c7
3 changed files with 55 additions and 20 deletions

View file

@ -65,7 +65,7 @@ struct GlShape
unique_ptr<GlGeometry> geometry; unique_ptr<GlGeometry> geometry;
}; };
#define MAX_GRADIENT_STOPS 4 #define MAX_GRADIENT_STOPS 16
struct GlLinearGradientBlock struct GlLinearGradientBlock
{ {

View file

@ -527,7 +527,8 @@ void GlRenderer::drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b,
void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFlag flag) void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFlag flag)
{ {
const Fill::ColorStop* stops = nullptr; const Fill::ColorStop* stops = nullptr;
auto stopCnt = fill->colorStops(&stops); auto stopCnt = min(fill->colorStops(&stops),
static_cast<uint32_t>(MAX_GRADIENT_STOPS));
if (stopCnt < 2) return; if (stopCnt < 2) return;
GlRenderTask* task = nullptr; GlRenderTask* task = nullptr;
@ -576,7 +577,15 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFla
gradientBlock.stopColors[i * 4 + 3] = stops[i].a / 255.f; gradientBlock.stopColors[i * 4 + 3] = stops[i].a / 255.f;
} }
linearFill->linear(&gradientBlock.startPos[0], &gradientBlock.startPos[1], &gradientBlock.stopPos[0], &gradientBlock.stopPos[1]); float x1, x2, y1, y2;
linearFill->linear(&x1, &y1, &x2, &y2);
auto transform = linearFill->transform();
gradientBlock.startPos[0] = x1 * transform.e11 + transform.e13;
gradientBlock.startPos[1] = y1 * transform.e22 + transform.e23;
gradientBlock.stopPos[0] = x2 * transform.e11 + transform.e13;
gradientBlock.stopPos[1] = y2 * transform.e22 + transform.e23;
gradientBinding = GlBindingResource{ gradientBinding = GlBindingResource{
1, 1,
@ -600,7 +609,14 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFla
gradientBlock.stopColors[i * 4 + 3] = stops[i].a / 255.f; gradientBlock.stopColors[i * 4 + 3] = stops[i].a / 255.f;
} }
radialFill->radial(&gradientBlock.centerPos[0], &gradientBlock.centerPos[1], &gradientBlock.radius[0]); float x, y, r;
radialFill->radial(&x, &y, &r);
auto transform = radialFill->transform();
gradientBlock.centerPos[0] = x * transform.e11 + transform.e13;
gradientBlock.centerPos[1] = y * transform.e22 + transform.e23;
gradientBlock.radius[0] = r * transform.e11;
gradientBinding = GlBindingResource{ gradientBinding = GlBindingResource{
1, 1,

View file

@ -67,7 +67,7 @@ void main()
std::string STR_GRADIENT_FRAG_COMMON_VARIABLES = TVG_COMPOSE_SHADER( std::string STR_GRADIENT_FRAG_COMMON_VARIABLES = TVG_COMPOSE_SHADER(
const int MAX_STOP_COUNT = 4; \n const int MAX_STOP_COUNT = 16; \n
in vec2 vPos; \n in vec2 vPos; \n
in float vOpacity; \n in float vOpacity; \n
); );
@ -80,16 +80,38 @@ float gradientStep(float edge0, float edge1, float x)
return x; \n return x; \n
} \n } \n
\n \n
float gradientStop(int index) \n
{ \n
if (index >= MAX_STOP_COUNT) index = MAX_STOP_COUNT - 1; \n
int i = index / 4; \n
int j = index % 4; \n
return uGradientInfo.stopPoints[i][j]; \n
} \n
\n
float gradientWrap(float d) \n
{ \n
int i = 1; \n
while (d > 1.0) { \n
d = d - 1.0; \n
i *= -1; \n
} \n
\n
if (i == 1) \n
return smoothstep(0.0, 1.0, d); \n
else \n
return smoothstep(1.0, 0.0, d); \n
} \n
\n
vec4 gradient(float t) \n vec4 gradient(float t) \n
{ \n { \n
vec4 col = vec4(0.0); \n vec4 col = vec4(0.0); \n
int i = 0; \n int i = 0; \n
int count = int(uGradientInfo.nStops[0]); \n int count = int(uGradientInfo.nStops[0]); \n
if (t <= uGradientInfo.stopPoints[0]) \n if (t <= gradientStop(0)) \n
{ \n { \n
col += uGradientInfo.stopColors[0]; \n col += uGradientInfo.stopColors[0]; \n
} \n } \n
else if (t >= uGradientInfo.stopPoints[count - 1]) \n else if (t >= gradientStop(count - 1)) \n
{ \n { \n
col += uGradientInfo.stopColors[count - 1]; \n col += uGradientInfo.stopColors[count - 1]; \n
} \n } \n
@ -97,13 +119,12 @@ vec4 gradient(float t)
{ \n { \n
for (i = 0; i < count - 1; ++i) \n for (i = 0; i < count - 1; ++i) \n
{ \n { \n
if (t > uGradientInfo.stopPoints[i] && t < uGradientInfo.stopPoints[i + 1]) \n float stopi = gradientStop(i); \n
float stopi1 = gradientStop(i + 1); \n
if (t > stopi && t <stopi1) \n
{ \n { \n
col += (uGradientInfo.stopColors[i] * \n col += (uGradientInfo.stopColors[i] * (1. - gradientStep(stopi, stopi1, t))); \n
(1. - gradientStep(uGradientInfo.stopPoints[i], \n col += (uGradientInfo.stopColors[i + 1] * gradientStep(stopi, stopi1, t)); \n
uGradientInfo.stopPoints[i + 1], t))); \n
col += (uGradientInfo.stopColors[i + 1] * \n
gradientStep(uGradientInfo.stopPoints[i], uGradientInfo.stopPoints[i + 1], t)); \n
break; \n break; \n
} \n } \n
} \n } \n
@ -124,7 +145,7 @@ layout(std140) uniform GradientInfo {
vec4 nStops; \n vec4 nStops; \n
vec2 gradStartPos; \n vec2 gradStartPos; \n
vec2 gradEndPos; \n vec2 gradEndPos; \n
vec4 stopPoints; \n vec4 stopPoints[MAX_STOP_COUNT / 4]; \n
vec4 stopColors[MAX_STOP_COUNT]; \n vec4 stopColors[MAX_STOP_COUNT]; \n
} uGradientInfo ; \n } uGradientInfo ; \n
); );
@ -141,8 +162,7 @@ void main()
\n \n
float t = dot(pos - st, ba) / dot(ba, ba); \n float t = dot(pos - st, ba) / dot(ba, ba); \n
\n \n
//t = smoothstep(0.0, 1.0, clamp(t, 0.0, 1.0)); \n t = gradientWrap(t); \n
t = clamp(t, 0.0, 1.0); \n
\n \n
vec4 color = gradient(t); \n vec4 color = gradient(t); \n
\n \n
@ -156,7 +176,7 @@ layout(std140) uniform GradientInfo {
vec4 nStops; \n vec4 nStops; \n
vec2 centerPos; \n vec2 centerPos; \n
vec2 radius; \n vec2 radius; \n
vec4 stopPoints; \n vec4 stopPoints[MAX_STOP_COUNT / 4]; \n
vec4 stopColors[MAX_STOP_COUNT]; \n vec4 stopColors[MAX_STOP_COUNT]; \n
} uGradientInfo ; \n } uGradientInfo ; \n
); );
@ -171,8 +191,7 @@ void main()
float d = distance(uGradientInfo.centerPos, pos); \n float d = distance(uGradientInfo.centerPos, pos); \n
d = (d / ba); \n d = (d / ba); \n
\n \n
//float t = smoothstep(0.0, 1.0, clamp(d, 0.0, 1.0)); \n float t = gradientWrap(d); \n
float t = clamp(d, 0.0, 1.0); \n
\n \n
vec4 color = gradient(t); \n vec4 color = gradient(t); \n
\n \n