From 57d6de47f8eee41ac6b0965850e4f4dee0802952 Mon Sep 17 00:00:00 2001 From: wuyize Date: Wed, 15 Mar 2023 11:23:21 +0800 Subject: [PATCH] Fix: painting.comp bug --- .../res/Shaders/element.comp | 5 - .../res/Shaders/painting.comp | 106 +++++++++++++----- 2 files changed, 78 insertions(+), 33 deletions(-) diff --git a/ArchitectureColoredPainting/res/Shaders/element.comp b/ArchitectureColoredPainting/res/Shaders/element.comp index 66910e7..b44b514 100644 --- a/ArchitectureColoredPainting/res/Shaders/element.comp +++ b/ArchitectureColoredPainting/res/Shaders/element.comp @@ -1150,11 +1150,6 @@ void main() else tangentEnd = normalize(p[3] - p[1]); - // if (onBegin ? shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, - // tangentEndLast) - // : (onEnd ? shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, - // tangentBeginNext) - // : d < minDistance)) bool hit = d < minDistance; if (onBegin) hit = hit && diff --git a/ArchitectureColoredPainting/res/Shaders/painting.comp b/ArchitectureColoredPainting/res/Shaders/painting.comp index 9ba19a9..50a32b8 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.comp +++ b/ArchitectureColoredPainting/res/Shaders/painting.comp @@ -1023,14 +1023,14 @@ void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 me } } -bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p3, vec2 tangentBegin, vec2 tangentEndLast) +bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, vec2 tangentBegin, vec2 tangentEndLast) { vec2 normal; if (onVeryBegin) { - if (endType == 0) + if (endType % 2 == 0) return true; - else if (endType == 1) + else if (endType % 2 == 1) normal = normalize(mat2(0, 1, -1, 0) * (-tangentBegin)); } else @@ -1039,17 +1039,26 @@ bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p3, ve vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin)); normal = normalLast + normalNow; } - return angleLargeThanPi(normal, localUV - p3); + return angleLargeThanPi(normal, localUV - p0); } -bool shouldFillEndCap(vec2 localUV, int endType, vec2 p0, vec2 tangentEnd) +bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 tangentEnd, vec2 tangentBeginNext) { vec2 normal; - if (endType == 0) - return true; - else if (endType == 1) - normal = normalize(mat2(0, 1, -1, 0) * tangentEnd); - return angleLargeThanPi(localUV - p0, normal); + if (onVeryEnd) + { + if ((endType / 2) % 2 == 0) + return true; + else if ((endType / 2) % 2 == 1) + normal = normalize(mat2(0, 1, -1, 0) * tangentEnd); + } + else + { + vec2 normalLast = normalize(mat2(0, 1, -1, 0) * tangentEnd); + vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBeginNext)); + normal = normalLast + normalNow; + } + return angleLargeThanPi(localUV - p3, normal); } bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex, @@ -1100,8 +1109,8 @@ bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsO return hitElement; } -bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex, float widthHeightRatio, - inout vec4 elementColor, inout vec2 metallicRoughness) +bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex, + float widthHeightRatio, inout vec4 elementColor, inout vec2 metallicRoughness) { bool hitElement = false; float strokeWidth = elementData[styleIndex]; @@ -1135,12 +1144,44 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point mat4x2 p = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], elementData[pyIndex[1]], elementData[pxIndex[2]], elementData[pyIndex[2]], elementData[pxIndex[3]], elementData[pyIndex[3]]); - p[0] *= ratio; p[1] *= ratio; p[2] *= ratio; p[3] *= ratio; + vec2 tangentBeginNext; + if (contourIterator + 1 < contourIndex + 1 + lineCount) + { + uint lineIndex = elementIndexs[contourIterator + 1]; + uint pLocation = linesOffset + 3 * lineIndex; + //vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]); + uvec4 pxIndex = uvec4(pointsOffset) + + 2 * uvec4(elementIndexs[pLocation] >> 16, elementIndexs[pLocation] & 0xFFFF, + elementIndexs[pLocation + 1] >> 16, elementIndexs[pLocation + 1] & 0xFFFF); + uvec4 pyIndex = uvec4(1) + pxIndex; + + mat4x2 pNext = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], + elementData[pyIndex[1]], elementData[pxIndex[2]], elementData[pyIndex[2]], + elementData[pxIndex[3]], elementData[pyIndex[3]]); + pNext[0] *= ratio; + pNext[1] *= ratio; + pNext[2] *= ratio; + pNext[3] *= ratio; + + if (pNext[0] == pNext[1] && pNext[2] == pNext[3]) + { + pNext[1] = (pNext[0] + pNext[3]) / 2; + pNext[2] = pNext[1]; + } + + //if(pNext[0]!=p[3]) + // break; + if (pNext[0] != pNext[1]) + tangentBeginNext = normalize(pNext[0] - pNext[1]); + else + tangentBeginNext = normalize(pNext[0] - pNext[2]); + } + if (p[0] == p[1] && p[2] == p[3]) { p[1] = (p[0] + p[3]) / 2; @@ -1158,7 +1199,10 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point 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 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]) @@ -1170,30 +1214,36 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point else tangentEnd = normalize(p[3] - p[1]); - if (onBegin ? shouldFillBeginCap(localUV, percent[0]<1e-5, endType, p[0], tangentBegin, p3Last - p2Last) - : d < minDistance) + bool hit = d < minDistance; + if (onBegin) + hit = + hit && shouldFillBeginCap(localUV, percent[0] < 1e-5, endType, p[0], tangentBegin, p3Last - p2Last); + if (onEnd) + hit = hit && + shouldFillEndCap(localUV, percent[1] > 1 - 1e-5, endType, p[3], tangentEnd, tangentBeginNext); + if (hit) { - minDistance = min(minDistance, d); bool reverse = p[3].y - p[0].y < 0.; - if (tangentBegin.y == 0.) - tangentBegin.y = reverse ? eps : -eps; - if (tangentEnd.y == 0.) - tangentEnd.y = reverse ? -eps : eps; + // if (tangentBegin.y == 0.) + // tangentBegin.y = reverse ? eps : -eps; + // if (tangentEnd.y == 0.) + // tangentEnd.y = reverse ? -eps : eps; int intTest = cubic_bezier_int_test2(localUV, p[0], p[1], p[2], p[3], reverse) + ray_int_test(localUV, p[0], tangentBegin, reverse) + ray_int_test(localUV, p[3], tangentEnd, reverse); if (lineType == 2 || (intTest % 2 == int(lineType))) { + minDistance = min(minDistance, d); hitElement = true; // elementColor = vec4(1, 1, 0, 1); vec2 metallicRoughness; drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness); } - else if (p3Last == p[0]) - hitElement = false; + // else if (p3Last == p[0]) + // hitElement = false; } tangentEndLast = tangentEnd; } @@ -1202,7 +1252,7 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point } if (hitElement && distance(localUV, p3Last) <= strokeWidth) { - hitElement = shouldFillEndCap(localUV, endType, p3Last, tangentEndLast); + // hitElement = shouldFillEndCap(localUV, percent[1] > 1 - 1e-5, endType, p3Last, tangentEndLast, vec2(0)); } // if (minDistance <= 0.001) @@ -1261,8 +1311,8 @@ bool drawElement(uint elementIndex, vec2 localUV, vec2 scale, out vec3 color, ou } else // Οί { - hitElement = strokeElement(localUV, contourIndex, linesOffset, pointsOffset, styleIndex, widthHeightRatio, - elementColor, metallicRoughness); + hitElement = strokeElement(localUV, contourIndex, linesOffset, pointsOffset, styleIndex, + widthHeightRatio, elementColor, metallicRoughness); } elementBvhIndex = elementBvhLength; @@ -1303,7 +1353,7 @@ void main() vec3 debugBVH = vec3(0); // bool debugHit = false; vec4 color = vec4(0.76, 0.33, 0.15, -1); - //vec4 color = vec4(1,1,1, -1); + // vec4 color = vec4(1,1,1, -1); vec2 metallicRoughness = vec2(0, 0.8); stack.top = 0; uint index = 0, visitTime = 0; @@ -1373,7 +1423,7 @@ void main() imageStore(gBaseColor, pixelLocation, vec4(color.rgb, 1)); imageStore(gMetallicRoughness, pixelLocation, vec4(metallicRoughness, 0, 1)); - return; + //return; if (/*color.a!=-1&&*/ debugBVH == vec3(0)) { // imageStore(gBaseColor, pixelLocation, vec4(vec3(1, 1, 0),1));