From 2345cd6758fedb1305384f7ca6fe54b5e7e35ec9 Mon Sep 17 00:00:00 2001 From: wuyize Date: Fri, 24 Mar 2023 13:42:16 +0800 Subject: [PATCH] =?UTF-8?q?Fix=EF=BC=9A=E6=9B=B2=E7=BA=BF=E9=94=90?= =?UTF-8?q?=E8=A7=92=E8=BF=9E=E6=8E=A5=E6=97=B6=E6=B8=B2=E6=9F=93=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../res/Shaders/element.comp | 53 +++++++++-------- .../res/Shaders/painting.comp | 59 +++++++++++-------- .../src/Renderer/Painting/BaseStyle.cpp | 6 +- UnitTest/ElementRendererTest.cpp | 2 +- 4 files changed, 68 insertions(+), 52 deletions(-) diff --git a/ArchitectureColoredPainting/res/Shaders/element.comp b/ArchitectureColoredPainting/res/Shaders/element.comp index 616920c..67700fa 100644 --- a/ArchitectureColoredPainting/res/Shaders/element.comp +++ b/ArchitectureColoredPainting/res/Shaders/element.comp @@ -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; 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)); 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; 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)); 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() @@ -1097,7 +1109,7 @@ void main() bool onVeryBegin = false; bool onVeryEnd = false; vec2 tangentEndLast = vec2(0); - vec2 tangentFirstBegin; + vec2 tangentFirstBegin = vec2(0); uint lastHitIndex = 0; bool lastHitElement = false; hitElement = false; @@ -1154,7 +1166,11 @@ void main() else onVeryEnd = true; } - + vec2 tangentBegin; + if (p[0] != p[1]) + tangentBegin = normalize(p[0] - p[1]); + else + tangentBegin = normalize(p[0] - p[2]); vec2 tangentEnd; if (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); if (d <= localWidth) { - bool onBegin = t<1e-5; - bool onEnd = t>1-1e-5; - //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 onBegin = true; + // bool onEnd = true; bool hit = d < minDistance; - if (onBegin) - hit = hit && - shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast); - if (onEnd) - hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext); + hit = hit && shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast, + localWidth); + hit = hit && + shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext, localWidth); if (hit) { bool reverse = p[3].y - p[0].y < 0.; @@ -1205,11 +1213,10 @@ void main() drawLine(minDistance / localWidth, styleIndex, elementColor, metallicRoughness); } } - if (pathIndex == 5) - tangentFirstBegin = tangentBegin; } tangentEndLast = tangentEnd; - + if (pathIndex == 5) + tangentFirstBegin = tangentBegin; p3Last = p[3]; p2Last = p[2]; onVeryBegin = false; diff --git a/ArchitectureColoredPainting/res/Shaders/painting.comp b/ArchitectureColoredPainting/res/Shaders/painting.comp index f363dbd..150321d 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.comp +++ b/ArchitectureColoredPainting/res/Shaders/painting.comp @@ -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; 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)); 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; 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)); 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, @@ -1231,29 +1243,24 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point debugBegin = 1; } + vec2 tangentBegin; + if (p[0] != p[1]) + tangentBegin = normalize(p[0] - p[1]); + else + tangentBegin = normalize(p[0] - p[2]); + vec2 tangentEnd; + if (p[3] != p[2]) + tangentEnd = normalize(p[3] - p[2]); + else + 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 onBegin = - distance(localUV, p[0]) <= strokeWidth; //&& (p3Last == p[0] || contourIterator == contourIndex + 1); - bool onEnd = distance(localUV, p[3]) <= strokeWidth; - - vec2 tangentBegin; - vec2 tangentEnd; - if (p[0] != p[1]) - tangentBegin = normalize(p[0] - p[1]); - else - tangentBegin = normalize(p[0] - p[2]); - if (p[3] != p[2]) - tangentEnd = normalize(p[3] - p[2]); - else - tangentEnd = normalize(p[3] - p[1]); - bool hit = d < minDistance; - if (onBegin) - hit = hit && shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast); - if (onEnd) - hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext); + hit = hit && + shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast, strokeWidth); + hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext, strokeWidth); if (hit) { @@ -1269,10 +1276,10 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness); } } - tangentEndLast = tangentEnd; - if (contourIterator == contourIndex + 1) - tangentFirstBegin = tangentBegin; } + tangentEndLast = tangentEnd; + if (contourIterator == contourIndex + 1) + tangentFirstBegin = tangentBegin; p3Last = p[3]; p2Last = p[2]; onVeryBegin = false; diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/BaseStyle.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/BaseStyle.cpp index e216d6b..f77a07a 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/BaseStyle.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/BaseStyle.cpp @@ -46,7 +46,7 @@ bool Renderer::Material::operator==(const Material& m) const std::pair 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 Renderer::MaterialStyle::decoded(const std::vector& encoded) @@ -66,6 +66,8 @@ std::unique_ptr Renderer::MaterialStyle::decoded(const std::vecto std::unique_ptr materialStroke; uint widthMapSize = floatBitsToUint(encoded[1]); uint headIndex = widthMapSize + 2; + if (encoded[1] < 0) + headIndex = 1; /// ¼æÈݾɰæ±àÂë uint headUint = floatBitsToUint(encoded[headIndex]); vec4 head = unpackUnorm4x8(headUint); StrokeType strokeType = (StrokeType)floor(head.b * 10); @@ -74,7 +76,7 @@ std::unique_ptr Renderer::MaterialStyle::decoded(const std::vecto { /// Plain case 0: { - materialStroke = std::make_unique(Material(glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[headIndex+1])), glm::vec2(head.r, head.g))); + materialStroke = std::make_unique(Material(glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[headIndex + 1])), glm::vec2(head.r, head.g))); break; } /// RadialGradient diff --git a/UnitTest/ElementRendererTest.cpp b/UnitTest/ElementRendererTest.cpp index 7ce67a3..1982b49 100644 --- a/UnitTest/ElementRendererTest.cpp +++ b/UnitTest/ElementRendererTest.cpp @@ -220,7 +220,7 @@ namespace UnitTest {1.00, Material{QColor(58,64,151)}} }; return { BaseStyle(std::make_shared(), - std::make_shared(10, StrokeType::kBothSides, StrokeEndType::kClosed, + std::make_shared(10, StrokeType::kLeftSide, StrokeEndType::kClosed, std::make_shared(materialMap, false))) }; } } style;