Fix:曲线锐角连接时渲染错误
parent
7667525287
commit
2345cd6758
|
@ -1002,7 +1002,8 @@ void nextStyleIndex(inout uint styleIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, vec2 tangentBegin, vec2 tangentEndLast)
|
bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, vec2 tangentBegin, vec2 tangentEndLast,
|
||||||
|
float width)
|
||||||
{
|
{
|
||||||
vec2 normal;
|
vec2 normal;
|
||||||
if (onVeryBegin)
|
if (onVeryBegin)
|
||||||
|
@ -1018,10 +1019,16 @@ bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, ve
|
||||||
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
|
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
|
||||||
normal = normalLast + normalNow;
|
normal = normalLast + normalNow;
|
||||||
}
|
}
|
||||||
return angleLargeThanPi(normal, localUV - p0);
|
normal = normalize(normal);
|
||||||
|
float cosine = dot(normal, -tangentBegin);
|
||||||
|
vec2 toBegin = localUV - p0;
|
||||||
|
if (/*cosine > 0 ||*/ dot(toBegin, toBegin) > (width * width / (1 - cosine * cosine)))
|
||||||
|
return true;
|
||||||
|
return angleLargeThanPi(normal, toBegin);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 tangentEnd, vec2 tangentBeginNext)
|
bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 tangentEnd, vec2 tangentBeginNext,
|
||||||
|
float width)
|
||||||
{
|
{
|
||||||
vec2 normal;
|
vec2 normal;
|
||||||
if (onVeryEnd)
|
if (onVeryEnd)
|
||||||
|
@ -1037,7 +1044,12 @@ bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 t
|
||||||
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBeginNext));
|
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBeginNext));
|
||||||
normal = normalLast + normalNow;
|
normal = normalLast + normalNow;
|
||||||
}
|
}
|
||||||
return angleLargeThanPi(localUV - p3, normal);
|
normal = normalize(normal);
|
||||||
|
float cosine = dot(normal, tangentEnd);
|
||||||
|
vec2 toEnd = localUV - p3;
|
||||||
|
if (/*cosine < 0 ||*/ dot(toEnd, toEnd) > (width * width / (1 - cosine * cosine)))
|
||||||
|
return true;
|
||||||
|
return angleLargeThanPi(toEnd, normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
@ -1097,7 +1109,7 @@ void main()
|
||||||
bool onVeryBegin = false;
|
bool onVeryBegin = false;
|
||||||
bool onVeryEnd = false;
|
bool onVeryEnd = false;
|
||||||
vec2 tangentEndLast = vec2(0);
|
vec2 tangentEndLast = vec2(0);
|
||||||
vec2 tangentFirstBegin;
|
vec2 tangentFirstBegin = vec2(0);
|
||||||
uint lastHitIndex = 0;
|
uint lastHitIndex = 0;
|
||||||
bool lastHitElement = false;
|
bool lastHitElement = false;
|
||||||
hitElement = false;
|
hitElement = false;
|
||||||
|
@ -1154,7 +1166,11 @@ void main()
|
||||||
else
|
else
|
||||||
onVeryEnd = true;
|
onVeryEnd = true;
|
||||||
}
|
}
|
||||||
|
vec2 tangentBegin;
|
||||||
|
if (p[0] != p[1])
|
||||||
|
tangentBegin = normalize(p[0] - p[1]);
|
||||||
|
else
|
||||||
|
tangentBegin = normalize(p[0] - p[2]);
|
||||||
vec2 tangentEnd;
|
vec2 tangentEnd;
|
||||||
if (p[3] != p[2])
|
if (p[3] != p[2])
|
||||||
tangentEnd = normalize(p[3] - p[2]);
|
tangentEnd = normalize(p[3] - p[2]);
|
||||||
|
@ -1166,22 +1182,14 @@ void main()
|
||||||
float localWidth = strokeWidth; // * mix(lengthRate.x, lengthRate.y, t);
|
float localWidth = strokeWidth; // * mix(lengthRate.x, lengthRate.y, t);
|
||||||
if (d <= localWidth)
|
if (d <= localWidth)
|
||||||
{
|
{
|
||||||
bool onBegin = t<1e-5;
|
// bool onBegin = true;
|
||||||
bool onEnd = t>1-1e-5;
|
// bool onEnd = true;
|
||||||
//bool onBegin = true;
|
|
||||||
//bool onEnd = true;
|
|
||||||
vec2 tangentBegin;
|
|
||||||
if (p[0] != p[1])
|
|
||||||
tangentBegin = normalize(p[0] - p[1]);
|
|
||||||
else
|
|
||||||
tangentBegin = normalize(p[0] - p[2]);
|
|
||||||
|
|
||||||
bool hit = d < minDistance;
|
bool hit = d < minDistance;
|
||||||
if (onBegin)
|
hit = hit && shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast,
|
||||||
|
localWidth);
|
||||||
hit = hit &&
|
hit = hit &&
|
||||||
shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast);
|
shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext, localWidth);
|
||||||
if (onEnd)
|
|
||||||
hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext);
|
|
||||||
if (hit)
|
if (hit)
|
||||||
{
|
{
|
||||||
bool reverse = p[3].y - p[0].y < 0.;
|
bool reverse = p[3].y - p[0].y < 0.;
|
||||||
|
@ -1205,11 +1213,10 @@ void main()
|
||||||
drawLine(minDistance / localWidth, styleIndex, elementColor, metallicRoughness);
|
drawLine(minDistance / localWidth, styleIndex, elementColor, metallicRoughness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pathIndex == 5)
|
|
||||||
tangentFirstBegin = tangentBegin;
|
|
||||||
}
|
}
|
||||||
tangentEndLast = tangentEnd;
|
tangentEndLast = tangentEnd;
|
||||||
|
if (pathIndex == 5)
|
||||||
|
tangentFirstBegin = tangentBegin;
|
||||||
p3Last = p[3];
|
p3Last = p[3];
|
||||||
p2Last = p[2];
|
p2Last = p[2];
|
||||||
onVeryBegin = false;
|
onVeryBegin = false;
|
||||||
|
|
|
@ -1035,7 +1035,8 @@ void drawLine(in float d, uint styleHeadIndex, out vec4 elementColor, out vec2 m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, vec2 tangentBegin, vec2 tangentEndLast)
|
bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, vec2 tangentBegin, vec2 tangentEndLast,
|
||||||
|
float width)
|
||||||
{
|
{
|
||||||
vec2 normal;
|
vec2 normal;
|
||||||
if (onVeryBegin)
|
if (onVeryBegin)
|
||||||
|
@ -1051,10 +1052,16 @@ bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, ve
|
||||||
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
|
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
|
||||||
normal = normalLast + normalNow;
|
normal = normalLast + normalNow;
|
||||||
}
|
}
|
||||||
return angleLargeThanPi(normal, localUV - p0);
|
normal = normalize(normal);
|
||||||
|
float cosine = dot(normal, -tangentBegin);
|
||||||
|
vec2 toBegin = localUV - p0;
|
||||||
|
if (/*cosine > 0 ||*/ dot(toBegin, toBegin) > (width * width / (1 - cosine * cosine)))
|
||||||
|
return true;
|
||||||
|
return angleLargeThanPi(normal, toBegin);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 tangentEnd, vec2 tangentBeginNext)
|
bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 tangentEnd, vec2 tangentBeginNext,
|
||||||
|
float width)
|
||||||
{
|
{
|
||||||
vec2 normal;
|
vec2 normal;
|
||||||
if (onVeryEnd)
|
if (onVeryEnd)
|
||||||
|
@ -1070,7 +1077,12 @@ bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 t
|
||||||
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBeginNext));
|
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBeginNext));
|
||||||
normal = normalLast + normalNow;
|
normal = normalLast + normalNow;
|
||||||
}
|
}
|
||||||
return angleLargeThanPi(localUV - p3, normal);
|
normal = normalize(normal);
|
||||||
|
float cosine = dot(normal, tangentEnd);
|
||||||
|
vec2 toEnd = localUV - p3;
|
||||||
|
if (/*cosine < 0 ||*/ dot(toEnd, toEnd) > (width * width / (1 - cosine * cosine)))
|
||||||
|
return true;
|
||||||
|
return angleLargeThanPi(toEnd, normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex,
|
bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex,
|
||||||
|
@ -1231,29 +1243,24 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
||||||
debugBegin = 1;
|
debugBegin = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true);
|
|
||||||
if (d <= strokeWidth)
|
|
||||||
{
|
|
||||||
bool onBegin =
|
|
||||||
distance(localUV, p[0]) <= strokeWidth; //&& (p3Last == p[0] || contourIterator == contourIndex + 1);
|
|
||||||
bool onEnd = distance(localUV, p[3]) <= strokeWidth;
|
|
||||||
|
|
||||||
vec2 tangentBegin;
|
vec2 tangentBegin;
|
||||||
vec2 tangentEnd;
|
|
||||||
if (p[0] != p[1])
|
if (p[0] != p[1])
|
||||||
tangentBegin = normalize(p[0] - p[1]);
|
tangentBegin = normalize(p[0] - p[1]);
|
||||||
else
|
else
|
||||||
tangentBegin = normalize(p[0] - p[2]);
|
tangentBegin = normalize(p[0] - p[2]);
|
||||||
|
vec2 tangentEnd;
|
||||||
if (p[3] != p[2])
|
if (p[3] != p[2])
|
||||||
tangentEnd = normalize(p[3] - p[2]);
|
tangentEnd = normalize(p[3] - p[2]);
|
||||||
else
|
else
|
||||||
tangentEnd = normalize(p[3] - p[1]);
|
tangentEnd = normalize(p[3] - p[1]);
|
||||||
|
|
||||||
|
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true);
|
||||||
|
if (d <= strokeWidth)
|
||||||
|
{
|
||||||
bool hit = d < minDistance;
|
bool hit = d < minDistance;
|
||||||
if (onBegin)
|
hit = hit &&
|
||||||
hit = hit && shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast);
|
shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast, strokeWidth);
|
||||||
if (onEnd)
|
hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext, strokeWidth);
|
||||||
hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext);
|
|
||||||
if (hit)
|
if (hit)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1269,10 +1276,10 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
||||||
drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness);
|
drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
tangentEndLast = tangentEnd;
|
tangentEndLast = tangentEnd;
|
||||||
if (contourIterator == contourIndex + 1)
|
if (contourIterator == contourIndex + 1)
|
||||||
tangentFirstBegin = tangentBegin;
|
tangentFirstBegin = tangentBegin;
|
||||||
}
|
|
||||||
p3Last = p[3];
|
p3Last = p[3];
|
||||||
p2Last = p[2];
|
p2Last = p[2];
|
||||||
onVeryBegin = false;
|
onVeryBegin = false;
|
||||||
|
|
|
@ -46,7 +46,7 @@ bool Renderer::Material::operator==(const Material& m) const
|
||||||
|
|
||||||
std::pair<glm::vec4, glm::vec2> Renderer::Material::toVec() const
|
std::pair<glm::vec4, glm::vec2> Renderer::Material::toVec() const
|
||||||
{
|
{
|
||||||
return { glm::vec4(color.redF(), color.greenF(), color.blueF(), color.alphaF()), glm::vec2(metallicF(), roughnessF())};
|
return { glm::vec4(color.redF(), color.greenF(), color.blueF(), color.alphaF()), glm::vec2(metallicF(), roughnessF()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vector<GLfloat>& encoded)
|
std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vector<GLfloat>& encoded)
|
||||||
|
@ -66,6 +66,8 @@ std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vecto
|
||||||
std::unique_ptr<MaterialStroke> materialStroke;
|
std::unique_ptr<MaterialStroke> materialStroke;
|
||||||
uint widthMapSize = floatBitsToUint(encoded[1]);
|
uint widthMapSize = floatBitsToUint(encoded[1]);
|
||||||
uint headIndex = widthMapSize + 2;
|
uint headIndex = widthMapSize + 2;
|
||||||
|
if (encoded[1] < 0)
|
||||||
|
headIndex = 1; /// 쇗휭앉경긍쯤
|
||||||
uint headUint = floatBitsToUint(encoded[headIndex]);
|
uint headUint = floatBitsToUint(encoded[headIndex]);
|
||||||
vec4 head = unpackUnorm4x8(headUint);
|
vec4 head = unpackUnorm4x8(headUint);
|
||||||
StrokeType strokeType = (StrokeType)floor(head.b * 10);
|
StrokeType strokeType = (StrokeType)floor(head.b * 10);
|
||||||
|
@ -74,7 +76,7 @@ std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vecto
|
||||||
{
|
{
|
||||||
/// Plain
|
/// Plain
|
||||||
case 0: {
|
case 0: {
|
||||||
materialStroke = std::make_unique<StrokePlain>(Material(glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[headIndex+1])), glm::vec2(head.r, head.g)));
|
materialStroke = std::make_unique<StrokePlain>(Material(glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[headIndex + 1])), glm::vec2(head.r, head.g)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/// RadialGradient
|
/// RadialGradient
|
||||||
|
|
|
@ -220,7 +220,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(10, StrokeType::kBothSides, StrokeEndType::kClosed,
|
std::make_shared<MaterialStyleStroke>(10, StrokeType::kLeftSide, StrokeEndType::kClosed,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
|
Loading…
Reference in New Issue